[Modul BETA] Hoymiles Modulwechselrichter mit OpenDTU

Laut OpenDTU-Doku können mit den Standard-Builds bis zu 10 Wechselrichter betrieben werden. Ob so viele tatsächlich funktionieren, kann ich nicht sagen. Aber selbst wenn nicht, könnte man bei den Kosten und dem geringen Aufwand auch problemlos eine weitere OpenDTU daneben hängen.

Hallo, nach dem Update der Firmware geht es wieder Fehlerfrei.
DIe DTU verliert nicht die Verbindung zu IPS.
LG Willi

@hirschbrat Mir ist aufgefallen, dass du im Modul zwar das Basic-Topic konfigurierbar implementiert hast, das Status-Topic der OpenDTU ist jedoch hardcoded, obwohl man dieses unter LMT-Topic in der openDTU ebenfalls ändern kann. Keine Ahnung, ob das jemand macht, könnte aber eine mögliche Fehlerquelle sein.

Weiß jemand, wie das mit dem Online-Status genau funktioniert? Eigentlich reagiert das Modul ja nur, wenn über den MQTT-Server neue Daten reinkommen. Wenn man die OpenDTU stromlos macht oder diese abraucht, dürfte sie ja eigentlich keinen Offline-Status mehr senden können. Irgendwie scheint es aber wohl doch zu klappen.

Ich frage, weil ich die OpenDTU gerne überwachen möchte und mir nicht sicher bin, ob die Statusvariable dafür geeignet ist oder ich besser die Konnektivität auf IP-Ebene prüfe.

Gruß
Slummi

Der LWT-Parameter nutzt - wie der Name sagt - das „Last Will an Testament“ von MQTT. Wenn der MQTT-Server merkt, dass der Client nicht mehr aktiv ist (vmtl. weil keep-alive Meldungen ausbleiben), setzt der MQTT-Server den Wert aus dem LWT.
Du kannst dies auch ausprobieren, indem du die DTU mal ausschaltest. Nach einer gewissen Zeit, wird dann auch der DTU Status in Symcon auf offline gesetzt - eben weil der MQTT-Server dies erledigt.

Ich bin auch ein Horst. :man_facepalming:t3:
Irgendwie habe ich LWT nicht mit „Last Will and Testament“ in Verbindung gebracht. Dann ist klar, warum es funktioniert und sollte halbwegs zuverlässig sein. Danke!

Das gilt nicht nur für das Topic, sondern auch für den Offline-Wert. Auch dieser kann vom User in der OpenDTU frei konfiguriert werden, womit das Modul den Status nicht mehr korrekt erkennen würde.

Es hat zwei Gründe, warum ich dies nicht im Modul konfigurierbar gemacht habe:

  1. Wenn jemand nicht weiß, was er tut und diese Werte in OpenDTU ändert, wird er die Änderungen wahrscheinlich nicht auch im Modul vornehmen - also würde es so oder so zu Fehlern führen.
  2. Es gibt ja derzeit keine OpenDTU Instanz, sondern nur Microinverter-Instanzen im Modul. Daher müssten dann diese Einstellungen auch wieder in jeder Microinverter-Instanz (wenn mehrere WR an einer DTU hängen) einzeln vorgenommen werden, was wieder zu Inkonsistenten Einstellungen führen kann.

Ich plane zwar auch eine OpenDTU Instanz fürs Modul (um auch besser den Status zu kontrollieren und die DTU ggf. über http neu starten zu können), aber auch dort würde ich aus den o.g. Gründen ungern diese Werte auch einstellbar machen. Mir ist auch nicht klar, warum in OpenDTU gerade diese MQTT-Topics änderbar sind und mir fällt auch gerade kein Anwendungsfall ein, warum man diese Werte ändern sollte.
Aber du hast recht: Es bleibt natürlich weiterhin eine Fehlerquelle - aber diese bleibt auch weiter bestehen bzw. vergrößert sich, wenn man die Einstellungen zusätzlich im Modul ändern kann.

Ah cool, wollte ich auch schon angesprochen haben. Gerade wenn man mehrere Wechselrichter an einer DTU hat, will man vielleicht lieber einmal zentral die Infos dazu haben, statt mehrfach unter jedem Wechselrichter. Und vielleicht interessiert den ein oder anderen ja auch die IP-Adresse, RSSI etc.

So ganz erschließt sich mir das auch nicht. Ich kann deine Gründe auch nachvollziehen. Theoretisch könnte man das LMT-Topic sogar automatisch ermitteln, da man ja die Namen der enthaltenen Attribute kennt. Wenn man Daten von der DTU empfängt, wüsste man sogar die Bezeichnung des Online-Status und könnte alles andere als offline interpretieren, also im Prinzip genau invertiert zur aktuellen Implementierung. Dann bräuchte man im Modul gar nichts konfigurieren, und die Fehlerquelle wäre aus meiner Sicht beseitigt. Ist aber nur so eine Idee und es war mir nur aufgefallen, dass es da eine mögliche „Schwachstelle“ gibt. Wenn du es so lässt, passt es für mich auch.

Gruß
Slummi

Kannst du mir das nochmal genauer erklären? Ich glaube nicht das das geht. Es sind doch sowohl das Topic, als auch die Werte für das LWT in OpenDTU frei konfigurierbar. Welche Namen von enthaltenen Attributen meinst du?

Habe gerade mal in der Doku der neuen WebAPI nachgesehen. Dort kann man sich auch die MQTT Konfiguration inkl. LWT holen. Das wäre der korrekte Weg für eine OpenDTU Instanz. Diese Instanz würde ohnehin nicht mehr nur ausschließlich über MQTT kommunizieren, sondern auch über HTTP (z.B. um bei fehlerhafter MQTT-Verbindung einen Reconnect zu bewirken)

Das wäre natürlich der ideale Weg.

Meine Überlegung war folgende:

In der DTU legst du das Basis-Topic fest, welches du auch in der Instanz angibst.
Zusätzlich gibst du das LWT-Topic an, welches unterhalb des Basis-Topics liegt, dass du ja durch die Konfiguration kennst. Und du gibst die Werte für LWT-Online und LWT-Offline an.

Du filterst nun in der Instanz auf das Basis-Topic. Das machst du ja eh schon.
Du weißt, dass es unter dem Basis-Topic (numerische) Topics je Wechselrichter gibt, die über die Seriennummern identifiziert werden und du kennst deren enthaltenen Werte.
Außerdem weißt du, dass es unter dem Basis-Topic irgendein Topic gibt, welches die DTU-Daten enthält. Da du weißt, dass dieses Topic die Werte hostname, ip, rssi und uptime enthält, müsste das, was du nicht zuordnen kannst das LWT-Topic sein.

Wenn du gerade Daten von der DTU empfängst, weißt du, dass sie online ist und kennst daher den LWT-Online-Wert. Den LWT-Offline-Wert kennst du nicht, musst du aber auch nicht, wenn du einfach alle LWT-Werte ungleich dem Online-Wert als offline interpretierst.

Das einzige, was ich nicht bedacht habe ist, dass du das LWT-Topic zwar konfigurieren kannst, das Topic für die restlichen Status-Werte (ip, rssi etc.) aber scheinbar hardcoded dtu ist. Ich hatte angenommen, dass dieses immer vom LWT-Topic abhängt, was aber scheinbar nur in der Standardkonfiguration der Fall ist.

Theoretisch müsste man das Topic per Ausschlussverfahren zwar trotzdem raus kriegen, aber schön ist das natürlich nicht und der Weg über die Web-API ist der deutlich bessere. Im Idealfall gibt es dann eine Splitterinstanz, die einmal die Daten der DTU enthält und in den Wechselrichter-Instanzen, die an der DTU hängen, braucht dann gar kein Topic mehr konfiguriert werden, weil der Splitter es kennt.

Danke für die Erläuterung, hab ich verstanden. Das Ausschlußprinzip würde voraussetzen, dass im Modul immer eine aktuelle Liste mit allen verfügbaren Topics hinterlegt wäre - wird bei OpenDTU eines hinzugefügt (durch Firmwareupdate) müsste es auch direkt ein Modul-Update geben.

Ich hatte auch schon überlegt die OpenDTU Instanz als Splitter zu implementieren. Allerdings würde dies die Komplexität des Moduls stark erhöhen und wegen des Datenflusses durch mehrere Splitter hintereinander ( ist das überhaupt möglich/zulässig? der MQTT-Server ist ja auch schon ein Splitter) sicher auch die Performance mindern. Bin da noch nicht sicher, ob man sich dadurch nicht mehr Probleme einhandelt…

Also funktionieren tut das prinzipiell. Habe ich auch schon mal gebaut. Da habe ich mich mit einem eigenen Splitter an eine Cutter-Instanz gehängt, die auch ein Splitter ist.

Aber klar, hat alles so seine Vor- und Nachteile. Waren auch einfach nur so ein paar Ideen, die mir gekommen sind, weil die DTU ja schon eine übergeordnete Funktion (wie ein Splitter) hat und verschiedene Geräte (Wechselrichter) daran hängen können.

Aber das Modul ist auch so super und funktioniert sehr gut. Vielen Dank dafür! :slightly_smiling_face:

Es gibt nun eine neue Version im BETA-Kanal:
Version 1.2.0 (2023-04-02)

Neu: OpenDTU Splitter Instanz

  • Statusvariablen der OpenDTU (Hostname, IP, RSSI, Uptime, Status)
  • Reboot() startet OpenDTU neu (über WebAPI)
  • ReconnectMQTT() versucht eine MQTT-Verbindung wiederherzustellen (über WebAPI)
  • Schalter für automatischen Reconnect bei MQTT-Verbindungsproblemen
  • Datenfluss (wird automatisch angepasst): MQTT-Server <-> OpenDTU (Splitter) <-> Microinverter (Device)

Wer von der BETA wieder zurück auf die STABLE wechselt, muss anschließend die Microinverter-Instanzen manuell wieder an den MQTT-Server hängen und DANACH die OpenDTU-Instanz löschen

1 „Gefällt mir“

Oh cool, probiere ich nach Ostern mal aus. Bin die Woche leider unterwegs.

Sind die bestehenden Geräte-Instanzen vollständig kompatibel zur alten Version? Also kann ich den Wechsel in beide Richtungen durchführen, ohne dass irgendwelche Bestandsvariablen des Wechselrichters dabei kaputt gehen?

Ja, die Variablen und Einstellungen der Geräte-Instanzen sind kompatibel und bleiben beim Wechsel in beide Richtungen erhalten.

Hallo hirschbrat,

kann man ungefähr sagen wann BETA zu STABLE wird?

Danke und lg

Ich warte jetzt erstmal Rückmeldungen ab, ob es damit Probleme gibt oder auch ob alles funktioniert. Wenn alles läuft, würd ich die Änderungen vlt. so in einem Monat auf den Stable Kanal ziehen.

Ok, werds dann abwarten. DANKE!!!

Ich habe es jetzt Dank eines KNX Smartmeters (enertex) und dem Modul hier geschafft eine echte Nulleinspeisung zu schaffen!! DANKE

Hier das Skript:

<?php

$timestamp = time();
$uhrzeit = date("H:i:s", $timestamp);
$datum = date("d.m.Y", $timestamp);
// + 30000000 = 1 Jahr
// + 15720000 = 6 Monate
// + 7776000 = 3 Monate
// + 2592000 = 1 Monat
// + 604800 = 1 Woche
// + 86400 = 1 Tag
// - 1000 = Nie
$merkzeit = 3000;
$IDname = $_IPS['SELF'];
$text1 = "</b>(".$IDname.")<b> Energiemanagement Nulleinspeisung PV Werkstatt 1 </b>";

// Script zur Sicherstellung der Nulleinspeisung, Ereignis muß freigegeben sein  !!!
// **************************************************************************************

// Verbrauch auslesen
$verbrauch_aktuell = GetValue(49846);
$verbrauch_aktuell = round($verbrauch_aktuell, 0);
// aktuelles Limit auslesen
$pv_limit_aktuell = GetValue(17638); 
// Erzeugung auslesen
$erzeugung_aktuell = GetValue(24227);
$erzeugung_aktuell = round($erzeugung_aktuell, 0);
// Einspeise Offset
$hysterese = 30;
// Minumum
$pv_level = 400; // Minumum

if ($verbrauch_aktuell > $hysterese)
{
    // zu viel Verbrauch - Limit erhöhen
    // Limit: 400, Erzeugung/Verbrauch = 500 -> Neues Limit 400 + 500 - hysterese = 850;

    $verbrauch_aktuell = abs($verbrauch_aktuell);

    // Berechnung neues Limit
    $pv_limit_neu = $erzeugung_aktuell + ($verbrauch_aktuell - $hysterese);

    if ($pv_limit_neu > 1500)
    {
        $pv_limit_neu = 1500;
    }

    if ($pv_limit_neu != $pv_limit_aktuell)
    {
        RequestAction(17638, $pv_limit_neu);
    }

    // Meldungseintrag
    $text = "</b>".$datum." ".$uhrzeit."</b> ".$text1." Limitänderung auf ".$pv_limit_neu." W [Limit alt: ".$pv_limit_aktuell." W, Verbrauch: ".$verbrauch_aktuell." W, Erzeugung: ".$erzeugung_aktuell." W]";
    $number = IPS_RunScriptWaitEx(25368, array('action' => 'add', 'text' => $text, 'expires' => time() + $merkzeit, 'removable' => true, 'type' => '3'));  
    // - 'type' (optional): Art der Meldung ... 0 => Normal(grün), 1 => Fehler(rot), 2 => Warnung(gelb), 3 => Status(blau), 4 => Status(orange) 

}
else
{
    // zu viel Erzeugung - Limit verringern
    // Limit: 700, Erzeugung/Verbrauch = -300 -> Neues Limit 700 + (-300) - hysterese = 350;

    // Berechnung neues Limit
    $pv_limit_neu = $erzeugung_aktuell + ($verbrauch_aktuell - $hysterese);

    if ($pv_limit_neu != $pv_limit_aktuell)
    {
        RequestAction(17638, $pv_limit_neu);
    }

    // Meldungseintrag
    $text = "</b>".$datum." ".$uhrzeit."</b> ".$text1." Limitänderung auf ".$pv_limit_neu." W [Limit alt: ".$pv_limit_aktuell." W, Verbrauch/Erzeugung: ".$verbrauch_aktuell." W, Erzeugung: ".$erzeugung_aktuell." W]";
    $number = IPS_RunScriptWaitEx(25368, array('action' => 'add', 'text' => $text, 'expires' => time() + $merkzeit, 'removable' => true, 'type' => '3'));  
    // - 'type' (optional): Art der Meldung ... 0 => Normal(grün), 1 => Fehler(rot), 2 => Warnung(gelb), 3 => Status(blau), 4 => Status(orange) 
}

Das Skript wird einfach alle 10 Sekunden ausgeführt (Bedingung WR muss erreichbar sein).
Vielleicht könnte man es auch alle 5 Sekunden triggern?
Ich weiß nicht wie schnell der WR und MQTT reagieren?
Oder besser bei jeder Änderung Erzeugung und Verbrauch?

Hört sich interessant an. Ich bin auch immer noch dabei Verbrauch und Einspeisung zu optimieren und im Idealfall Nulleinspeisung zu erreichen.

Ich scheue mich allerdings ein wenig davor, den Wechselrichtern zu häufig eine neue Leistungsbegrenzung vorzugeben. Irgendwie habe ich Sorge, dass denen das auf Dauer nicht bekommt (Hardwaredefekt, Absturz aufgrund zu häufiger Befehle etc.)

Konnte damit schon jemand Erfahrung sammeln und weiß, wie diese Begrenzung technisch genau realisiert wird? Also was macht der Wechselrichter, damit er weniger oder mehr Leistung erzeugt? Läuft das ähnlich der Leistungsanpassung der MPPTs oder wird die Leistung irgendwo „verbraten“?

Letzteres glaube ich eigentlich nicht, da die Wechselrichter bei einer Reduzierung der Leistung auch eine DC-seitig reduzierte Spannung/Strom anzeigen.