-
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Beta Was this translation helpful? Give feedback.
-
|
I found a solution. The Solakon ONE seems to be a FoxESS under the hood, but the HA integration is a bit different. The Solakon integration does not have any knowledge about grid usage, so it cannot do zero export controlling. You have to use an external system for that, such as this blueprint or better even: this integration. Both also support AC charging, but you should not use it. Predbat will take care of that. You should also set
Minimal Predbat ConfigUse the default config or the FoxESS template, but adjust a few parameters. Replace UPPERCASE stuff with your own sensors. Adjust the pred_bat:
module: predbat
class: PredBat
# XXX: This is a configuration template, delete this line once you edit your configuration
#template: true
# Other standard stuff here
load_today:
- sensor.predbat_load_energy_today
import_today:
- sensor.YOUR_DAILY_GRID_IMPORT_SENSOR
export_today:
- sensor.YOUR_DAILY_GRID_EXPORT_SENSOR
pv_today:
- sensor.solakon_one_effective_pv_energy_today
pv_power:
- sensor.solakon_one_effective_pv_power
load_power:
- sensor.predbat_load_power
grid_power:
- sensor.YOUR_GRID_LOAD_SENSOR
battery_power:
- sensor.solakon_one_battery_power
soc_percent:
- sensor.solakon_one_battery_state_of_charge
soc_max:
- sensor.solakon_one_battery_capacity
battery_voltage:
- sensor.solakon_one_battery_voltage
battery_temperature:
- sensor.solakon_one_battery_max_temperature
# Solakon ONE is a FoxESS inverter internally.
num_inverters: 1
inverter_type: FoxESS
charge_control_immediate: true
output_charge_control: power
charge_rate:
- input_number.predbat_remote_control_charge_power
discharge_rate:
- input_number.predbat_remote_control_discharge_power
reserve:
- number.solakon_one_minimum_state_of_charge_on_grid
charge_start_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "3"
charge_stop_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "0"
discharge_start_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "1"
discharge_stop_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "0"
charge_freeze_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "0"
discharge_freeze_service:
service: select.select_option
entity_id: select.solakon_one_remote_control_mode
option: "0"
# Forecast Solar interface. Configure as needed.
forecast_solar:
- latitude: 0.00
longitude: 0.00
kwp: 1
azimuth: 240
declination: 42
# Either your Octopus price sensor or a reformatted Tibber sensor (see below)
metric_octopus_import: sensor.tibber_predbat_import_rates
# Inverter charge limit is 1200W, discharge is limited to 800W.
inverter_limit:
- 1200
inverter_limit_charge:
- 1200
inverter_limit_discharge:
- 800
# Zero export (don't ever feed into the grid).
export_limit:
- 0
rates_export:
- rate: 0
# Other stuffAdditional Sensors and InputsApart from that, you need the following extra sensors and inputs: input_number:
predbat_remote_control_charge_power:
name: "Predbat Remote Control Charge Power"
icon: mdi:flash
min: 0
max: 1200
step: 1
unit_of_measurement: W
mode: box
predbat_remote_control_discharge_power:
name: "Predbat Remote Control Discharge Power"
icon: mdi:flash
min: 0
max: 800
step: 1
unit_of_measurement: W
mode: box
utility_meter:
solakon_one_battery_discharge_energy_today:
name: "Solakon ONE Battery Discharge Energy Today"
unique_id: solakon_one_battery_discharge_energy_today
source: sensor.solakon_one_grid_export_energy
cycle: daily
solakon_one_battery_charge_energy_today:
name: "Solakon ONE Battery Charge Energy Today"
unique_id: solakon_one_battery_discharge_energy_today
source: sensor.solakon_one_grid_import_energy
cycle: daily
solakon_one_effective_pv_energy_today:
name: "Solakon ONE Effective PV Energy Today"
unique_id: solakon_one_effective_pv_energy_today
source: sensor.solakon_one_effective_pv_power
cycle: daily
sensor:
- platform: integration
name: "Solakon ONE Effective PV Energy"
unique_id: solakon_one_effective_pv_energy
source: sensor.solakon_one_effective_pv_power
unit_prefix: k
unit_time: h
method: left
round: 3
template:
- sensor:
# sensor.solakon_one_pv_power seems to have an almost constant 15W offset and about a 25W dead band.
- name: "Solakon ONE Effective PV Power"
unique_id: solakon_one_effective_pv_power
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >
{% set pv_power = states('sensor.solakon_one_pv_power') | float(0) %}
{% if pv_power > 25 %}{{ max(0, pv_power - 15) }}{% else %}0{% endif %}
- sensor:
- name: "Predbat Load Power"
unique_id: predbat_load_power
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >
{% set grid = states('sensor.YOUR_GRID_LOAD_SENSOR') | float(0) %}
{% set pv = states('sensor.solakon_one_effective_pv_power') | float(0) %}
{% set batt = states('sensor.solakon_one_battery_power') | float(0) %}
{{ max(grid + pv + batt, 0) | round(1) }}
- sensor:
- name: "Predbat Load Energy Today"
unique_id: predbat_load_energy_today
unit_of_measurement: "kWh"
device_class: energy
state_class: total
state: >
{% set grid_import = states('sensor.YOUR_DAILY_GRID_IMPORT_SENSOR') | float(0) %}
{% set grid_export = states('sensor.YOUR_DAILY_GRID_EXPORT_SENSOR') | float(0) %}
{% set pv = states('sensor.solakon_one_effective_pv_energy_today') | float(0) %}
{% set battery_discharge = states('sensor.solakon_one_battery_discharge_energy_today') | float(0) %}
{% set battery_charge = states('sensor.solakon_one_battery_charge_energy_today') | float(0) %}
{{ max(grid_import + pv + battery_discharge - battery_charge - grid_export, 0) | round(3) }}As well as this automation to forward charge/discharge power. Without it, Predbat will always try to write both 1200W and 800W to the same sensor, and it will interfere with the zero export integration: automation:
- alias: Solakon Predbat Remote Control Power Sync
id: solakon_predbat_remote_control_power_sync
mode: restart
triggers:
- trigger: state
entity_id:
- input_number.predbat_remote_control_charge_power
- input_number.predbat_remote_control_discharge_power
- predbat.status
conditions:
- condition: state
entity_id: input_boolean.solakon_predbat_remote_control_active
state: "on"
actions:
- choose:
- conditions:
- condition: state
entity_id: predbat.status
state: "Charging"
sequence:
- action: number.set_value
target:
entity_id: number.solakon_one_remote_control_power
data:
value: "{{ states('input_number.predbat_remote_control_charge_power') | float(0) }}"
- conditions:
- condition: state
entity_id: predbat.status
state: "Discharging"
sequence:
- action: number.set_value
target:
entity_id: number.solakon_one_remote_control_power
data:
value: "{{ states('input_number.predbat_remote_control_discharge_power') | float(0) }}"If you use Tibber instead of Octopus, I recommend this integration. Then you only need to convert the price information to the format expected by Predbat: template:
- trigger:
- platform: homeassistant
event: start
- platform: state
entity_id: sensor.TIBBER_CURRENT_PRICE_SENSOR
action:
- action: tibber_prices.get_chartdata
data:
day:
- today
- tomorrow
output_format: array_of_objects
resolution: interval
price_source: total
subunit_currency: false
response_variable: tibber_chartdata
sensor:
- name: "Tibber Predbat Import Rates"
unique_id: tibber_predbat_import_rates
unit_of_measurement: "EUR/kWh"
state_class: measurement
state: >
{{ states('sensor.TIBBER_CURRENT_PRICE_SENSOR') | float(0) }}
attributes:
raw_today: >
{% set rows = tibber_chartdata.data | default([]) %}
{% set ns = namespace(out=[]) %}
{% for r in rows %}
{% set start = as_datetime(r.start_time) %}
{% if start.date() == now().date() %}
{% set ns.out = ns.out + [{
'start': start.isoformat(),
'end': (start + timedelta(minutes=15)).isoformat(),
'value': r.price_per_kwh | float
}] %}
{% endif %}
{% endfor %}
{{ ns.out | to_json }}
raw_tomorrow: >
{% set rows = tibber_chartdata.data | default([]) %}
{% set ns = namespace(out=[]) %}
{% for r in rows %}
{% set start = as_datetime(r.start_time) %}
{% if start.date() == (now() + timedelta(days=1)).date() %}
{% set ns.out = ns.out + [{
'start': start.isoformat(),
'end': (start + timedelta(minutes=15)).isoformat(),
'value': r.price_per_kwh | float
}] %}
{% endif %}
{% endfor %}
{{ ns.out | to_json }}Zero-Export IntegrationThe config above will charge your battery when Predbat sees the need, but it will only disable the Solakon remote control otherwise. To actually discharge the battery, use the zero-export integration mentioned above and then use the following scripts in place of the explicit service calls from above to toggle solakon_predbat_remote_control_enable:
alias: Solakon Predbat Remote Control Enable
mode: restart
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.solakon_predbat_remote_control_active
- service: number.set_value
target:
entity_id: number.solakon_one_force_mode_duration
data:
value: 60
- service: number.set_value
target:
entity_id: number.solakon_one_remote_control_timeout
data:
value: 3600
solakon_predbat_remote_control_disable:
alias: Solakon Predbat Remote Control Disable
mode: restart
sequence:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.solakon_predbat_remote_control_active
- service: number.set_value
target:
entity_id: number.solakon_one_force_mode_duration
data:
value: 0
- service: number.set_value
target:
entity_id: number.solakon_one_remote_control_timeout
data:
value: 0
solakon_predbat_charge_start:
alias: Solakon Predbat Charge Start
mode: restart
sequence:
- service: script.solakon_predbat_remote_control_enable
# Enable Inverter import (PV priority).
- service: select.select_option
target:
entity_id: select.solakon_one_remote_control_mode
data:
option: "3"
solakon_predbat_charge_stop:
alias: Solakon Predbat Charge Stop
mode: restart
sequence:
- service: script.solakon_predbat_remote_control_disable
solakon_predbat_discharge_start:
alias: Solakon Predbat Discharge Start
mode: restart
sequence:
- service: script.solakon_predbat_remote_control_enable
# Enable Inverter export (PV priority).
- service: select.select_option
target:
entity_id: select.solakon_one_remote_control_mode
data:
option: "1"
- service: number.set_value
target:
entity_id: number.solakon_one_maximum_discharge_current
data:
value: 40
solakon_predbat_discharge_stop:
alias: Solakon Predbat Discharge Stop
mode: restart
sequence:
- service: script.solakon_predbat_remote_control_disable
solakon_predbat_hold_start:
alias: Solakon Predbat Hold Start
mode: restart
sequence:
- service: script.solakon_predbat_remote_control_enable
# Hold charge / disable active remote power.
- service: select.select_option
target:
entity_id: select.solakon_one_remote_control_mode
data:
option: "0"
# Prevent battery discharge.
- service: number.set_value
target:
entity_id: number.solakon_one_remote_control_power
data:
value: 0
- service: number.set_value
target:
entity_id: number.solakon_one_maximum_discharge_current
data:
value: 0
solakon_predbat_hold_stop:
alias: Solakon Predbat Hold Stop
mode: restart
sequence:
# Re-enable battery discharge.
- service: number.set_value
target:
entity_id: number.solakon_one_maximum_discharge_current
data:
value: 40
- service: script.solakon_predbat_remote_control_disableWith the following periodic automation: input_boolean:
solakon_predbat_remote_control_active:
name: Solakon Predbat Remote Control Active
icon: mdi:remote
automation:
- id: solakon_predbat_remote_control_refresh
alias: Solakon Predbat Remote Control Refresh
mode: restart
triggers:
- trigger: state
entity_id: input_boolean.solakon_predbat_remote_control_active
id: remote_control_changed
- trigger: time_pattern
seconds: "/15"
id: refresh
actions:
- choose:
# Predbat remote control is active:
# Disable zero-export and refresh Solakon timeout/duration.
- conditions:
- condition: state
entity_id: input_boolean.solakon_predbat_remote_control_active
state: "on"
sequence:
- action: switch.turn_off
target:
entity_id: switch.solakon_zero_export_regelung_aktiv
- action: script.solakon_predbat_remote_control_enable
# Predbat remote control switched off:
# Reset remote control exactly once and concede control to zero export.
- conditions:
- condition: trigger
id: remote_control_changed
- condition: template
value_template: >
{{ trigger.from_state is not none
and trigger.to_state is not none
and trigger.from_state.state == 'on'
and trigger.to_state.state == 'off' }}
sequence:
- action: script.solakon_predbat_remote_control_disable
- action: switch.turn_on
target:
entity_id: switch.solakon_zero_export_regelung_aktivAnd then in the Predbat config: charge_start_service:
service: script.solakon_predbat_charge_start
charge_stop_service:
service: script.solakon_predbat_charge_stop
discharge_start_service:
service: script.solakon_predbat_discharge_start
discharge_stop_service:
service: script.solakon_predbat_discharge_stop
charge_freeze_service:
service: script.solakon_predbat_hold_start
discharge_freeze_service:
service: script.solakon_predbat_hold_startMake sure you don't have Tariff charging enabled in the zero-export integration. I would also lower the Zone 1 SoC threshold, since Predbat decides when the battery should be preserved or not. |
Beta Was this translation helpful? Give feedback.




I found a solution. The Solakon ONE seems to be a FoxESS under the hood, but the HA integration is a bit different.
The Solakon integration does not have any knowledge about grid usage, so it cannot do zero export controlling. You have to use an external system for that, such as this blueprint or better even: this integration. Both also support AC charging, but you should not use it. Predbat will take care of that.
You should also set
input_number.predbat_set_reserve_minin the Predbat settings to at least 10%, not 4%.input_number.predbat_manual_soc_valueshould be at most 99%, otherwise you'll be zig-zagging between 99% and 100% a lot.input_number.predbat_battery_lossandinput_number.…