Inverter Setup

PredBat was originally written for GivEnergy inverters using the GivTCP integration but this is now being extended to other inverter models:

Name Integration Template
GivEnergy with GivTCP GivTCP givenergy_givtcp.yaml
Solis Hybrid inverters Solax Modbus integration ginlong_solis.yaml
Solax Gen4 inverters Solax Modbus integration in Modbus Power Control Mode solax_sx4.yaml
Sofar inverters Sofar MQTT integration sofar.yaml
Huawei inverters Huawei Solar huawei.yaml
SolarEdge inverters Solaredge Modbus Multi solaredge.yaml
Givenergy with GE Cloud ge_cloud givenergy_cloud.yaml
Givenergy with GE Cloud EMC ge_cloud givenergy_ems.yaml
SunSynk Sunsynk sunsynk.yaml
Fox Foxess fox.yaml

Note that support for all these inverters is in various stages of development. Please expect things to fail and report them as Issues on Github.

NB: By default the apps.yaml template for GivTCP is installed with Predbat. If you are using a different inverter then you will need to copy the appropriate apps.yaml template from the above list and use it to replace the GivTCP apps.yaml - if you copy but don't replace the standard template then Predbat will not function correctly.

GivEnergy with GivTCP

Its recommended that you firstly watch the Installing GivTCP and Mosquitto Add-on's video from Speak to the Geek. Although the video covers GivTCP v2 and v3 has been recently released, the install and setup process is very similar.

The below instructions assume you are installing GivTCP v3, with changes highlighted against GivTCP v2 as covered in the video.

  1. Install Mosquitto Broker add-on:
  • Go to Settings / Add-ons / Add-on Store (bottom right)
  • Scroll down the add-on store list, to find 'Mosquitto broker', click on the add-on, then click 'INSTALL'
  • Once the Mosquitto broker has been installed, ensure that the 'Start on boot' and 'Watchdog' options are turned on, and click 'START' to start the add-on
  • Next, configure Mosquitto broker by going to Settings / Devices and Services / Integrations. Mosquitto broker should appear as a Discovered integration so click the blue 'CONFIGURE' button, then SUBMIT to complete configuring Mosquitto broker
  • With GivTCP v3 you no longer need to create a dedicated Home Assistant user for MQTT so this part of the video can be skipped over
  1. Install the GivTCP add-on:
  • Go to Settings / Add-ons / Add-on Store
  • Click the three dots in the top right corner, then Repositories
  • You'll need to add the GivTCP repository as an additional custom repository so paste/type 'https://github.com/britkat1980/ha-addons' into the text box and click 'Add' the 'Close'
    NB: this URL is for GivTCP v3, not v2 as covered in the video.
  • Click the back button and then re-navigate to Settings / Add-ons / Add-on Store so Home Assistant picks up the GivTCP add-on from the custom repository
  • Scroll down the add-on store list, to find 'GivTCP-V3', you should see the three addon's; the production version, the latest beta and the latest dev versions. Click on the 'GivTCP' add-on, then click 'INSTALL'
  • Once GivTCP has been installed, ensure that the 'Start on boot' and 'Watchdog' options are turned on
  1. Configure GivTCP:
  • The configuration process for GivTCP in v3 has changed from that shown in the video, the Configuration tab is now no longer used and all configuration is now done via the add-on's Web interface
  • On the GivTCP add-on, click 'START' to start the add-on
  • Once the add-on has started, click 'Open Web UI' or go to http://homeassistant.local:8099/, then click 'Go to Config Page' to configure GivTCP
  • GivTCP will auto-discover your inverters and batteries so you shouldn't need to manually enter these, but check the IP address(s) it finds are correct
  • If you have multiple inverters you may wish to change the default device prefixes that GivTCP assigns ('givtcp', 'givtcp2', 'givtcp3', etc) to make it easier to identify your devices within Home Assistant.
    For example if you have a gateway and two AIO's you could use the prefixes 'GW', 'AIO-1' and 'AIO-2'. The prefixes should be set before you start using GivTCP in anger as changing the prefixes later on will result in both the old and new sensor names appearing in Home Assistant with the 'old' sensors being "unavailable".
    Note that if you do change the givtcp prefixes then you will also have to edit the apps.yaml configuration file to match, and change the sensor names that predbat is looking for (by default prefixed 'givtcp_xxx') to your new sensor naming structure
  • Click Next and Next to get to the Selfrun page, and turn on Self run. The Self Run Loop Timer is how often GivTCP will retrieve data from your inverters - it's recommended that set this to a value between 20 and 60, but not less than 15 seconds as otherwise the inverter will then spend all its time talking to GivTCP and won't communicate with the GivEnergy portal and app
  • GivTCP now auto-populates the MQTT page so as long as you're using Mosquitto broker within Home Assistant; you won't need to create a dedicated MQTT user or enter the details on the MQTT page
  • You don't need to configure the Influx page. Tariff and Palm pages can also be skipped as these functions are done by Predbat
  • (Optional) On the Web page, you can turn the Dashboard on to see a simple power flow diagram for your inverters (similar to the GivEnergy mobile app)
  • On the 'Misc' page check that 'Print Raw' is set to on for added monitoring
  • Finally click 'Save and Restart' and GivTCP should start communicating with your inverters and will automatically create a set of 'givtcp_xxx' entities in Home Assistant for your inverter data, inverter controls and battery data
  • Check the GivTCP Log tab that there aren't any errors; it should end with 'Publishing Home Assistant Discovery messages'
  1. Specific Predbat configuration requirements for certain GivEnergy equipment

The rest of the Predbat installation instructions should now be followed, but its worth highlighting that there are a few specific settings that should be set for certain GivEnergy equipment. These settings are documented in the appropriate place in the documentation, but for ease of identification, are repeated here:

  • If you are using GivTCP v3 and have an AIO or 3 phase inverter then you will need to manually set geserial in apps.yaml to your inverter serial number
  • If you have a single AIO then control is directly to the AIO. Ensure geserial in apps.yaml is correctly picking the AIO and comment out geserial2 lines
  • If you have multiple AIO's then all control of the AIO's is done through the Gateway so geserial in apps.yaml should be set to the Gateway serial number
  • If you have a 2.6kWh, 5.2kWh or AIO battery then you will need to set battery_scaling in apps.yaml as the battery size is incorrectly reported to GivTCP
  • If you have a Gen 2, Gen 3 or AIO then you may need to set inverter_reserve_max in apps.yaml to 98. If you have a Gen 1 or a firmware version that allows reserve being set to 100 then you can change the default from 98 to 100
  • If your inverter has been wired as an EPS (Emergency Power Supply) or AIO 'whole home backup', consider setting input_number.predbat_set_reserve_min to reserve some battery power for use in emergencies.

NB: GivTCP and Predbat do not currently yet work together for 3 phase inverters. This is being worked on by the author of GivTCP, e.g. see GivTCP issue: unable to charge or discharge 3 phase inverters with predbat

Solis Inverters

To run PredBat with Solis hybrid inverters, follow the following steps:

  1. Install PredBat as per the Installation Summary
  2. Ensure that you have the Solax Modbus integration running. There are a number of entities which this integration disables by default that you will need to enable via the Home Assistant GUI:
Name Description
sensor.solisx_rtc Real Time Clock
sensor.solisx_battery_power Battery Power
  1. Instead of apps.yaml use ginlong_solis.yaml from this Repo as your starting template. The majority of settings should be correct but please check. You will need to un-comment the template line to enable it. Save it to the config/appdaemon/apps/predbat/config folder. Set solax_modbus_new in apps.yaml to True if you have integration version 2024.03.2 or greater
  2. Ensure that the inverter is set Control Mode 35 - on the Solax integration this is Timed Charge/Discharge. If you want to use the Reserve functionality within PredBat you will need to select Backup/Reserve (code 51) instead but be aware that this is not fully tested. In due course these mode settings will be incorporated into the code.

Solax Gen4 Inverters

Use the template configuration from: solax.sx4.yaml

  • Set solax_modbus_new in apps.yaml to True if you have integration version 2024.03.2 or greater

Please see this ticket in Github for ongoing discussion: https://github.com/springfall2008/batpred/issues/259

Sofar Inverters

For this integration the key elements are:

  • Hardware - sofar2mqtt EPS board - Relatively easy to solder and flash, or can be bought pre-made.
  • Software - Sofar MQTT integration - MQTT integration
  • Home Assistant configuration - sofar_inverter.yaml package (in templates directory) with the MQTT sensors. This is the default with a couple of additional inputs to support battery capacity. This should be installed in Home Assistant.
  • Predbat configuration - sofar.yaml template for Predbat (in templates directory). This file should be copied to apps.yaml

  • Please note that the inverter needs to be put into "Passive Mode" for the sofar2mqtt to control the inverter.

  • This integration has various limitations, it can charge and discharge the battery but does not have finer control over reserve and target SOC%
  • Note: You will need to change the min reserve in Home Assistant to match your minimum battery level (input_number.predbat_set_reserve_min).

Please see this ticket in Github for ongoing discussions: https://github.com/springfall2008/batpred/issues/395

Huawei Inverters

Discussion ticket is here: https://github.com/springfall2008/batpred/issues/684

SolarEdge Inverters

Discussion ticket is here: https://github.com/springfall2008/batpred/issues/181

  • Please copy the template apps.yaml from https://github.com/springfall2008/batpred/blob/main/templates/solaredge.yaml and modify for your system
  • Ensure that number.solaredge_i1_storage_command_timeout is set to reasonably high value e.g. 3600 seconds to avoid the commands issued being cancelled
  • Power Control Options, as well as Enable Battery Control, must be enabled in the Solaredge Modbus Multi integration configuration, and switch.solaredge_i1_advanced_power_control must be on.

  • For pv_today, pv_power and load_power sensors to work you need to create this as a template within your Home Assistant configuration.yml Please see: https://gist.github.com/Ashpork/f80fb0d3cb22356a12ed24734065061c. These sensors are not critical so you can just comment it out in apps.yaml if you can't get it to work

template:
  - sensor:
      - name: "Solar Panel Production W"
        unique_id: solar_panel_production_w
        unit_of_measurement: "W"
        icon: mdi:solar-power
        state: >
          {% set i1_dc_power = states('sensor.solaredge_i1_dc_power') | float(0) %}
          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}
          {% if (i1_dc_power + b1_dc_power <= 0) %}
            0
          {% else %}
            {{ (i1_dc_power + b1_dc_power) }}
          {% endif %}
        availability: >
          {{ states('sensor.solaredge_i1_dc_power') | is_number and states('sensor.solaredge_b1_dc_power') | is_number }}

      - name: "Solar House Consumption W"
        unique_id: solar_house_consumption_w
        unit_of_measurement: "W"
        icon: mdi:home
        state: >
          {% set i1_ac_power = states('sensor.solaredge_i1_ac_power') | float(0) %}
          {% set m1_ac_power = states('sensor.solaredge_m1_ac_power') | float(0) %}
          {% if (i1_ac_power - m1_ac_power <= 0) %}
            0
          {% else %}
            {{ (i1_ac_power - m1_ac_power) }}
          {% endif %}
        availability: >
          {{ states('sensor.solaredge_i1_ac_power') | is_number and states('sensor.solaredge_m1_ac_power') | is_number }}

sensor:
  - platform: integration
    source: sensor.solar_panel_production_w
    method: left
    unit_prefix: k
    name: solar_panel_production_kwh

Givenergy with ge_cloud

This is experimental system, please discuss on the ticket: https://github.com/springfall2008/batpred/issues/905

  • First set up ge_cloud integration using your API key https://github.com/springfall2008/ge_cloud
  • Now copy the template givenergy_cloud.yaml from templates into your apps.yaml and edit
    • Set geserial to your inverter serial
  • Make sure discharge down to registers are set to 4% and slots 2, 3 and 4 for charge and discharge are disabled (if you have them)

Givenergy with EMC

  • First set up ge_cloud integration using your API key https://github.com/springfall2008/ge_cloud
  • Now copy the template givenergy_emc.yaml from templates into your apps.yaml and edit
    • Set geserial to your first inverter serial and geserial2 to the second (look in HA for entity names)
    • Set geseriale to the EMS inverter serial number (look in HA for entity names)
  • Turn off slots 2, 3 and 4 for charge, export and discharge as Predbat will only use 1 slot (set the start and end times to 00:00)

Fox

Experimental

Template is in the templates area, give it a try

Sunsynk

  • Copy the Sunsynk apps.yaml template and edit for your system.
  • Create the automations below
  • Create the value templates below

See: https://github.com/springfall2008/batpred/issues/1331

SunSynk automations

Copy into your HA automations

Predbat Charge/Discharge Control

alias: Predbat Charge / Discharge Control
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.predbat_charging
    to: "on"
    id: predbat_charge_on
  - platform: state
    entity_id:
      - binary_sensor.predbat_charging
    to: "off"
    id: predbat_charge_off
  - platform: state
    entity_id:
      - binary_sensor.predbat_discharging
    to: "on"
    id: predbat_discharge_on
  - platform: state
    entity_id:
      - binary_sensor.predbat_discharging
    to: "off"
    id: predbat_discharge_off
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - predbat_charge_on
        sequence:
          - service: switch.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: switch.sunsynk_grid_charge_timezone1
      - conditions:
          - condition: trigger
            id:
              - predbat_charge_off
        sequence:
          - service: switch.turn_off
            target:
              entity_id:
                - switch.sunsynk_grid_charge_timezone1
            data: {}
      - conditions:
          - condition: trigger
            id:
              - predbat_discharge_on
        sequence:
          - service: switch.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: switch.sunsynk_solar_sell
      - conditions:
          - condition: trigger
            id:
              - predbat_discharge_off
        sequence:
          - service: switch.turn_off
            target:
              entity_id:
                - switch.sunsynk_solar_sell
            data: {}
mode: single

Update the charge limits across all timezone's

alias: PredBat - Copy Charge Limit
description: Copy Battery SOC to all time slots
trigger:
  - platform: state
    entity_id:
      - number.sunsynk_set_soc_timezone1
    to: null
condition: []
action:
  - service: number.set_value
    data_template:
      entity_id:
        - number.sunsynk_set_soc_timezone2
        - number.sunsynk_set_soc_timezone3
        - number.sunsynk_set_soc_timezone4
        - number.sunsynk_set_soc_timezone5
        - number.sunsynk_set_soc_timezone6
      value: "{{ states('number.sunsynk_set_soc_timezone1')|int(20) }}"
mode: single

SunSynk Value templates

Copy into your template/sensor area of configuration.yaml

template:
  sensor:
    xxxxx

Sunsynk Battery Max Charge Rate

- name: "sunsynk_max_battery_charge_rate"
  unit_of_measurement: "w"
  state_class: measurement
  state: >
    {{ [8000,[states('input_number.sunsynk_battery_max_charge_current_limit')|int,states('sensor.sunsynk_battery_charge_limit_current')|int]|min
        * states('sensor.sunsynk_battery_voltage')|float]|min }}

Sunsynk Battery Max DisCharge Rate

- name: "sunsynk_max_battery_discharge_rate"
  unit_of_measurement: "w"
  state_class: measurement
  state: >
    {{ [8000,[states('input_number.sunsynk_battery_max_discharge_current_limit')|int,states('sensor.sunsynk_battery_discharge_limit_current')|int]|min
        * states('sensor.sunsynk_battery_voltage')|float]|min }}

Sunsynk Charge Rate Calc

- name: "sunsynk_charge_rate_calc"
  unit_of_measurement: "w"
  state_class: measurement
  state: >
     {{ [8000,[states('input_number.test_sunsynk_battery_max_charge_current')|int,states('sensor.sunsynk_battery_charge_limit_current')|int]|min
         * states('sensor.sunsynk_battery_voltage')|float]|min }}

Sunsynk Discharge Rate Calc

- name: "sunsynk_discharge_rate_calc"
  unit_of_measurement: "w"
  state_class: measurement
  state: >
     {{ [8000,[states('input_number.test_sunsynk_battery_max_discharge_current')|int,states('sensor.sunsynk_battery_discharge_limit_current')|int]|min
         * states('sensor.sunsynk_battery_voltage')|float]|min }}

I want to add an unsupported inverter to Predbat

  • First copy one of the template configurations that is close to your system and try to configure it to match the sensors you have
  • Create a github ticket for support and add in what you know to the ticket
  • Then find out how to control your inverter inside Home Assistant, ideally share any automation you have to control the inverter
  • You can create a new inverter type in apps.yaml and change the options as to which controls it has
  • The easy way to integrate is to use a HA service to start charges and discharges, edit the template below
 inverter_type: MINE
 inverter:
    name : "My Shiny new Inverter"
    has_rest_api: False
    has_mqtt_api: False
    output_charge_control: "power"
    has_charge_enable_time: False
    has_discharge_enable_time: False
    has_target_soc: False
    has_reserve_soc: False
    charge_time_format: "S"
    charge_time_entity_is_option: False
    soc_units: "%"
    num_load_entities: 1
    has_ge_inverter_mode": False
    time_button_press: False
    clock_time_format: "%Y-%m-%d %H:%M:%S"
    write_and_poll_sleep: 2
    has_time_window: False
    support_charge_freeze: False
    support_discharge_freeze": False

  # Services to control charging/discharging
  charge_start_service:
    service: select.select_option
    entity_id: "select.solaredge_i1_storage_command_mode"
    option: "Charge from Solar Power and Grid"
  charge_stop_service:
    service: select.select_option
    entity_id: "select.solaredge_i1_storage_command_mode"
    option: "Charge from Solar Power"
  discharge_start_service:
    service: select.select_option
    entity_id: "select.solaredge_i1_storage_command_mode"
    option: "Maximize Self Consumption"

Inverter control option

The follow options are supported per inverter:

has_rest_api

When True the REST API will be used to fetch data/control the inverter. This is currently only for GivEnergy inverters with GivTCP and givtcp_rest must be set in apps.yaml

has_mqtt_api

When True the MQTT API to Home Assistant will be used to issue control messages for the inverter

The mqtt/publish service is used with the topic as defined by mqtt_topic in apps.yaml

Messages will be sent these controls:

Values that are updated:

  • topic/set/reserve - payload=reserve
  • topic/set/charge_rate - payload=new_rate
  • topic/set/discharge_rate - payload=new_rate
  • topic/set/target_soc - payload=target_soc

These three change between battery charge/discharge and auto (idle) mode:

  • topic/set/charge - payload=charge_rate
  • topic/set/discharge - payload=discharge_rate
  • topic/set/auto - payload=true

Service API

When True a Home Assistant service will be used to issue control messages for the inverter

For each service you wish to use it must be defined in apps.yaml.

There are two ways to define a service, the basic mode:

charge_start_service: my_service_name_charge

Will call my_service_name_charge for the charge start service.

Or the custom method:

charge_start_service:
   - service: my_charge_start_service
     device_id: {device_id}
     power: {power}
     soc: {target_soc}

Here you can define all the values passed to the service and use the default values from the template or define your own.

You can also call more than one service e.g:

charge_start_service:
   - service: my_charge_start_service
     device_id: {device_id}
     power: {power}
     soc: {target_soc}
   - service: switch.turn_off
     entity_id: switch.tsunami_charger

charge_start_service

Called to start a charge

The default options passed in are:

  • device_id - as defined in apps.yaml by device_id
  • target_soc - The SOC to charge to
  • power - The charge power to use

discharge_start_service

Called to start a discharge

The default options passed in are:

  • device_id - as defined in apps.yaml by device_id
  • target_soc - The SOC to discharge to
  • power - The discharge power to use

charge_stop_service

Called to stop a charge or stop a discharge

device_id - as defined in apps.yaml by device_id

discharge_stop_service

Called to stop a discharge

  • device_id - as defined in apps.yaml by device_id

output_charge_control

Set to power, current or none

When power the inverter has a charge_rate and discharge_rate setting in watts defined in apps.yaml

When current the inverter has timed_charge_current and timed_discharge_current setting in amps defined in apps.yaml

charge_control_immediate

When True the inverter timed_charge_current or timed_discharge_current is used to control charging or discharging as/when it starts and stops rather than using a timed method.

current_dp

Sets the number of decimal places when setting the current in Amps, should be 0 or 1

has_charge_enable_time

When True the inverter has a setting defined in apps.yaml called scheduled_charge_enable when can be used to enable/disable timed charging.

has_discharge_enable_time

When True the inverter has a setting defined in apps.yaml called scheduled_discharge_enable when can be used to enable/disable timed discharging.

has_target_soc

When True the inverter has a target soc setting in apps.yaml called charge_limit, when False charging must be turned on and off by Predbat rather than the inverter doing it based on the target %

has_reserve_soc

When True the inverter has a reserve soc setting in apps.yaml called reserve

has_timed_pause

When True the inverter has a setting in apps.yaml called pause_mode and settings pause_start_time and pause_end_time which can be used to pause the inverter from charging and discharging the battery - this is for GivEnergy systems only right now.

charge_time_format

When set to "HH:MM:SS" the inverter has:

charge_start_time charge_end_time discharge_start_time discharge_end_time

Which are option selectors in the format HH:MM:SS (e.g. 12:23:00) where seconds are always 00.

When set to "H M" the inverter has:

charge_start_hour charge_end_hour charge_start_minute charge_end_minute discharge_start_hour discharge_end_hour discharge_start_minute discharge_end_minute

Settings in apps.yaml which can be used to set the start and end times of charges and discharges

charge_time_entity_is_option

When True charge_start_time charge_end_time discharge_start_time and discharge_end_time are all Options, when false they are number values.

clock_time_format

Defines the time format of the inverter clock setting inverter_time in apps.yaml

soc_units

Defines the units of the SOC setting (currently not used)

time_button_press

When true the inverter has a button press which is needed to update the inverter registers from the Home Assistant values.

The apps.yaml setting charge_discharge_update_button is the entity name of the button that must be pressed and polled until it updates after each inverter register change.

support_charge_freeze

When True the inverter supports charge freeze modes

support_discharge_freeze

When True the inverter supports discharge freeze modes

has_ge_inverter_mode

When True the inverter as the GivEnergy inverter modes (ECO, Timed Export etc).

num_load_entities

Sets the number of load_power_n settings in apps.yaml are present in addition to load_power (the default)

write_and_poll_sleep

Sets the number of seconds between polls of inverter settings

has_idle_time

When True the inverter has an idle time register which must be set to the start and end times for ECO mode (GivEnergy EMC)

can_span_midnight

When True start and end times for charge and discharge can span midnight e.g. 23:00:00 - 01:00:00 is a 2 hour slot.

charge_discharge_with_rate

When True when charging discharge rate must be 0 and visa-versa. When false the rate does not have to change.