Goodwe export limiter together with HomeWizard P1

blueprint:
  name: GoodWe export-limiter naar doelwaarde met hysterese (P1 + HomeWizard)
  description: >
    Regelt de GoodWe exportlimiet zodat ~target W naar het net wordt teruggeleverd,
    met hysterese om fladderen te voorkomen. Werkt met HomeWizard P1 (netvermogen)
    en een GoodWe "number" entiteit voor exportlimiet (0–4200 W).
  domain: automation
  input:
    p1_power_entity:
      name: P1 netvermogen sensor
      description: Sensor met actueel netvermogen (W). Bij P1 is export meestal negatief.
      selector:
        entity:
          domain: sensor
    goodwe_limit_entity:
      name: GoodWe exportlimiet (number)
      description: Number-entiteit waarmee je de exportlimiet (W) zet.
      selector:
        entity:
          domain: number
    target_export_w:
      name: Doelwaarde export (W)
      default: 250
      selector:
        number:
          min: 0
          max: 6000
          step: 50
          unit_of_measurement: W
          mode: box
    hysteresis_w:
      name: Hysterese (±W)
      description: Pas de limiet pas aan als de afwijking groter is dan deze waarde.
      default: 100
      selector:
        number:
          min: 50
          max: 1000
          step: 10
          unit_of_measurement: W
          mode: box
    step_w:
      name: Stapgrootte (W)
      description: Grootte van elke aanpassing van de exportlimiet.
      default: 100
      selector:
        number:
          min: 20
          max: 1000
          step: 10
          unit_of_measurement: W
          mode: box
    min_limit_w:
      name: Minimum exportlimiet (W)
      default: 0
      selector:
        number:
          min: 0
          max: 4200
          step: 50
          unit_of_measurement: W
          mode: box
    max_limit_w:
      name: Maximum exportlimiet (W)
      default: 4200
      selector:
        number:
          min: 0
          max: 10000
          step: 50
          unit_of_measurement: W
          mode: box
    invert_p1_sign:
      name: P1-teken omkeren (export is negatief)
      description: Laat aan staan wanneer je P1 export negatief is (standaard bij HomeWizard P1).
      default: true
      selector:
        boolean: {}
    sample_seconds:
      name: Update-interval (seconden)
      default: 5
      selector:
        number:
          min: 5
          max: 120
          step: 5
          unit_of_measurement: s
          mode: slider
    enable_helper:
      name: (Optioneel) schakelaar om regeling te activeren
      default:
      selector:
        entity:
          domain: input_boolean
          multiple: false

mode: single
max_exceeded: silent

variables:
  p1_entity: !input p1_power_entity
  limit_entity: !input goodwe_limit_entity
  target_w: !input target_export_w
  hyst_w: !input hysteresis_w
  step_w: !input step_w
  min_w: !input min_limit_w
  max_w: !input max_limit_w
  invert: !input invert_p1_sign

  # Huidige metingen/staten
  p1_raw: "{{ states(p1_entity) | float(0) }}"
  # Maak export positief in W; import wordt 0
  export_now: >
    {% set v = (invert | iif(-1,1)) * p1_raw %}
    {{ [v, 0] | max }}
  limit_now: "{{ states(limit_entity) | float(0) }}"
  error_w: "{{ target_w - export_now }}"
  need_adjust: "{{ (error_w | abs) > hyst_w }}"
  direction: "{{ 1 if error_w > 0 else -1 }}"
  proposed_limit: >
    {% set adjust = [step_w, (error_w | abs)] | min * direction %}
    {{ (limit_now + adjust) | float }}
  clamped_limit: >
    {% if proposed_limit < min_w %} {{ min_w }}
    {% elif proposed_limit > max_w %} {{ max_w }}
    {% else %} {{ proposed_limit }}
    {% endif %}

trigger:
  - platform: time_pattern
    seconds: "/10"

condition:
  - condition: template
    value_template: "{{ states(p1_entity) not in ['unknown','unavailable','none'] }}"
  - condition: template
    value_template: "{{ states(limit_entity) not in ['unknown','unavailable','none'] }}"
  - condition: template
    value_template: >
      {% if not enable_helper %}
        true
      {% else %}
        {{ is_state(enable_helper, 'on') }}
      {% endif %}

action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ need_adjust }}"
        sequence:
          - service: number.set_value
            target:
              entity_id: "{{ limit_entity }}"
            data:
              value: "{{ clamped_limit }}"
    default: []

Hi,

My problem is that the goodwe inverter works with percentages on limit power.
Your program works only it goes always to 100%. Have you an example for changes to percentage value?

Regards Harry.

This one is working fine for mine 6kw Goodwe inverter:

blueprint:
  name: GoodWe export-limiter snel & stabiel (% uitgang)
  description: >
    Regelt GoodWe vermogenslimiet op basis van P1 export.
    Intern in Watt, uitgang in percentage.
    Proportionele regeling (snel bij groot verschil).
    Omhoog en omlaag zelfde snelheid.
    Zonder min/max list constructies.

  domain: automation

  input:
    p1_power_entity:
      name: P1 netvermogen sensor
      selector:
        entity:
          domain: sensor

    goodwe_limit_entity:
      name: GoodWe vermogenslimiet (percentage 0–100)
      selector:
        entity:
          domain: number

    inverter_max_w:
      name: Max omvormervermogen (W)
      default: 6000
      selector:
        number:
          min: 1000
          max: 20000
          step: 100

    target_export_w:
      name: Doelwaarde export (W)
      default: 100
      selector:
        number:
          min: 0
          max: 6000
          step: 50

    hysteresis_w:
      name: Hysterese (±W)
      default: 100
      selector:
        number:
          min: 10
          max: 1000
          step: 10

    min_step_w:
      name: Minimale stap (W)
      default: 60
      selector:
        number:
          min: 20
          max: 1000
          step: 10

mode: single

trigger:
  - platform: time_pattern
    seconds: "/3"

variables:
  p1_entity: !input p1_power_entity
  limit_entity: !input goodwe_limit_entity
  max_w: !input inverter_max_w
  target_w: !input target_export_w
  hyst_w: !input hysteresis_w
  min_step_w: !input min_step_w

  # Huidige waarden
  p1_raw: "{{ states(p1_entity) | float(0) }}"
  limit_percent_now: "{{ states(limit_entity) | float(0) }}"

  # Export positief maken (P1 is meestal negatief bij export)
  export_now: >
    {% set val = -1 * p1_raw %}
    {% if val > 0 %}
      {{ val }}
    {% else %}
      0
    {% endif %}

  # Huidige limiet in Watt
  limit_w_now: "{{ (limit_percent_now / 100 * max_w) | float(0) }}"

  # Regelverschil
  error_w: "{{ target_w - export_now }}"
  abs_error: "{{ error_w | abs }}"

  need_adjust: "{{ abs_error > hyst_w }}"

  direction: >
    {% if error_w > 0 %}
      1
    {% else %}
      -1
    {% endif %}

  # PROPORTIONELE stap (60% van fout, met minimum en maximum)
  dynamic_step: >
    {% set proportional = abs_error * 0.7 %}
    {% if proportional < min_step_w %}
      {{ min_step_w }}
    {% elif proportional > 2500 %}
      2500
    {% else %}
      {{ proportional }}
    {% endif %}

  # Nieuwe watt waarde
  adjusted_w: "{{ limit_w_now + (dynamic_step * direction) }}"

  # Begrenzen tussen 0 en max_w
  clamped_w: >
    {% if adjusted_w < 0 %}
      0
    {% elif adjusted_w > max_w %}
      {{ max_w }}
    {% else %}
      {{ adjusted_w }}
    {% endif %}

  # Omrekenen naar percentage
  new_percent: >
    {% set pct = (clamped_w / max_w * 100) %}
    {% if pct < 0 %}
      0
    {% elif pct > 100 %}
      100
    {% else %}
      {{ pct | round(1) }}
    {% endif %}

condition:
  - condition: template
    value_template: "{{ states(p1_entity) not in ['unknown','unavailable'] }}"
  - condition: template
    value_template: "{{ states(limit_entity) not in ['unknown','unavailable'] }}"

action:
  - if:
      - condition: template
        value_template: "{{ need_adjust }}"
    then:
      - service: number.set_value
        target:
          entity_id: !input goodwe_limit_entity
        data:
          value: "{{ new_percent | float }}

Hi all,

I'm using Home Assistant to dynamically update the grid_export_limit on my GoodWe inverter every 10-30 seconds (based on P1 meter data).

Does writing to the grid_export_limit entity via the standard integration (UDP/API) wear out the internal Flash memory (NVRAM)? I want to avoid bricking the inverter's storage by sending too many updates.

Thanks!

What if I have 2 inverters? And I have a p1 meter, but that has 2 values: Power Consumption and Power Production (default DSMR). Which sensor do I use?