[FEMS] Auto per Wallbox nicht aus Speicher laden

Ja, der Vorschlag mit der Notstromreserve ist gut, hat aber auch andere Nachteile. Mir gefällt die Idee, der Wallbox bzw Fenecon via Home Assistant die richtigen Setpoints zu schicken, aber noch besser.

Und genau so verstehe ich diese Community hier: Wir verbessern für uns die Situation, diskutieren Lösungsideen und tauschen uns zur Situation aus. Offene Schnittstellen sind einer der USPs von Fenecon. Ist doch super, wenn wir das System genau so nutzen, wie gedacht.

Ich verstehe null, was hier “hergezogen”, “verdreht” und unkorrekt sein soll.

Zusätzlich habe ich oben die Nachteile des aktuellen Verhaltens beschrieben. Mehrere User oben hatten zum Ausdruck gebracht, dass Fenecon das Thema derzeit nicht für dringend hält. Das ist ein von mir absolut respektierter Standpunkt. Aber es ist doch wohl fair, auf die Nachteile hinzuweisen, um ggf ein höheres Backlog Ranking hinzuwirken.

2 Likes

Wie gesagt, die Mehrzahl der Kunden sehen das nicht als schwäche und sind auch total zufrieden. Mich hat es genug gestört das ich nach einer Lösung gesucht habe. Diese läuft jetzt einwandfrei seit Wochen ohne Probleme, daher ist das Thema erst einmal vom Tisch. Habe meine Implementation geteilt für diejenigen die selbst etwas Smart Home affin sind und es nachbauen wollen. Ich teile meine Informationen gerne, dann hat jeder etwas davon.

Jedoch ist beim Call mit dem Support direkt ein echter Bug nachvollziehbar gewesen: Bei Abschaltung eines hohen Verbrauchers (Durchlauferhitzer) schaltet das System sofort die Wallbox ein, weil kurzzeitig ein Überschuss (die vorher genutzten 20kW von Erhitzer) ins Netz gespeist wird. Eigentlich sollte das nicht mehr auftreten, da eine Hysterie eingebaut wurde. Konnten wir nur leider bei meiner Installation nicht bestätigen. Taucht auch mit dem letzen Update noch auf.

@Sn0w3y : das war bisher mein Vorgehen. Leider erlaubt die schreibende REST API kein setzen der Batteriereserve. Vermutlich weil es hier keine timeouts gibt und es sich um eine Systemeinstellung handelt. Ich wollte dies auf keinen Fall manuell machen, genau deswegen habe ich ja die Wallbox Lösung von FENECON überhaupt gekauft. Mit meiner Lösung bin ich zufrieden und es wäre ein schönes Feature im Base Code. Ich habe auch schon im OpenEMS Code geschaut doch bin ich leider überhaupt kein Java Programmierer. Für ein wenig Debuggen für das o.g. Problem hat es gereicht aber selber etwas bauen trau ich mir nicht zu. Und selbst wenn ich an den Code gehen würde habe ich keine Möglichkeit diesen einfach mal auf meiner Hardware zu testen um das Verhalten im Live Betrieb nachvollziehen zu können. Als Kunde bleibt mir nur der Support und der Wille von FENECON die Produkte zu verbessern :slightly_smiling_face:

Edit: und noch kurz ein positives Feedback: auch wenn es wie „meckern“ klingt bin ich mit dem Produkt super zufrieden! Es läuft einfach … und das FENECON mit seiner Software ein komplettes Open Source Projekt gestartet hat verdient Hochachtung. So stelle ich mir die Energiewende vor, jeder kann mitmachen.

1 Like

@TheSerapher: Ich wollte das heute wie besprochen umsetzen. Dabei fiel mir auf: Ignorierst du mit deiner Automatisierung nicht fälschlicherweise den Verbrauch des Hauses? In deinem Vorschlag lädst du die Batterie mit der Solarproduktion. Wenn in deinem Haus gleichzeitig Verbraucher mit 3 kW aktiv sind, ziehst du diese 3 kW aus dem Netz. Richtig?

Wäre die korrekte Formel daher nicht eher:
ChargeMinPower = ProductionActivePower - ConsumptionActivePower + ChargePower

Meine Automatisierung setzt keine Ladeleistung der Wallbox sondern ich setze einfach die nutzbare Leistung des ESS Systems auf die derzeit vorhandene Solarleistung. Damit wird die Batterie nicht als Energiequelle genutzt sondern nur die Solaranlage. Wo der Strom hingeht ist dem ESS in dem Moment egal. Es definiert nur die maximale Ausgangsleistung aller Systeme im ESS (Solar und Batterie in meinem Fall).

Der REST Endpoint dafür ist http://<FEMS_IP>/rest/channel/ess0/SetActivePowerEquals, es hat eine weile gedauert bis ich verstanden habe wie die Settings hier interpretiert werden.

Ich hoffe das beantwortet deine Frage, bin mir nicht 100% sicher es richtig verstanden zu haben. Ich habe nicht ganz Verstanden wo diese ChargeMinPower herkommen :slight_smile:

Edit: Auf den Trichter mit “setz Leistung auf Solar-Produktion” bin ich nur gekommen, weil ich /rest/channel/ess0/DebugSetActivePower ausgelesen habe und Festellen konnte, das FEMS diesen Wert bei Solarproduktion auch kontinuierlich genau auf den Verbrauch stellt. Habe das einfach übernommen und die Automatisierung erzwingt den Wert der Solarproduktion, damit er die tatsächlich benötigte Leistung ignoriert.

Okay, verstanden. Aber auch wenn es die kombinierte Ladeleistung des Speichersystems ist, so stellt sich doch das dassselbe Problem, oder nicht?

Mein Gedanke:
Wenn das Speichersystem (egal ob Wallbox oder integrierter Speicher) mit exakt der Solarproduktion lädt, das Haus aber 50% der Produktion verbraucht, dann kommen 50% der Speicherleistung aus dem Netz.

Die Hausspeicher wird nur geladen wenn von der Solarproduktion genug Überschuss vorhanden ist (ausser man stellt eine Mindestladung als Backupspeicher an). Meine Solarvorgabe bedeutet das der Solarstrom an alle Verbraucher (Haus und Wallbox) geschickt wird und der Rest aus dem Netz verfügbar gemacht wird. Der Hausspeicher bekommt dann keinen Strom, da kein Überschuss verfügbar ist.

Edit: Und hier noch ein detail: Ein positiver Wert im ESS bedeutet Stromabgabe vom ESS and die Verbraucher, ein negativer Wert Aufladeleistung des ESS (also den Speicher). Vielleicht kommt daher die Verwirrung :slight_smile: Da ich einen positiven Wert einstelle (Produktion von Solar) ist das die maximale Abgabemenge - sollten keine Verbraucher angeschlossen sein würde diese Leistung auch ins Netz gespeist werden!

Du stellst die aktuelle Solarproduktion als Sollwert für die Entladung des Speichers ein?

Reden wir noch über das Szenario, dass die Wallbox nicht aus dem Speicher geladen werden soll? Ich verstehe gerade nicht mehr, wie die obige Logik das Problem löst…

Ich will hier auch keine endlose Diskussion führen (private Messages gibts im Forum leider nicht). Ich kann auch einfach akzeptieren, dass ich dir nicht folgen kann. Passt scho. :slight_smile:

ESS ist nicht nur der Speicher, da ist auch das Solarsystem dabei! Wenn ich dem ESS sage, setze deine Ausgangsleistung auf Solarstrom liefert das System nur den Solarstrom an alle Verbraucher. Im normalen Betrieb schaut FEMS auf den Netzstromzähler und setzt den Wert im ESS auf den Netzstrombezug. Entweder der Solarstrom reicht aus (und eventuell kann der Speicher noch geladen werden) oder es wird Solarstrom PLUS Speicher genutzt, um den Netzstrombezug auf 0 auszupegeln.

Ich musste tatsächlich mein Post noch einmal durchlesen, da es eine Weile her ist, wo ich das Thema angefasst habe. Kann verstehen, wenn das etwas schwer nachvollziehbar ist.

Und weil ich im Post vergessen hatte die Automation zu Posten, nachdem ich eine funktionierende Version hatte, hier die YAML. Habe das Timing auf alle 5 Sekunden gesetzt, da HA ein Loop Limit hat. Mit 5 Sekunden sollte man dieses nicht erreichen :slight_smile:

alias: "Cron: Check Wallbox Charger"
description: >-
  Checks if the Wallbox charger is active and sets battery discharge limit to
  actual solar production via rest_command
triggers:
  - trigger: state
    entity_id:
      - sensor.battery_inverter_fems_evcs0_chargestate
    from: Not charging
conditions:
  - condition: template
    value_template: >-
      {{ not is_state('sensor.battery_inverter_fems_evcs0_chargestate', 'Not
      charging') }}
actions:
  - repeat:
      sequence:
        - delay:
            hours: 0
            minutes: 0
            seconds: 5
            milliseconds: 0
          enabled: true
        - action: rest_command.fenecon_battery_power
          metadata: {}
          data:
            power: "{{ states('sensor.battery_inverter_fems_sum_productionactivepower') | int(0) }}"
          alias: Set battery power to solar production
          enabled: true
      while:
        - condition: template
          value_template: >-
            {{ not is_state('sensor.battery_inverter_fems_evcs0_chargestate',
            'Not charging') }}
mode: single
2 Likes

Hallo alle,

habe mal versucht einen Controller zu erstellen, welcher dem oben genannten Anforderungen gerecht wird.

Hier der Code der Implementierung. Bitte schaut Mal drüber und gebt mir feedback ob ich das richtig mache.

Habe noch keine Zeit gehabt es zu testen sollte aber bald dazukommen.

@Designate(ocd = Config.class, factory = true)
@Component(
    name = "ess.optimizedevcs",
    immediate = true,
    configurationPolicy = ConfigurationPolicy.REQUIRE
)
public class ControllerOptimizeEssEvcsImpl extends AbstractOpenemsComponent implements ControllerOptimizeEssEvcs, Controller, OpenemsComponent {

    private Config config = null;

    @Reference
    private OpenemsComponent gridMeter;

    @Reference
    private OpenemsComponent ess;

    @Reference
    private OpenemsComponent evcs;

    private static final int HYSTERESE = 100; // Mindeständerung in Watt
    private static final int MAX_CHANGE_RATE = 500; // Maximal 500 W Änderung pro Zyklus

    private double Kp = 0.3;  // Proportionalfaktor
    private double Ki = 0.01; // Integrationsfaktor
    private double Kd = 0.05; // Differenzialfaktor
    private double lastError = 0;
    private double integral = 0;
    private int lastSetPower = 0; // Letzte Batterieleistung

    public ControllerOptimizeEssEvcsImpl() {
        super(OpenemsComponent.ChannelId.values(), Controller.ChannelId.values(), ControllerOptimizeEssEvcs.ChannelId.values());
    }

    @Activate
    private void activate(ComponentContext context, Config config) {
        super.activate(context, config.id(), config.alias(), config.enabled());
        this.config = config;
    }

    @Deactivate
    protected void deactivate() {
        super.deactivate();
    }

    @Override
    public void run() throws OpenemsNamedException {
        try {
            int gridPower = gridMeter.channel("ActivePower").value().asInt();
            int evcsPower = evcs.channel("ActivePower").value().asInt();
            int pvPower = ess.channel("ProductionPower").value().asInt();
            int loadPower = gridPower + pvPower;

            if (evcsPower <= 0) {
                log.info("EVCS nicht aktiv → ESS regelt selbst und setzt Modus zurück.");
                ess.channel("ControlMode").setValue("internal");
                return;
            }
            
            ess.channel("ControlMode").setValue("smart");

            int targetPower = pvPower - (loadPower - evcsPower);

            double error = targetPower - lastSetPower;
            integral += error;
            double derivative = error - lastError;
            double pidOutput = (Kp * error) + (Ki * integral) + (Kd * derivative);
            lastError = error;

            int newSetPower = lastSetPower + (int) pidOutput;
            if (Math.abs(newSetPower - lastSetPower) > MAX_CHANGE_RATE) {
                newSetPower = lastSetPower + (newSetPower > lastSetPower ? MAX_CHANGE_RATE : -MAX_CHANGE_RATE);
            }

            if (Math.abs(newSetPower - lastSetPower) > HYSTERESE) {
                ess.channel("SetActivePower").setValue(newSetPower);
                lastSetPower = newSetPower;
                log.info("Batterie-Leistung angepasst: " + newSetPower + " W");
            }
        } catch (Exception e) {
            log.error("Fehler in ControllerOptimizeEssEvcsImpl: " + e.getMessage());
        }
    }
}

Kann ich damit weitermachen oder habe ich die Implementierung von Controllern falsch verstanden?

Beste Grüße
Beton

Hallo,

hast du ein Repo auf GitHub, in dem man sich das mal anschauen kann?

So wirds ein wenig schwer :smiley:

Grüße !

Hallo,

wenn ich beim Git einen PULL Request aufmache, wird dann ein neuer Branch erstellt?
Bin leider nicht der größte Held auf git. Wäre super wenn du dir dann ansehen könntest was ich hier gebaut habe.

Beste Grüße
Beton

Hallo,

du musst zuerst OpenEMS forken und dann deinen Fork bearbeiten :slight_smile:

Grüße !

Guten Abend,

habe das mit dem Fork umgesetzt. Habe hier das Repo mit einem Test branch, wo der controller im ersten commit drin ist.

Vielleicht hast du Mal Zeit und schaust drüber. Ist für mich Mal ein Konzept, wie ich mir die Funktion vorstelle. Werde die Tage weitermachen. Je nachdem wie oft ich dazu komme.

Bin schon auf ein Problem gestoßen. Wo bekomme ich bzw. von welchem component bekomme ich den PV output? ESS?

Edit:
Weil alle anderen Werte sind für mich klar. Ess → charge/discharge Meter → load und evcs → ev-charge.

Edit2:
Wie muss ich eigentlich die Werte der Componenten abfragen? Mit dieser Channelabfrage wo der channel angegeben wird oder gibt es immer Get und Set Methode?

Beste Grüße
Beton

Guten Tag,

habe den controller nun fertig gebaut → er lässt sich nun starten. Muss leider erst nachschehen ob die Werte die ich für die Berechnung verwende, überhaupt die richtigen Werte sind. Werde das aber ausgiebig testen.

Frage: Wenn ich mit diesem controller nur die ActivePower des Ess anpasse, muss ich überhaupt einen PID Regler im Controller einbauen? Wird das Ess nicht sowieso, von dem PID, welcher immer aktiv ist geregelt?

Beste Grüße
Beton

Hallo,

habe wieder etwas mehr gelernt. Wenn ich einfach den Controller ess.balancing anpasse wird die benötigt Funktion abgedeckt. Bin ich gerade am testen scheint aber zuverlässig zu funktionieren. Man könnte dies dann entweder in einen eigenen Controller geben, oder eben den balancing anpassen. Hier der veränderte Code falls es jemand benötigt:

protected static int calculateRequiredPower(int essPower, int gridPower, int targetGridSetpoint, int evcsPower) {
		
		if(evcsPower > 0) {
			return (gridPower-evcsPower) + essPower - targetGridSetpoint;
		}
			return gridPower + essPower - targetGridSetpoint;	
	}

edit1:

oder mann fügt in dieser Zeile folgendes hinzu:

this.ess.setActivePowerEqualsWithPid(calculatedPower-this.evcs.getActivePower().getOrError());

Beste Grüße
Beton

Hallo,

habe mich wieder etwas mit dem Thema aus diesem Thread gespielt. Bin dann beim balancing controller auf die Idee gekommen als “targetgridsetpoint” einfach die EVCS-Activepower zu verwenden. So sollte das ESS nie den Speicher für die Beladung des EV verwenden.

Beste Grüße
Beton

Guten Morgen.

Der Pid-Regler fürs ESS ist im ESS-Power Controller drinnen. Da kannst den deaktivieren, bzw die Werte für P, I, D einstellen.

LG Daniel

Es geht hier überhaupt nicht um diese Werte :slight_smile:

Servus,

habe es geschafft bei einem Nachbar zu testen. Wenn ich den “balancing” Controller verwenden und den Gridpoint auf evcs power einstelle wird die Leistung der Batterie nur für die Last des Hauses und nicht für die Ladung des EV verwendet.

Beste Grüße
Beton