Problem is that with the EVO you can't set work mode to Force Charge / Force Discharge, and it's a right pain getting it to dynamically work with timed periods, especially if you are linking to Predbat. Additionally many of the addresses seem to be read-only even over a hardwired modbus connection.
This method uses the Remote Control feature. Specific addresses used are:
46001 - Remote control
46002 - Remote Timeout_Set
46003 - Remote Control Active Power Command
Turns out you need to set all of these to get it to actually run, and you need to do that each time you want to trigger an action.
46001 - Remote control - setting this as '5' forces discharge to the grid. Setting it as '7' forces charge from the grid.
46002 - Timeout for the control in seconds. I use "300".
46003 - I haven't figured out what 46003 is, but 46004 is the required power to discharge / charge with. And 46004 cannot be written to. however 46003 accepts two comma separated values, so I use "0,5000"
You can test this by going to Settings / Developer Tools / Actions and finding the Write registers for your integration, select your inverter, then in "start address" put '46001' and in Values put '5'. then repeat for the other two addresses.
As this is a faff to do every time, and I have 0 idea how to do the GitHub bits, I've made it easier on Home Assistant.
Note the below isn't fully tested, but seems to be working for me. If you're using a different integration, you need to change the automation action target from foxess_modbus.write_registers to your one.
The way it works is you create 3 helpers to allow you to set the charge / discharge rate, and the mode. Changing the mode triggers an automation, which writes the modbus commands to charge or discharge. if you change back to self-use, it changes 46001 to '0' (off).
There is then a second automation that re-starts the first one every 4 minutes to ensure it doesn't time-out.
And there's a third automation that ensures you don't go below your minimum SOC.
Predbat can then be configured to target the work mode entity ID to trigger charge or discharge modes.
This may not be the easiest way to do this, but wanted to share the knowledge in case it helps someone.
Steps:
1. Create Helpers:
Number Helpers
Name: FoxESS Charge Power
Minimum Value: 0
Maximum Value: 5000
Step size: 100
Unit of measurement: W
Name: FoxESS Discharge Power
Minimum Value: 0
Maximum Value: 5000
Step size: 100
Unit of measurement: W
These control the maximum allowed power to / from your battery. Mine maxes out at 5,000W, hence above.
Once you've created the helper, you also need to assign a value to it eg 5000
Mode Helper
In configuration.yaml add the below:
Code: Select all
input_select:
foxess_mode:
name: FoxESS Mode
options:
- Self Use
- Force Charge
- Force Discharge
initial: Self Use
icon: mdi:battery
Automations
1. FoxESS Apply Mode
Code: Select all
alias: FoxESS Apply Mode
description: Writes charge/discharge/stop commands to FoxESS inverter via Modbus
variables:
mode: "{{ states('input_select.foxess_mode') }}"
charge_w: "{{ states('input_number.foxess_charge_power') | int(3000) }}"
discharge_w: "{{ states('input_number.foxess_discharge_power') | int(3000) }}"
triggers:
- entity_id:
- input_select.foxess_mode
- input_number.foxess_charge_power
- input_number.foxess_discharge_power
trigger: state
actions:
- choose:
- conditions:
- condition: template
value_template: "{{ mode == 'Self Use' }}"
sequence:
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46001
values: "0"
- conditions:
- condition: template
value_template: "{{ mode == 'Force Charge' }}"
sequence:
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46001
values: "7"
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46002
values: "300"
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46003
values: 0,{{ charge_w }}
- conditions:
- condition: template
value_template: "{{ mode == 'Force Discharge' }}"
sequence:
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46001
values: "5"
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46002
values: "300"
- action: foxess_modbus.write_registers
data:
inverter: [your_inverter_reference]
start_address: 46003
values: 0,{{ discharge_w }}
Code: Select all
alias: FoxESS Remote Control Keepalive
description: Re-sends command every 4 minutes to prevent 300s timeout expiry
triggers:
- minutes: /4
trigger: time_pattern
conditions:
- condition: template
value_template: >
{{ states('input_select.foxess_mode') in ['Force Charge', 'Force
Discharge'] }}
actions:
- action: automation.trigger
target:
entity_id: automation.foxess_apply_mode
3. FoxESS Stop Discharge at Min SoC
Code: Select all
alias: FoxESS Stop Discharge at Min SoC
description: Reverts to Self Use when battery hits MinSoC on Grid threshold
triggers:
- value_template: |
{{ states('sensor.foxess_bat_soc') | float(100)
<= states('sensor.foxess_bat_minsocongrid') | float(10) }}
trigger: template
conditions:
- condition: state
entity_id: input_select.foxess_mode
state: Force Discharge
actions:
- action: input_select.select_option
target:
entity_id: input_select.foxess_mode
data:
option: Self Use