springfall2008 / batpred

Home battery prediction and charging automation for Home Assistant, supporting many inverter types
https://springfall2008.github.io/batpred/
115 stars 40 forks source link

Sunsynk Docs apps.yaml and automations #1331

Open tmh88 opened 1 month ago

tmh88 commented 1 month ago

Below is the code for the my app.yaml and automations used to integrate my Sunsynk 8.8Kw ECCO inverter, hopefully it helps others. Thanks to @springfall2008 for the code modifications along the way.

apps.yaml

---
pred_bat:
  module: predbat
  class: PredBat

  # Sets the prefix for all created entities in HA - only change if you want to run more than once instance
  prefix: predbat

  # Timezone to work in
  timezone: Europe/London

  # If you are using Predbat outside of HA then set the HA URL and Key (long lived access token here)
  #ha_url: 'http://homeassistant.local:8123'
  #ha_key: 'xxx'

  # Currency, symbol for main currency second symbol for 1/100s e.g. $ c or £ p or e c
  currency_symbols:
    - '£'
    - 'p'

  # Number of threads to use in plan calculation
  # Can be auto for automatic, 0 for off or values 1-N for a fixed number
  threads: auto

  # Sets the maximum period of zero load before the gap is filled, default 30 minutes
  # To disable set it to 1440
  load_filter_threshold: 30

  #
  # Sensors, more than one can be specified and they will be summed up automatically
  #
  # For two inverters the load today would normally be the master load sensor only (to cover the entire house)
  # If you have three phase and one inverter per phase then you would need three load sensors
  #
  # For pv_today if you have multiple solar inverter inputs then you should include one entry for each inverter
  #
  load_today:
    - sensor.sunsynk_load_power_daily_2 # load_power_daily_kWh
  import_today:
    - sensor.smart_meter_electricity_import_today # electric_import_daily_kWh
  export_today:
    - sensor.smart_meter_electricity_total_export_daily # electric_export_daily_kWh
  pv_today:
    - sensor.sunsynk_total_pv_power_daily

  # Load forecast can be used to add to the historical load data (heat-pump)
  # To link to Predheat
  # Data must be in the format of 'last_updated' timestamp and 'energy' for incrementing kWh
  #load_forecast:
  #  - predheat.heat_energy$external
  #
  # Controls/status - must by 1 per inverter
  #
  num_inverters: 1
  inverter_type: SK

  # **** Start of Outputs to Sunsynk Inverter ****

  charge_start_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode" # Inverter work mode
    option: "Limited to Home"

  charge_stop_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode" # Inverter work mode
    option: "Limited to Home"

  discharge_start_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode"  # Inverter work mode
    option: "Selling First"   

  timed_charge_current:
    - number.sunsynk_battery_max_charge_current # Inverter battery max charge setting in A

  timed_discharge_current:
    - number.sunsynk_battery_max_discharge_current # Inverter battery max discharge setting in A

  charge_limit:
    - number.sunsynk_set_soc_timezone1 # Inverter SOC time slot1
  # added to test need to add atuomation to copy to sunsynk timeslots

  # **** End of Outputs to Sunsynk Inverter **** 

  # Run balance inverters every N seconds (0=disabled) - only for multi-inverter
  balance_inverters_seconds: 0
  #

  # Custom sensors to get the BMS charge/discharge limit, based on inverter size (8000kW, BMS reported limit, and inverter set limit)
  inverter_limit_charge:
    - sensor.sunsynk_battery_max_charge_rate # {{ [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 }}

  inverter_limit_discharge:
    - sensor.sunsynk_battery_max_discharge_rate # {{ [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 }}

  # calculations to tell predbat the actual charge/discharge power of the inverter
  charge_rate:
    - sensor.sunsynk_charge_rate_calc # {{ [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 }}

  discharge_rate:
    - sensor.sunsynk_discharge_rate_calc # {{ [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 }}

  battery_rate_max:
    - 8000  # The maximum rate of the battery charge/discharge in watts **required to lift the 2600w default limit**

  battery_voltage:
    - sensor.sunsynk_battery_voltage

  battery_power:
    - sensor.sunsynk_battery_output_power #in watts

  pv_power:
    - sensor.sunsynk_total_solar #in watts

  load_power:
    - sensor.sunsynk_load_power #in watts

  soc_kw:
    - sensor.bcc_battery_soc_kwh #in kWh

  soc_max:
    - input_number.battery_cappacity #in kWh

  battery_min_soc:
    - sensor.sunsynk_battery_capacity_shutdown #in %

#  reserve:
#    - sensor.sunsynk_battery_capacity_shutdown #in % (belive this is disabled for Sunsynk)

#  inverter_mode:
#    - select.givtcp_{geserial}_mode
#  inverter_time:
#    - sensor.givtcp_{geserial}_invertor_time
#  charge_start_time:
#    - select.givtcp_{geserial}_charge_start_time_slot_1
#  charge_end_time:
#    - select.givtcp_{geserial}_charge_end_time_slot_1

#  scheduled_charge_enable:
#    - switch.givtcp_{geserial}_enable_charge_schedule
#  scheduled_discharge_enable:
#    - switch.givtcp_{geserial}_enable_discharge_schedule
#  discharge_start_time:
#    - select.givtcp_{geserial}_discharge_start_time_slot_1
#  discharge_end_time:
#    - select.givtcp_{geserial}_discharge_end_time_slot_1

  # Pause mode is not supported by all firmware's and will be ignored if not present
#  pause_mode:
#   - select.givtcp_{geserial}_battery_pause_mode

  # Not all firmwares support pause start/end time, delete these if not supported
  # to avoid spurious writes/warnings
#  pause_start_time:
#   - select.givtcp_{geserial}_battery_pause_start_time_slot
#  pause_end_time:
#   - select.givtcp_{geserial}_battery_pause_end_time_slot

  # Inverter max AC limit (one per inverter). E.g for a 3.6kw inverter set to 3600
  # If you have a second inverter for PV only please add the two values together
  inverter_limit:
    - 8000 # change to inveter size in W

  # Export limit is a software limit set on your inverter that prevents exporting above a given level
  # When enabled Predbat will model this limit
  #export_limit:
  # - 3600
  # - 3600

  # Some inverters don't turn off when the rate is set to 0, still charge or discharge at around 200w
  # The value can be set here in watts to model this (doesn't change operation)
  #inverter_battery_rate_min:
  #  - 200

  # Workaround to limit the maximum reserve setting, some inverters won't allow 100% to be set
  # Comment out if your inverter allows 100%
#  inverter_reserve_max : 98

  # Some batteries tail off their charge rate at high soc%
  # enter the charging curve here as a % of the max charge rate for each soc percentage.
  # the default is 1.0 (full power)
  # The example below is from GE 9.5kwh battery with latest firmware and gen1 inverter
  #
  # Predbat can compute this curve automatically if you have enough data, restart the add-on and look in the logfile for the data
  # once set here Predbat will no longer re-compute the curve.
  # Can also be set to 'auto' to just use the calculation curve, not recommended if you are using low power charging mode.
  #battery_charge_power_curve:
  #  91 : 0.91
  #  92 : 0.81
  #  93 : 0.71
  #  94 : 0.62
  #  95 : 0.52
  #  96 : 0.43
  #  97 : 0.33
  #  98 : 0.24
  #  99 : 0.24
  #  100 : 0.24
  #battery_discharge_power_curve:
  #  4 : 1.0

  # Inverter clock skew in minutes, e.g. 1 means it's 1 minute fast and -1 is 1 minute slow
  # Separate start and end options are applied to the start and end time windows, mostly as you want to start late (not early) and finish early (not late)
  # Separate discharge skew for discharge windows only
  inverter_clock_skew_start: 0
  inverter_clock_skew_end: 0
  inverter_clock_skew_discharge_start: 0
  inverter_clock_skew_discharge_end: 0

  # Clock skew adjusts the Appdaemon time
  # This is the time that Predbat takes actions like starting discharge/charging
  # Only use this for workarounds if your inverter time is correct but Predbat is somehow wrong (AppDaemon issue)
  # 1 means add 1 minute to AppDaemon time, -1 takes it away
  clock_skew: 0

  # Solcast cloud interface, set this or the local interface below
  #solcast_host: 'https://api.solcast.com.au/'
  #solcast_api_key: 'xxxx'
  #solcast_poll_hours: 8

  # Set these to match solcast sensor names if not using the cloud interface
  # The regular expression (re:) makes the solcast bit optional
  # If these don't match find your own names in Home Assistant
  pv_forecast_today: re:(sensor.(solcast_|)(pv_forecast_|)forecast_today)
  pv_forecast_tomorrow: re:(sensor.(solcast_|)(pv_forecast_|)forecast_tomorrow)
  pv_forecast_d3: re:(sensor.(solcast_|)(pv_forecast_|)forecast_(day_3|d3))
  pv_forecast_d4: re:(sensor.(solcast_|)(pv_forecast_|)forecast_(day_4|d4))

  # car_charging_energy defines an incrementing sensor which measures the charge added to your car
  # is used for car_charging_hold feature to filter out car charging from the previous load data
  # Automatically set to detect Wallbox and Zappi, if it doesn't match manually enter your sensor name
  # Also adjust car_charging_energy_scale if it's not in kwH to fix the units
#  car_charging_energy: 're:(sensor.myenergi_zappi_[0-9a-z]+_charge_added_session|sensor.wallbox_portal_added_energy)'

  # Defines the number of cars modelled by the system, set to 0 for no car
  num_cars: 0

  # car_charging_planned is set to a sensor which when positive indicates the car will charged in the upcoming low rate slots
  # This should not be needed if you use Intelligent Octopus slots which will take priority if enabled
  # The list of possible values is in car_charging_planned_response
  # Auto matches Zappi and Wallbox, or change it for your own
  # One entry per car
#  car_charging_planned:
#    - 're:(sensor.wallbox_portal_status_description|sensor.myenergi_zappi_[0-9a-z]+_plug_status)'

#  car_charging_planned_response:
#    - 'yes'
#    - 'on'
#    - 'true'
#    - 'connected'
#    - 'ev connected'
#    - 'charging'
#    - 'paused'
#    - 'waiting for car demand'
#    - 'waiting for ev'
#    - 'scheduled'
#    - 'enabled'
#    - 'latched'
#    - 'locked'
#    - 'plugged in'

  # In some cases car planning is difficult (e.g. Ohme with Intelligent doesn't report slots)
  # The car charging now can be set to a sensor to indicate the car is charging and to plan
  # for it to charge during this 30 minute slot
  #car_charging_now:
  #  - off

  # Positive responses for car_charging_now
#  car_charging_now_response:
#    - 'yes'
#    - 'on'
#    - 'true'

  # To make planned car charging more accurate, either using car_charging_planned or the Octopus Energy plugin,
  # specify your battery size in kwh, charge limit % and current car battery soc % sensors/values.
  # If you have Intelligent Octopus the battery size and limit will be extracted from the Octopus Energy plugin directly.
  # Set the car SOC% if you have it to give an accurate forecast of the cars battery levels.
  # One entry per car if you have multiple cars.
  #car_charging_battery_size:
  #  - 75
  #car_charging_limit:
  #  - 're:number.tsunami_charge_limit'
  #car_charging_soc:
  #  - 're:sensor.tsunami_battery'

  # One per car, when true only one car can charge at once, when False multiple cars can charge at once
  #car_charging_exclusive:
  #  - True

  # If you have Octopus intelligent, enable the intelligent slot information to add to pricing
  # Will automatically disable if not found, or comment out to disable fully
  # When enabled it overrides the 'car_charging_planned' feature and predict the car charging based on the intelligent plan (unless octopus intelligent charging is False)
  # This matches either the intelligent slot from the Octopus Plugin or from the Intelligent plugin
  #octopus_intelligent_slot: 're:(binary_sensor.octopus_energy([0-9a-z_]+|)_intelligent_dispatching)'
  #octopus_ready_time: 're:(time.octopus_energy([0-9a-z_]+|)_intelligent_ready_time)'
  #octopus_charge_limit: 're:(number.octopus_energy([0-9a-z_]+|)_intelligent_charge_limit)'
  # Example alternative configuration for Ohme integration release >=v0.6.1
  #octopus_intelligent_slot: 'binary_sensor.ohme_slot_active'
  #octopus_ready_time: 'time.ohme_target_time'
  #octopus_charge_limit: 'number.ohme_target_percent'

  # Carbon Intensity data from National grid
  carbon_intensity: 're:(sensor.carbon_intensity_uk)'

  # Octopus saving session points to the saving session Sensor in the Octopus plugin, when enabled saving sessions will be at the assumed
  # Rate is read automatically from the add-in and converted to pence using the conversion rate below (default is 8)
  octopus_saving_session: 're:(binary_sensor.octopus_energy([0-9a-z_]+|)_saving_session(s|))'
  octopus_saving_session_octopoints_per_penny: 8

  # Energy rates
  # Please set one of these three, if multiple are set then Octopus is used first, second rates_import/rates_export and latest basic metric

  # Set import and export entity to point to the Octopus Energy plugin import and export sensors
  # automatically matches your meter number assuming you have only one (no need to edit the below)
  # Will be ignored if you don't have the sensor but will error if you do have one and it's incorrect
  # NOTE: To get detailed energy rates you need to go in and manually enable the following events in HA
  #       event.octopus_energy_electricity_xxxxxxxx_previous_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_current_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_next_day_rates
  # and if you have export enable:
  #       event.octopus_energy_electricity_xxxxxxxx_export_previous_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_export_current_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_export_next_day_rates
  # Predbat will automatically find the event. entities from the link below to the sensors
  metric_octopus_import: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_current_rate)'
  metric_octopus_export: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_export_current_rate)'

  # Standing charge in pounds, can be set to a sensor or manually entered (e.g. 0.50 is 50p)
  # The default below will pick up the standing charge from the Octopus Plugin
  # The standing charge only impacts the cost graphs and doesn't change the way Predbat plans
  # If you don't want to show the standing charge then just delete this line or set to zero
  metric_standing_charge: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_current_standing_charge)'

  # Or set your actual rates across time for import and export
  # If start/end is missing it's assumed to be a fixed rate
  # Gaps are filled with zero rate
  #rates_import:
  #  -  start: "00:30:00"
  #     end: "04:30:00"
  #     rate: 7.5
  #  -  start: "04:30:00"
  #     end: "00:30:00"
  #     rate: 40.0
  #
  #rates_export:
  #  -  rate: 4.2

  # Can be used instead of the plugin to get import rates directly online
  # Overrides metric_octopus_import and rates_import
  # rates_import_octopus_url : "https://api.octopus.energy/v1/products/FLUX-IMPORT-23-02-14/electricity-tariffs/E-1R-FLUX-IMPORT-23-02-14-A/standard-unit-rates"
  # rates_import_octopus_url : "https://api.octopus.energy/v1/products/AGILE-FLEX-BB-23-02-08/electricity-tariffs/E-1R-AGILE-FLEX-BB-23-02-08-A/standard-unit-rates"

  # Overrides metric_octopus_export and rates_export
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/FLUX-EXPORT-BB-23-02-14/electricity-tariffs/E-1R-FLUX-EXPORT-BB-23-02-14-A/standard-unit-rates"
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/AGILE-OUTGOING-BB-23-02-28/electricity-tariffs/E-1R-AGILE-OUTGOING-BB-23-02-28-A/standard-unit-rates/"
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/OUTGOING-FIX-12M-BB-23-02-09/electricity-tariffs/E-1R-OUTGOING-FIX-12M-BB-23-02-09-A/standard-unit-rates/"

  # Import rates can be overridden with rate_import_override
  # Export rates can be overridden with rate_export_override
  # Use the same format as above, but a date can be included if it just applies for a set day (e.g. Octopus power ups)
  # This will override even the Octopus plugin rates if enabled
  #
  #rates_import_override:
  # -  date: '2023-09-10'
  #    start: '14:00:00'
  #    end: '14:30:00'
  #    rate: 112
  #    load_scaling: 0.8

  # For pv estimate, leave blank for central estimate, or add 10 for 10% curve (worst case) or 90 or 90% curve (best case)
  # If you use 10 then disable pv_metric10_weight below
  # pv_estimate: 10

  # Days previous is the number of days back to find historical load data
  # Recommended is 7 to capture day of the week but 1 can also be used
  # if you have more history you could use 7 and 14 (in a list) but the standard data in HA only lasts 10 days
  days_previous:
    - 7
    - 14

  # Days previous weight can be used to control the weighting of the previous load points, the values are multiplied by their
  # weights and then divided through by the total weight. E.g. if you used 1 and 0.5 then the first value would have 2/3rd of the weight and the second 1/3rd
  # Include one value for each days_previous value, each weighting on a separate line.
  # If any days_previous's that are not given a weighting they will assume a default weighting of 1.
  days_previous_weight:
    - 1

  # Number of hours forward to forecast, best left as-is unless you have specific reason
  forecast_hours: 48

  # Specify the devices that notifies are sent to, the default is 'notify' which goes to all
  #notify_devices:
  #  - mobile_app_treforsiphone12_2

  # Battery scaling makes the battery smaller (e.g. 0.9) or bigger than its reported
  # If you have an 80% DoD battery that falsely reports it's kwh then set it to 0.8 to report the real figures
  # One per inverter
  battery_scaling:
    - 1.0

  # Can be used to scale import and export data, used for workarounds
  import_export_scaling: 1.0

  # Export triggers:
  # For each trigger give a name, the minutes of export needed and the energy required in that time
  # Multiple triggers can be set at once so in total you could use too much energy if all run
  # Creates an entity called 'binary_sensor.predbat_export_trigger_<name>' which will be turned On when the condition is valid
  # connect this to your automation to start whatever you want to trigger
  export_triggers:
    - name: 'large'
      minutes: 60
      energy: 1.0
    - name: 'small'
      minutes: 15
      energy: 0.25

  # If you have a sensor that gives the energy consumed by your solar diverter then add it here
  # this will make the predictions more accurate. It should be an incrementing sensor, it can reset at midnight or not
  # It's assumed to be in Kwh but scaling can be applied if need be
  #iboost_energy_today: 'sensor.xxxxx'
  #iboost_energy_scaling: 1.0
  # Gas rates for comparison
  #metric_octopus_gas: 're:(sensor.(octopus_energy_|)gas_[0-9a-z]+_[0-9a-z]+_current_rate)'

  # Nordpool market energy rates
  #futurerate_url: 'https://www.nordpoolgroup.com/api/marketdata/page/325?currency=GBP'
  #futurerate_adjust_import: True
  #futurerate_adjust_export: False
  #futurerate_peak_start: "16:00:00"
  #futurerate_peak_end: "19:00:00"
  #futurerate_peak_premium_import: 14
  #futurerate_peak_premium_export: 6.5

  # Watch list, a list of sensors to watch for changes and then update the plan if they change
  # This is useful for things like the Octopus Intelligent Slot sensor so that the plan update as soon as you plugin in
  # Only uncomment the items you actually have set up above in apps.yaml, of course you can add your own as well
  # Note those using +[] are lists that are appended to this list, whereas {} items are single items only
  #watch_list:
  #  - '{octopus_intelligent_slot}'
  #  - '{octopus_ready_time}'
  #  - '{octopus_charge_limit}'
  #  - '{octopus_saving_session}'
  #  - '+[car_charging_planned]'
  #  - '+[car_charging_soc]'
  #  - '{car_charging_now}'

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

PredBat - Copy Charge Limit

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

Value Templates for charge/discharge calculations

Change the 8000 to your inverter size in W

Sunsynk Battery Max Charge Rate

{{ [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

{{ [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

{{ [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

{{ [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 }}
Meatballs1 commented 3 weeks ago

What are the test values e.g. input_number.test_sunsynk_battery_max_charge_current ?

I currently have the following templates (slightly different naming for the BMS reported limitation):

Max Charge Rate: {{ [5000,[states('number.sunsynk_battery_max_charge_current')|int,states('sensor.sunsynk_battery_charge_bms_limit_current')|int]|min * states('sensor.sunsynk_battery_voltage')|float]|min }}
Max Discharge Rate: {{ [5000,[states('number.sunsynk_battery_max_discharge_current')|int, states('sensor.sunsynk_battery_discharge_bms_limit_current')|int]|min * states('sensor.sunsynk_battery_voltage')|float]|min }}

But not sure what the Sunsynk Charge Rate Calc refers to - are the input numbers just helpers to manually restrict it?

Meatballs1 commented 3 weeks ago

Ah I think I see, the charge_rate/discharge_rate should be the actual power the inverter can handle, the inverter_limit_charge could just be an input number to apply a limit.

tmh88 commented 3 weeks ago

Ah I think I see, the charge_rate/discharge_rate should be the actual power the inverter can handle, the inverter_limit_charge could just be an input number to apply a limit.

I think you are correct, I’ve made an error in my config. I was testing before allowing it to adjust the inverter.

tmh88 commented 3 weeks ago

Below is the code for the my app.yaml and automations used to integrate my Sunsynk 8.8Kw ECCO inverter, hopefully it helps others. Thanks to @springfall2008 for the code modifications along the way.

apps.yaml

---
pred_bat:
  module: predbat
  class: PredBat

  # Sets the prefix for all created entities in HA - only change if you want to run more than once instance
  prefix: predbat

  # Timezone to work in
  timezone: Europe/London

  # If you are using Predbat outside of HA then set the HA URL and Key (long lived access token here)
  #ha_url: 'http://homeassistant.local:8123'
  #ha_key: 'xxx'

  # Currency, symbol for main currency second symbol for 1/100s e.g. $ c or £ p or e c
  currency_symbols:
    - '£'
    - 'p'

  # Number of threads to use in plan calculation
  # Can be auto for automatic, 0 for off or values 1-N for a fixed number
  threads: auto

  # Sets the maximum period of zero load before the gap is filled, default 30 minutes
  # To disable set it to 1440
  load_filter_threshold: 30

  #
  # Sensors, more than one can be specified and they will be summed up automatically
  #
  # For two inverters the load today would normally be the master load sensor only (to cover the entire house)
  # If you have three phase and one inverter per phase then you would need three load sensors
  #
  # For pv_today if you have multiple solar inverter inputs then you should include one entry for each inverter
  #
  load_today:
    - sensor.sunsynk_load_power_daily_2 # load_power_daily_kWh
  import_today:
    - sensor.smart_meter_electricity_import_today # electric_import_daily_kWh
  export_today:
    - sensor.smart_meter_electricity_total_export_daily # electric_export_daily_kWh
  pv_today:
    - sensor.sunsynk_total_pv_power_daily

  # Load forecast can be used to add to the historical load data (heat-pump)
  # To link to Predheat
  # Data must be in the format of 'last_updated' timestamp and 'energy' for incrementing kWh
  #load_forecast:
  #  - predheat.heat_energy$external
  #
  # Controls/status - must by 1 per inverter
  #
  num_inverters: 1
  inverter_type: SK

  # **** Start of Outputs to Sunsynk Inverter ****

  charge_start_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode" # Inverter work mode
    option: "Limited to Home"

  charge_stop_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode" # Inverter work mode
    option: "Limited to Home"

  discharge_start_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode"  # Inverter work mode
    option: "Selling First"   

  discharge_stop_service:
    service: select.select_option
    entity_id: "select.sunsynk_work_mode" # Inverter work mode
    option: "Limited to Home"
  timed_charge_current:
    - number.sunsynk_battery_max_charge_current # Inverter battery max charge setting in A

  timed_discharge_current:
    - number.sunsynk_battery_max_discharge_current # Inverter battery max discharge setting in A

  charge_limit:
    - number.sunsynk_set_soc_timezone1 # Inverter SOC time slot1
  # added to test need to add atuomation to copy to sunsynk timeslots

  # **** End of Outputs to Sunsynk Inverter **** 

  # Run balance inverters every N seconds (0=disabled) - only for multi-inverter
  balance_inverters_seconds: 0
  #

  # Custom sensors to get the BMS charge/discharge limit, based on inverter size (8000kW, BMS reported limit, and inverter set limit)
  inverter_limit_charge:
    - sensor.sunsynk_battery_max_charge_rate # {{ [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 }}

  inverter_limit_discharge:
    - sensor.sunsynk_battery_max_discharge_rate # {{ [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 }}

  # calculations to tell predbat the actual charge/discharge power of the inverter
  charge_rate:
    - sensor.sunsynk_charge_rate_calc # {{ [8000,[states('number.sunsynk_battery_max_charge_current')|int,states('sensor.sunsynk_battery_charge_limit_current')|int]|min * states('sensor.sunsynk_battery_voltage')|float]|min }}

  discharge_rate:
    - sensor.sunsynk_discharge_rate_calc # {{ [8000,[states('number.sunsynk_battery_max_discharge_current')|int,states('sensor.sunsynk_battery_discharge_limit_current')|int]|min * states('sensor.sunsynk_battery_voltage')|float]|min }}

  battery_rate_max:
    - 8000  # The maximum rate of the battery charge/discharge in watts **required to lift the 2600w default limit**

  battery_voltage:
    - sensor.sunsynk_battery_voltage

  battery_power:
    - sensor.sunsynk_battery_output_power #in watts

  pv_power:
    - sensor.sunsynk_total_solar #in watts

  load_power:
    - sensor.sunsynk_load_power #in watts

  soc_kw:
    - sensor.bcc_battery_soc_kwh #in kWh

  soc_max:
    - input_number.battery_cappacity #in kWh

  battery_min_soc:
    - sensor.sunsynk_battery_capacity_shutdown #in %

#  reserve:
#    - sensor.sunsynk_battery_capacity_shutdown #in % (belive this is disabled for Sunsynk)

#  inverter_mode:
#    - select.givtcp_{geserial}_mode
#  inverter_time:
#    - sensor.givtcp_{geserial}_invertor_time
#  charge_start_time:
#    - select.givtcp_{geserial}_charge_start_time_slot_1
#  charge_end_time:
#    - select.givtcp_{geserial}_charge_end_time_slot_1

#  scheduled_charge_enable:
#    - switch.givtcp_{geserial}_enable_charge_schedule
#  scheduled_discharge_enable:
#    - switch.givtcp_{geserial}_enable_discharge_schedule
#  discharge_start_time:
#    - select.givtcp_{geserial}_discharge_start_time_slot_1
#  discharge_end_time:
#    - select.givtcp_{geserial}_discharge_end_time_slot_1

  # Pause mode is not supported by all firmware's and will be ignored if not present
#  pause_mode:
#   - select.givtcp_{geserial}_battery_pause_mode

  # Not all firmwares support pause start/end time, delete these if not supported
  # to avoid spurious writes/warnings
#  pause_start_time:
#   - select.givtcp_{geserial}_battery_pause_start_time_slot
#  pause_end_time:
#   - select.givtcp_{geserial}_battery_pause_end_time_slot

  # Inverter max AC limit (one per inverter). E.g for a 3.6kw inverter set to 3600
  # If you have a second inverter for PV only please add the two values together
  inverter_limit:
    - 8000 # change to inveter size in W

  # Export limit is a software limit set on your inverter that prevents exporting above a given level
  # When enabled Predbat will model this limit
  #export_limit:
  # - 3600
  # - 3600

  # Some inverters don't turn off when the rate is set to 0, still charge or discharge at around 200w
  # The value can be set here in watts to model this (doesn't change operation)
  #inverter_battery_rate_min:
  #  - 200

  # Workaround to limit the maximum reserve setting, some inverters won't allow 100% to be set
  # Comment out if your inverter allows 100%
#  inverter_reserve_max : 98

  # Some batteries tail off their charge rate at high soc%
  # enter the charging curve here as a % of the max charge rate for each soc percentage.
  # the default is 1.0 (full power)
  # The example below is from GE 9.5kwh battery with latest firmware and gen1 inverter
  #
  # Predbat can compute this curve automatically if you have enough data, restart the add-on and look in the logfile for the data
  # once set here Predbat will no longer re-compute the curve.
  # Can also be set to 'auto' to just use the calculation curve, not recommended if you are using low power charging mode.
  #battery_charge_power_curve:
  #  91 : 0.91
  #  92 : 0.81
  #  93 : 0.71
  #  94 : 0.62
  #  95 : 0.52
  #  96 : 0.43
  #  97 : 0.33
  #  98 : 0.24
  #  99 : 0.24
  #  100 : 0.24
  #battery_discharge_power_curve:
  #  4 : 1.0

  # Inverter clock skew in minutes, e.g. 1 means it's 1 minute fast and -1 is 1 minute slow
  # Separate start and end options are applied to the start and end time windows, mostly as you want to start late (not early) and finish early (not late)
  # Separate discharge skew for discharge windows only
  inverter_clock_skew_start: 0
  inverter_clock_skew_end: 0
  inverter_clock_skew_discharge_start: 0
  inverter_clock_skew_discharge_end: 0

  # Clock skew adjusts the Appdaemon time
  # This is the time that Predbat takes actions like starting discharge/charging
  # Only use this for workarounds if your inverter time is correct but Predbat is somehow wrong (AppDaemon issue)
  # 1 means add 1 minute to AppDaemon time, -1 takes it away
  clock_skew: 0

  # Solcast cloud interface, set this or the local interface below
  #solcast_host: 'https://api.solcast.com.au/'
  #solcast_api_key: 'xxxx'
  #solcast_poll_hours: 8

  # Set these to match solcast sensor names if not using the cloud interface
  # The regular expression (re:) makes the solcast bit optional
  # If these don't match find your own names in Home Assistant
  pv_forecast_today: re:(sensor.(solcast_|)(pv_forecast_|)forecast_today)
  pv_forecast_tomorrow: re:(sensor.(solcast_|)(pv_forecast_|)forecast_tomorrow)
  pv_forecast_d3: re:(sensor.(solcast_|)(pv_forecast_|)forecast_(day_3|d3))
  pv_forecast_d4: re:(sensor.(solcast_|)(pv_forecast_|)forecast_(day_4|d4))

  # car_charging_energy defines an incrementing sensor which measures the charge added to your car
  # is used for car_charging_hold feature to filter out car charging from the previous load data
  # Automatically set to detect Wallbox and Zappi, if it doesn't match manually enter your sensor name
  # Also adjust car_charging_energy_scale if it's not in kwH to fix the units
#  car_charging_energy: 're:(sensor.myenergi_zappi_[0-9a-z]+_charge_added_session|sensor.wallbox_portal_added_energy)'

  # Defines the number of cars modelled by the system, set to 0 for no car
  num_cars: 0

  # car_charging_planned is set to a sensor which when positive indicates the car will charged in the upcoming low rate slots
  # This should not be needed if you use Intelligent Octopus slots which will take priority if enabled
  # The list of possible values is in car_charging_planned_response
  # Auto matches Zappi and Wallbox, or change it for your own
  # One entry per car
#  car_charging_planned:
#    - 're:(sensor.wallbox_portal_status_description|sensor.myenergi_zappi_[0-9a-z]+_plug_status)'

#  car_charging_planned_response:
#    - 'yes'
#    - 'on'
#    - 'true'
#    - 'connected'
#    - 'ev connected'
#    - 'charging'
#    - 'paused'
#    - 'waiting for car demand'
#    - 'waiting for ev'
#    - 'scheduled'
#    - 'enabled'
#    - 'latched'
#    - 'locked'
#    - 'plugged in'

  # In some cases car planning is difficult (e.g. Ohme with Intelligent doesn't report slots)
  # The car charging now can be set to a sensor to indicate the car is charging and to plan
  # for it to charge during this 30 minute slot
  #car_charging_now:
  #  - off

  # Positive responses for car_charging_now
#  car_charging_now_response:
#    - 'yes'
#    - 'on'
#    - 'true'

  # To make planned car charging more accurate, either using car_charging_planned or the Octopus Energy plugin,
  # specify your battery size in kwh, charge limit % and current car battery soc % sensors/values.
  # If you have Intelligent Octopus the battery size and limit will be extracted from the Octopus Energy plugin directly.
  # Set the car SOC% if you have it to give an accurate forecast of the cars battery levels.
  # One entry per car if you have multiple cars.
  #car_charging_battery_size:
  #  - 75
  #car_charging_limit:
  #  - 're:number.tsunami_charge_limit'
  #car_charging_soc:
  #  - 're:sensor.tsunami_battery'

  # One per car, when true only one car can charge at once, when False multiple cars can charge at once
  #car_charging_exclusive:
  #  - True

  # If you have Octopus intelligent, enable the intelligent slot information to add to pricing
  # Will automatically disable if not found, or comment out to disable fully
  # When enabled it overrides the 'car_charging_planned' feature and predict the car charging based on the intelligent plan (unless octopus intelligent charging is False)
  # This matches either the intelligent slot from the Octopus Plugin or from the Intelligent plugin
  #octopus_intelligent_slot: 're:(binary_sensor.octopus_energy([0-9a-z_]+|)_intelligent_dispatching)'
  #octopus_ready_time: 're:(time.octopus_energy([0-9a-z_]+|)_intelligent_ready_time)'
  #octopus_charge_limit: 're:(number.octopus_energy([0-9a-z_]+|)_intelligent_charge_limit)'
  # Example alternative configuration for Ohme integration release >=v0.6.1
  #octopus_intelligent_slot: 'binary_sensor.ohme_slot_active'
  #octopus_ready_time: 'time.ohme_target_time'
  #octopus_charge_limit: 'number.ohme_target_percent'

  # Carbon Intensity data from National grid
  carbon_intensity: 're:(sensor.carbon_intensity_uk)'

  # Octopus saving session points to the saving session Sensor in the Octopus plugin, when enabled saving sessions will be at the assumed
  # Rate is read automatically from the add-in and converted to pence using the conversion rate below (default is 8)
  octopus_saving_session: 're:(binary_sensor.octopus_energy([0-9a-z_]+|)_saving_session(s|))'
  octopus_saving_session_octopoints_per_penny: 8

  # Energy rates
  # Please set one of these three, if multiple are set then Octopus is used first, second rates_import/rates_export and latest basic metric

  # Set import and export entity to point to the Octopus Energy plugin import and export sensors
  # automatically matches your meter number assuming you have only one (no need to edit the below)
  # Will be ignored if you don't have the sensor but will error if you do have one and it's incorrect
  # NOTE: To get detailed energy rates you need to go in and manually enable the following events in HA
  #       event.octopus_energy_electricity_xxxxxxxx_previous_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_current_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_next_day_rates
  # and if you have export enable:
  #       event.octopus_energy_electricity_xxxxxxxx_export_previous_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_export_current_day_rates
  #       event.octopus_energy_electricity_xxxxxxxx_export_next_day_rates
  # Predbat will automatically find the event. entities from the link below to the sensors
  metric_octopus_import: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_current_rate)'
  metric_octopus_export: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_export_current_rate)'

  # Standing charge in pounds, can be set to a sensor or manually entered (e.g. 0.50 is 50p)
  # The default below will pick up the standing charge from the Octopus Plugin
  # The standing charge only impacts the cost graphs and doesn't change the way Predbat plans
  # If you don't want to show the standing charge then just delete this line or set to zero
  metric_standing_charge: 're:(sensor.(octopus_energy_|)electricity_[0-9a-z]+_[0-9a-z]+_current_standing_charge)'

  # Or set your actual rates across time for import and export
  # If start/end is missing it's assumed to be a fixed rate
  # Gaps are filled with zero rate
  #rates_import:
  #  -  start: "00:30:00"
  #     end: "04:30:00"
  #     rate: 7.5
  #  -  start: "04:30:00"
  #     end: "00:30:00"
  #     rate: 40.0
  #
  #rates_export:
  #  -  rate: 4.2

  # Can be used instead of the plugin to get import rates directly online
  # Overrides metric_octopus_import and rates_import
  # rates_import_octopus_url : "https://api.octopus.energy/v1/products/FLUX-IMPORT-23-02-14/electricity-tariffs/E-1R-FLUX-IMPORT-23-02-14-A/standard-unit-rates"
  # rates_import_octopus_url : "https://api.octopus.energy/v1/products/AGILE-FLEX-BB-23-02-08/electricity-tariffs/E-1R-AGILE-FLEX-BB-23-02-08-A/standard-unit-rates"

  # Overrides metric_octopus_export and rates_export
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/FLUX-EXPORT-BB-23-02-14/electricity-tariffs/E-1R-FLUX-EXPORT-BB-23-02-14-A/standard-unit-rates"
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/AGILE-OUTGOING-BB-23-02-28/electricity-tariffs/E-1R-AGILE-OUTGOING-BB-23-02-28-A/standard-unit-rates/"
  # rates_export_octopus_url: "https://api.octopus.energy/v1/products/OUTGOING-FIX-12M-BB-23-02-09/electricity-tariffs/E-1R-OUTGOING-FIX-12M-BB-23-02-09-A/standard-unit-rates/"

  # Import rates can be overridden with rate_import_override
  # Export rates can be overridden with rate_export_override
  # Use the same format as above, but a date can be included if it just applies for a set day (e.g. Octopus power ups)
  # This will override even the Octopus plugin rates if enabled
  #
  #rates_import_override:
  # -  date: '2023-09-10'
  #    start: '14:00:00'
  #    end: '14:30:00'
  #    rate: 112
  #    load_scaling: 0.8

  # For pv estimate, leave blank for central estimate, or add 10 for 10% curve (worst case) or 90 or 90% curve (best case)
  # If you use 10 then disable pv_metric10_weight below
  # pv_estimate: 10

  # Days previous is the number of days back to find historical load data
  # Recommended is 7 to capture day of the week but 1 can also be used
  # if you have more history you could use 7 and 14 (in a list) but the standard data in HA only lasts 10 days
  days_previous:
    - 7
    - 14

  # Days previous weight can be used to control the weighting of the previous load points, the values are multiplied by their
  # weights and then divided through by the total weight. E.g. if you used 1 and 0.5 then the first value would have 2/3rd of the weight and the second 1/3rd
  # Include one value for each days_previous value, each weighting on a separate line.
  # If any days_previous's that are not given a weighting they will assume a default weighting of 1.
  days_previous_weight:
    - 1

  # Number of hours forward to forecast, best left as-is unless you have specific reason
  forecast_hours: 48

  # Specify the devices that notifies are sent to, the default is 'notify' which goes to all
  #notify_devices:
  #  - mobile_app_treforsiphone12_2

  # Battery scaling makes the battery smaller (e.g. 0.9) or bigger than its reported
  # If you have an 80% DoD battery that falsely reports it's kwh then set it to 0.8 to report the real figures
  # One per inverter
  battery_scaling:
    - 1.0

  # Can be used to scale import and export data, used for workarounds
  import_export_scaling: 1.0

  # Export triggers:
  # For each trigger give a name, the minutes of export needed and the energy required in that time
  # Multiple triggers can be set at once so in total you could use too much energy if all run
  # Creates an entity called 'binary_sensor.predbat_export_trigger_<name>' which will be turned On when the condition is valid
  # connect this to your automation to start whatever you want to trigger
  export_triggers:
    - name: 'large'
      minutes: 60
      energy: 1.0
    - name: 'small'
      minutes: 15
      energy: 0.25

  # If you have a sensor that gives the energy consumed by your solar diverter then add it here
  # this will make the predictions more accurate. It should be an incrementing sensor, it can reset at midnight or not
  # It's assumed to be in Kwh but scaling can be applied if need be
  #iboost_energy_today: 'sensor.xxxxx'
  #iboost_energy_scaling: 1.0
  # Gas rates for comparison
  #metric_octopus_gas: 're:(sensor.(octopus_energy_|)gas_[0-9a-z]+_[0-9a-z]+_current_rate)'

  # Nordpool market energy rates
  #futurerate_url: 'https://www.nordpoolgroup.com/api/marketdata/page/325?currency=GBP'
  #futurerate_adjust_import: True
  #futurerate_adjust_export: False
  #futurerate_peak_start: "16:00:00"
  #futurerate_peak_end: "19:00:00"
  #futurerate_peak_premium_import: 14
  #futurerate_peak_premium_export: 6.5

  # Watch list, a list of sensors to watch for changes and then update the plan if they change
  # This is useful for things like the Octopus Intelligent Slot sensor so that the plan update as soon as you plugin in
  # Only uncomment the items you actually have set up above in apps.yaml, of course you can add your own as well
  # Note those using +[] are lists that are appended to this list, whereas {} items are single items only
  #watch_list:
  #  - '{octopus_intelligent_slot}'
  #  - '{octopus_ready_time}'
  #  - '{octopus_charge_limit}'
  #  - '{octopus_saving_session}'
  #  - '+[car_charging_planned]'
  #  - '+[car_charging_soc]'
  #  - '{car_charging_now}'

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

PredBat - Copy Charge Limit

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

Value Templates for charge/discharge calculations

Change the 8000 to your inverter size in W

Sunsynk Battery Max Charge Rate (Sets Charge Limit)

input_number.sunsynk_battery_max_charge_current_limit = Setpoint in HA to set the charge limit in A

{{ [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 (Sets Discharge Limit)

input_number.sunsynk_battery_max_discharge_current_limit = Setpoint in HA to set the discharge limit in A

{{ [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 (Feedback to Pedbat of actual Charge Limit)

{{ [8000,[states('number.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 (Feedback to Pedbat of actual Discharge Limit)

{{ [8000,[states('number.sunsynk_battery_max_discharge_current')|int,states('sensor.sunsynk_battery_discharge_limit_current')|int]|min * states('sensor.sunsynk_battery_voltage')|float]|min }}
tmh88 commented 3 weeks ago

@springfall2008 have I interpreted this correctly? in the apps.yaml inverter_limit_charge: & inverter_limit_discharge: are inputs to predbat to limit the charge and discharge power to the batteries

charge_rate: & discharge_rate: are inputs to predbat to tell predbat the actual charge/discharge power of the inverter

springfall2008 commented 2 weeks ago

Inverter limit charge/discharge are inputs that defined the maximum rate to set

charge_rate/discharge_rate are controls, Predbat can read them to find the current rate and write them to change the rate

Meatballs1 commented 1 week ago

Inverter limit charge/discharge are inputs that defined the maximum rate to set

charge_rate/discharge_rate are controls, Predbat can read them to find the current rate and write them to change the rate

I think charge_rate is ignored because ooutput_charge_control is set to current for SK?

We have the number.sunsynk_battery_max_charge_current etc which are used in the timed_charge_current/timed_discharge_current settings.

Meatballs1 commented 16 hours ago

I had some issues with:

Resetting charging SOC as we are not within the window or charge is disabled and inverter_soc_reset is enabled (now 09-14 21:05:00 target set_soc_minutes 30 charge start time 09-14 23:30:00)

It kept putting my Timezone SOC back up to 100%, which was causing Idle to fail to cover the load. Disabled it in expert mode and will see how I go.