Automating SolarEdge Power Limiting with Home Assistant

Since 2026, exporting solar power back to the grid in the Netherlands actually costs money. The old net metering scheme (“salderingsregeling”) is being phased out, and every kWh you push back comes with a fee. So instead of letting the inverter run at full blast and paying for the privilege, I set up Home Assistant to dynamically throttle my SolarEdge inverter to match household consumption.

The setup

  • Inverter: SolarEdge SE3000
  • Integration: SolarEdge Modbus Multi (HACS) — gives full Modbus TCP control over the inverter
  • Smart meter: DSMR integration via Electricity Meter entities
  • Home Assistant: running locally

The SolarEdge Modbus Multi integration exposes a number.solaredge_i1_site_limit entity (0–3000W) that controls how much the inverter is allowed to produce. Combined with the smart meter’s export reading, you have everything you need for a closed-loop controller.

Prerequisites

  1. Enable Modbus TCP on the inverter (port 1502, one-time setting in the SolarEdge commissioning interface)
  2. Install SolarEdge Modbus Multi from HACS
  3. Set control mode to Production Control via select.solaredge_i1_limit_control_mode

The automation — proportional controller

The core idea: check export every 2 minutes. If exporting too much, reduce the limit proportionally. If export is low, gently ramp back up. Leave a deadband in between where no action is taken.

automation:
  - id: solaredge_dynamic_power_limiting
    alias: "SolarEdge - Dynamic power limiting"
    description: >-
      Proportional controller that gradually adjusts the SolarEdge production
      limit to minimize export and maximize self-consumption. Uses a deadband
      (50-200W), proportional steps, and a 300W minimum to prevent oscillation.
    mode: single
    trigger:
      - trigger: time_pattern
        minutes: "/2"
    condition:
      - condition: numeric_state
        entity_id: sensor.solaredge_i1_ac_power
        above: 50
    action:
      - variables:
          current_power: >-
            {{ states('sensor.solaredge_i1_ac_power') | float(0) }}
          current_export_kw: >-
            {{ states('sensor.electricity_meter_energieproductie') | float(0) }}
          current_export: >-
            {{ current_export_kw * 1000 }}
          current_limit: >-
            {{ states('number.solaredge_i1_site_limit') | float(3000) }}
          headroom: >-
            {{ 3000 - current_limit }}
          new_limit: >-
            {% if current_export > 200 %}
              {{ [current_limit - ((current_export - 200) * 0.5) | round(0), 300] | max }}
            {% elif current_export < 50 %}
              {{ [current_limit + [headroom * 0.15, 100] | max, 3000] | min }}
            {% else %}
              {{ current_limit }}
            {% endif %}
          change: >-
            {{ (new_limit | float - current_limit | float) | abs }}
      - condition: template
        value_template: "{{ change | float > 50 }}"
      - service: number.set_value
        target:
          entity_id: number.solaredge_i1_site_limit
        data:
          value: "{{ new_limit | int }}"

How it works

The controller has three zones based on current grid export:

  • Export > 200W → ramp down by 50% of the excess above 200W (minimum result: 300W)
  • Export < 50W → ramp up by 15% of remaining headroom (minimum step: 100W, max: 500W)
  • 50–200W export → do nothing (deadband)

The 50W gate condition prevents tiny adjustments — changes smaller than 50W are ignored.

This is essentially a proportional controller. Instead of jumping to a calculated target, it nudges the limit in the right direction and lets the system converge over a few cycles. The deadband provides stability: 50–200W of export is “good enough” and not worth chasing.

Nighttime reset

A companion automation resets the limit to 3000W when the inverter goes to sleep, so it starts fresh the next morning:

  - id: solaredge_nighttime_reset
    alias: "SolarEdge - Nighttime limit reset"
    trigger:
      - trigger: state
        entity_id: sensor.solaredge_i1_status
        to: "I_STATUS_SLEEPING"
    condition:
      - condition: numeric_state
        entity_id: number.solaredge_i1_site_limit
        below: 3000
    action:
      - service: number.set_value
        target:
          entity_id: number.solaredge_i1_site_limit
        data:
          value: 3000

Tuning for your setup

These are the parameters you can adjust:

  • Deadband upper (200W): higher = more export tolerated, fewer adjustments. If you still have net metering, you could set this much higher
  • Deadband lower (50W): lower = more aggressive ramp-up after clouds pass
  • Ramp-down factor (0.5): lower = gentler reduction. Try 0.3 if you see any oscillation
  • Ramp-up factor (0.15): higher = faster recovery. Try 0.25 if production stays throttled too long
  • Floor (300W): minimum production limit — going too low can cause inverter instability
  • Interval (2 min): longer = more stable but slower response

What doesn’t work

I went through two simpler approaches before landing on the proportional controller:

Fixed threshold — throttle to a fixed wattage (e.g. 1800W) when export is high, restore to 3000W when it drops. Problem: if your household consumption is only 300W, even 1800W means 1500W of sustained export. And the toggle between two values oscillates in variable conditions.

Direct calculation — set the limit to current_consumption + margin every 30 seconds. Problem: the inverter needs time to stabilize after a Modbus write. Checking every 30 seconds means you are reacting to stale data, and the large jumps cause severe hunting. I saw 865 limit changes in a single day with this approach, with production dropping 65% compared to the day before.

The key insight is that this is a feedback control loop, and it needs to be treated as one: deadbands for stability, proportional corrections instead of jumps, and enough time between adjustments for the actuator to settle.

Adapting for different meters

Most guides assume a HomeWizard P1 meter that reports power in watts (negative = export). If you use DSMR like I do, the export sensor reports in kW as a positive value. The automation above is written for DSMR — if you use HomeWizard, adjust the current_export variable to use your sensor directly in watts without the * 1000 multiplier.

Also make sure you use the correct inverter max for headroom calculation and the ramp-up cap — it’s 3000W for the SE3000, but could be 3700W, 5000W, or higher for other models.

Key entities

Control:

  • select.solaredge_i1_limit_control_mode — must be Production Control
  • number.solaredge_i1_site_limit — the power cap in watts
  • button.solaredge_i1_commit_power_settings — writes changes to the inverter

Monitoring:

  • sensor.solaredge_i1_ac_power — current AC output (W)
  • sensor.electricity_meter_energieproductie — current grid export (kW)
  • sensor.electricity_meter_energieverbruik — current grid consumption (kW)