I'm currently having problems using FoxESS-Modbus with my KH7 inverter, and was wondering whether FoxESS-Control could solve my problems?
The problem with FoxESS-Modbus is: it can only put the inverter into one of three work modes:
- Self Use
- Back Up (when Back-Up or Force Charge is selected in FoxESS-Modbus)
- Feed-In Priority (when Feed-in First or Force Discharge is selected in FoxESS-Modbus)
The problem is that, due to the above limitations:
- If Force Charge (Back Up) mode is invoked when excess solar is being generated the excess solar is discarded - it is neither exported nor used to charge the battery
- If Force Discharge (Feed-In Priority) is selected it will not export charge from the battery to take advantage of good export rates unless feed-in limits have been exceeded. It will only export excess solar to the grid.
This means that I lose two major benefits of predbat:
- taking advantage of cheap/free/negative import rates to charge the battery during the day without discarding excess solar energy that is being generated at the time
- taking advantage of high export rates by exporting charge from the battery.
Could FoxESS-Control help with any of this?
Personally, I’d chat with ChatGPT.
I put what I wanted into Codex and now it runs my Solar via HA automations.
I put what I wanted into Codex and now it runs my Solar via HA automations.
Fox 7kW HYBRID inverter with Fox EP11 10kWh battery
Would you be able to post an example of one of your automations, so that I can get an idea of the basic principles and methods?
Code: Select all
alias: Solar - Ohme EV Charging Guard
description: >-
Clean-slate Ohme and solar-battery guard.
Current intent:
- Allow Ohme without approval during cheap Octopus/Intelligent periods or when
genuine excess solar is available.
- Require approval during expensive periods without excess solar.
- Never allow the solar battery to discharge into the EV.
- During cheap/Intelligent periods, block battery discharge only while Ohme is
actively charging.
- Let the battery discharge for normal house load at other times, including
overnight.
- Top the battery up late in the cheap window, then return to Self Use at
05:30 or once SOC is above 90%.
- Keep inverter SOC limits fixed at Min 10% and Max 100%.
triggers:
- trigger: homeassistant
event: start
id: startup
- trigger: time_pattern
minutes: /1
id: periodic_guard
- trigger: time
at: "23:30:00"
id: fixed_offpeak_start
- trigger: time
at: "05:30:00"
id: fixed_offpeak_end
- trigger: state
entity_id:
- sensor.octopus_energy_electricity_2GUID_current_rate
- >-
binary_sensor.octopus_energy_0GUID_intelligent_dispatching
- sensor.ohme_epod_status
- sensor.ohme_epod_power
- switch.garage_ohme_epod_solar_boost
- switch.ohme_epod_require_approval
id: state_changed
- trigger: numeric_state
entity_id: sensor.home_solar_feed_in
above: 1.4
for:
minutes: 2
id: excess_solar_available
- trigger: numeric_state
entity_id: sensor.home_solar_feed_in
below: 0.35
for:
minutes: 1
id: excess_solar_lost
- trigger: numeric_state
entity_id: sensor.home_solar_battery_discharge
above: 0.05
for:
seconds: 15
id: battery_discharge_guard
- trigger: numeric_state
entity_id: sensor.home_solar_grid_consumption
above: 0.08
for:
minutes: 1
id: grid_import_guard
- trigger: state
entity_id:
- number.home_solar_min_soc
- number.home_solar_min_soc_on_grid
- number.home_solar_max_soc
- number.home_solar_max_discharge_current
id: inverter_setting_changed
- trigger: time
at: "03:30:00"
id: late_topup_start
conditions: []
actions:
- variables:
rate: >-
{{
states('sensor.octopus_energy_electricity_2GUID_current_rate')
| float(999) }}
fixed_offpeak: >-
{{ now().hour > 23 or (now().hour == 23 and now().minute >= 30) or
now().hour < 5 or (now().hour == 5 and now().minute < 30) }}
cheap_rate: >-
{{
states('sensor.octopus_energy_electricity_2GUID_current_rate')
| float(999) < 0.08 }}
intelligent_slot: >-
{{
is_state('binary_sensor.octopus_energy_0GUID_intelligent_dispatching',
'on') or
state_attr('sensor.octopus_energy_electricity_2GUID_current_rate',
'is_intelligent_adjusted') == true }}
cheap_or_intelligent: "{{ cheap_rate or intelligent_slot or fixed_offpeak }}"
excess_solar: "{{ states('sensor.home_solar_feed_in') | float(0) >= 1.4 }}"
ev_charging: >-
{{ states('sensor.ohme_epod_status') == 'charging' or
states('sensor.ohme_epod_power') | float(0) > 0.2 }}
ev_ready: >-
{{ states('sensor.ohme_epod_status') in ['charging', 'plugged_in',
'pending_approval'] }}
battery_discharge: "{{ states('sensor.home_solar_battery_discharge') | float(0) }}"
grid_import: "{{ states('sensor.home_solar_grid_consumption') | float(0) }}"
ohme_mode: "{{ states('select.ohme_epod_charge_mode') }}"
allowed_without_approval: "{{ cheap_or_intelligent or excess_solar }}"
battery_soc: "{{ states('sensor.home_solar_battery_soc') | float(0) }}"
late_topup_window: >-
{{ (now().hour == 3 and now().minute >= 30) or now().hour == 4 or
(now().hour == 5 and now().minute < 30) }}
- choose:
- alias: Keep Min SoC at 10 if too high
conditions:
- condition: numeric_state
entity_id: number.home_solar_min_soc
above: 10
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_min_soc
data:
value: 10
- alias: Keep Min SoC at 10 if too low
conditions:
- condition: numeric_state
entity_id: number.home_solar_min_soc
below: 10
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_min_soc
data:
value: 10
default: []
- choose:
- alias: Keep Min SoC on Grid at 10 if too high
conditions:
- condition: numeric_state
entity_id: number.home_solar_min_soc_on_grid
above: 10
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_min_soc_on_grid
data:
value: 10
- alias: Keep Min SoC on Grid at 10 if too low
conditions:
- condition: numeric_state
entity_id: number.home_solar_min_soc_on_grid
below: 10
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_min_soc_on_grid
data:
value: 10
default: []
- choose:
- alias: Keep Max SoC at 100
conditions:
- condition: numeric_state
entity_id: number.home_solar_max_soc
below: 100
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_soc
data:
value: 100
default: []
- alias: Late cheap-window battery top-up control
choose:
- alias: Return battery to Self Use above 90% or when cheap window ends
conditions:
- condition: or
conditions:
- condition: trigger
id: fixed_offpeak_end
- condition: and
conditions:
- condition: time
after: "03:30:00"
before: "05:30:00"
- condition: numeric_state
entity_id: sensor.home_solar_battery_soc
above: 90
sequence:
- action: select.select_option
target:
entity_id: select.home_solar_work_mode
data:
option: Self Use
- alias: Late cheap-window top-up until SOC is above 90%
conditions:
- condition: time
after: "03:30:00"
before: "05:30:00"
- condition: numeric_state
entity_id: sensor.home_solar_battery_soc
below: 90
- condition: template
value_template: "{{ cheap_or_intelligent }}"
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_soc
data:
value: 100
- action: number.set_value
target:
entity_id: number.home_solar_max_charge_current
data:
value: 50
- action: select.select_option
target:
entity_id: select.home_solar_work_mode
data:
option: Force Charge
default: []
- choose:
- alias: >-
Cheap/Intelligent EV availability: allow Ohme, block battery only
while actively charging
conditions:
- condition: template
value_template: "{{ cheap_or_intelligent and ev_ready }}"
sequence:
- action: switch.turn_off
target:
entity_id: switch.ohme_epod_require_approval
- action: switch.turn_on
target:
entity_id: switch.garage_ohme_epod_solar_boost
- choose:
- alias: Resume Ohme if paused in cheap/Intelligent period
conditions:
- condition: state
entity_id: select.ohme_epod_charge_mode
state: paused
sequence:
- action: select.select_option
target:
entity_id: select.ohme_epod_charge_mode
data:
option: smart_charge
default: []
- choose:
- alias: Clamp battery discharge only while Ohme is actively charging
conditions:
- condition: template
value_template: "{{ ev_charging }}"
- condition: numeric_state
entity_id: number.home_solar_max_discharge_current
above: 0
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_discharge_current
data:
value: 0
- alias: Release battery discharge when Ohme is not actively charging
conditions:
- condition: template
value_template: "{{ not ev_charging }}"
- condition: numeric_state
entity_id: number.home_solar_max_discharge_current
below: 25
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_discharge_current
data:
value: 25
default: []
- alias: >-
Expensive with excess solar: allow Ohme without approval, keep battery
available
conditions:
- condition: template
value_template: "{{ not cheap_or_intelligent and excess_solar and ev_ready }}"
sequence:
- choose:
- alias: Pause Ohme if solar charging starts using battery or grid
conditions:
- condition: template
value_template: >-
{{ ev_charging and (battery_discharge > 0.05 or
grid_import > 0.08 or (trigger is defined and trigger.id
in ['battery_discharge_guard', 'grid_import_guard'])) }}
sequence:
- action: select.select_option
target:
entity_id: select.ohme_epod_charge_mode
data:
option: paused
- action: persistent_notification.create
data:
title: Ohme charging paused
message: "Ohme paused: battery/grid detected."
notification_id: SolarOhmeGuardPaused
- alias: Allow Ohme on genuine excess solar
conditions:
- condition: template
value_template: >-
{{ not (ev_charging and (battery_discharge > 0.05 or
grid_import > 0.08)) }}
sequence:
- action: switch.turn_off
target:
entity_id: switch.ohme_epod_require_approval
- action: switch.turn_on
target:
entity_id: switch.garage_ohme_epod_solar_boost
- choose:
- alias: Resume Ohme for solar charging
conditions:
- condition: state
entity_id: select.ohme_epod_charge_mode
state: paused
sequence:
- action: select.select_option
target:
entity_id: select.ohme_epod_charge_mode
data:
option: smart_charge
default: []
- choose:
- alias: >-
Release battery discharge for house load during
expensive solar charging
conditions:
- condition: numeric_state
entity_id: number.home_solar_max_discharge_current
below: 25
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_discharge_current
data:
value: 25
default: []
default: []
- alias: >-
Expensive without excess solar: require approval and keep house
battery available
conditions:
- condition: template
value_template: "{{ not cheap_or_intelligent and not excess_solar }}"
sequence:
- action: switch.turn_on
target:
entity_id: switch.ohme_epod_require_approval
- choose:
- alias: Release battery discharge for house load during expensive rate
conditions:
- condition: numeric_state
entity_id: number.home_solar_max_discharge_current
below: 25
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_discharge_current
data:
value: 25
default: []
- choose:
- alias: >-
Pause Ohme if it is charging during expensive rate without
solar cover
conditions:
- condition: template
value_template: >-
{{ ev_charging and (battery_discharge > 0.05 or
grid_import > 0.08 or (trigger is defined and trigger.id
in ['battery_discharge_guard', 'grid_import_guard'])) }}
sequence:
- action: select.select_option
target:
entity_id: select.ohme_epod_charge_mode
data:
option: paused
- action: persistent_notification.create
data:
title: Ohme charging paused
message: "Ohme paused: expensive rate and no excess solar."
notification_id: SolarOhmeGuardPaused
default: []
default:
- choose:
- alias: "No EV ready: keep battery available"
conditions:
- condition: numeric_state
entity_id: number.home_solar_max_discharge_current
below: 25
sequence:
- action: number.set_value
target:
entity_id: number.home_solar_max_discharge_current
data:
value: 25
default: []
mode: restart
Fox 7kW HYBRID inverter with Fox EP11 10kWh battery