Seite 1 von 1

[V4.0 IP3] [DEV-22.02.2023] Zähler mit Wertsicherung und Korrekturwert

Verfasst: So Mär 12, 2023 6:10 pm
von gbglace
Puhh mein erster Custom-Logikbaustein.
Eine echt herausfordernde Lernkurve. Aber mit der Doku hier im Forum und im Wiki und einigen Beispielen der anderen vorgestellten Customlogiken, denke ich habe ich es hinbekommen. Da schonmal Dank an das Elabnet Team, und Robert für die Doku im Wiki.
Ich habe halt bisher noch nix mit Elektronischer Schaltlogik und diesen Begrifflichkeiten zu tun gehabt, insofern echt nicht leicht gewesen meine Gedanken des Ablaufes und der kleinen Exceltabelle die ich zur Vorbereitung hatte hier umzusetzen. Und wie immer in meinen Codes teilweise im feinsten Denglisch, wem es stört mag das gern korrigieren ;-)

Ansonsten bitte ich gern um Anregungen / Korrekturen von Experten.


Hintergrund:
Ich habe grade im Zählerschrank einen neuen Zähler für das Nebenhaus eingebaut. In dem Strompfad hängt auch die PV-Anlage. An Der PV Anlage hängt auch ein Shelly. Aus diesem Shelly beziehe ich per MQTT den Bruttoertrag der PV-Anlage. Der große Zähler musste gewechselt werden da der vorige nur ein Einrichtungszähler war und ich somit nicht sehen konnte, wie hoch der Brutto-Verbrauch in dem Strompfad ist, sowie die PV-Anlage Überschuss produziert. Nun zählt dort ein Zweirichtungszähler ab 0.
Da natürlich der ganze Strompfad beim Zählerwechsel stromlos war hat der Shelly auch seinen Gesamtzählerstand vergessen.
Und der bisher ermittelte Verbrauch des Strompfades ist auch zu niedrig, da ihm mit dem HW-Wechsel die vielen kWh der letzten Jahre fehlen.
Und will ich den ausgebauten Zähler mal irgendwo als neuen Zähler einbauen, dann kommen da massiv zu viel kWh raus, da man den leider auch nicht resetten kann (L&J EMU KNX-Zähler).

Die Funktionalitäten relative Ergebniswerte (Tages / Wochen / Monats) zu ermitteln habe ich hier bewusst weggelassen, da es dazu ja bereits einen Baustein gibt ( Zähler Universalbaustein viewtopic.php?f=65&t=3782) von Sven @Robosoc . Ggf nimmt jemand das hier als funktionale Erweiterung dort noch mit auf.

Anforderung:
Damit habe ich nun das Bedürfnis einen neuen Logikbaustein zu entwerfen, der möglichst frei von solchem Vergessen ist und bei dem man auch mal bei einem HW-Wechsel auf Basis eines anderen Standes sinnvoll weiterzählen kann.
Also im Ergebnis nicht einfach darauf vertraut, dass die angelieferten Total kWh die korrekte Zahl sind. Ja und ich mag die Ergebnisse gern parallel in Wh und kWh.

Funktion:
Der Eingangswert wird geprüft ob er größer als der letzte Eingangswert ist. Ist er kleiner als der zuletzt empfangene Wert wird der Eingangswert auf den zuletzt errechneten Zählerstand hinzuaddiert. Ist dieser nicht kleiner wird auf den zuletzt errechneten Zählerstand die Differenz aus aktuellem Eingangswert und zuletzt empfangenen Eingangswert addiert.
Im Anschluss wird noch ein Korrektur-/Initialisierungswert, der als weiterer Eingangswert der Logik vorliegt, hinzu addiert und am ersten Ausgang ausgegeben.
Dieses Ergebnis wird dann noch mit einem Skalierungsfaktor multipliziert und dieses Ergebnis am zweiten Ausgang ausgegeben.
Der Dritte Ausgang ist die Signalisierung das ein Reset berücksichtigt wurde.


Die 3 Eingänge der Logik
["Eingang 1","Zählerrohwert","$In1","c" ],
["Eingang 2","Korrektur- / Initialisierungswert","$In2","u" ],
["Eingang 3","Umrechnungsfaktor","$In3","u" ]


Die drei Ausgänge der Logik
["Ausgang 1","Zählerwert weitergezählt + korrigiert","$Out1","a" ],
["Ausgang 2","Zählerwert weitergezählt + korrigiert + umgerechnet","$Out2","a" ],
["Ausgang 3","Reset am Inputzähler","$Found_reset","c" ]


dazu noch interne Zwischenergebniswerte
Intern 1: Auslöser der Logik war ein neuer Zählerstand
Intern 2: letzter Zähler Rohwert
Intern 3: Zähler Rohwert weitergezählt
Intern 4: letzter Zähler Rohwert weitergezählt


Um mit einem Latch-Modul die beiden Werte für den nächsten Durchlauf der Logik zu speichern (Intern 2 und Intern 4) braucht es einen booleschen Auslöser. Das Modul Triggerd prüft das am Eingang 1.
["Triggered", "$In1", "$Was_new_input"]

Im Anschluss folgt die Prüfung ob ein Reset des anliefernden Zählwerkes vorliegt mit einem Vergleicher-Baustein.
["Comparator" , "-$In1" , "$Found_reset" , "-$Last_input"]
Die beiden Vergleichswerte sind invertiert in Verwendung, um das als >= zu prüfen, da ich aber nur ein true haben will wenn es ein Reset gab ist der Ausgang hier ohne Invertierung.

Als nächstes kommt die Berechnung des fortgeführten Zählerstandes in Abhängigkeit ob es ein Reset gab ja/nein.
Dazu habe ich das Modul Freie Formel verwendet.
"X1?X2+X3:X2+X3-X4"
Wenn ein Reset vorliegt wird X2 + X3 gerechnet, sonst wird X2 + X3 - X4 gerechnet.
X1 ist das Reset Signal, X2 ist der zuletzt errechnete Zählerwert, X3 ist der aktuelle Eingangswert, X4 ist der zuletzt empfangene Eingangswert
["CalcFormula",["$Found_reset","$Last_continued","$In1","$Last_input"], "$Continued_value", "$F1"]

Dies deckt den Sachverhalt ab, dass sofern der Shelly mal keinen Strom mehr hat und dann beim Reboot mit einem Total-Zählerstand von 0 beginnt automatisch ein voller Zählerwert weitergezählt wird. Gibt es nur einen Reboot der Logik oder des TWS, funktioniert das soweit auch, da der Vorwert hier mit 0 initialisiert wird und somit der Vergleich ebenfalls positiv ausfällt.


Mit einem weiteren Baustein freie Formel wird dann der manuelle Korrektur/Initialisierungswert (zweiter Eingangswert) in einfacher Addition berücksichtigt.
"X1+X2"

["CalcFormula",["$Continued_value","$In2"], "$Out1", "$F2"]


Diese Addition hätte natürlich auch in die erste freie Formel im THEN und im ELSE eingebaut werden können, zur Wahrung der Transparenz wollte ich das aber getrennt berechnen.

Die dritte Formel konvertiert dann den fortgeführten und korrigierten Zählerwert mit dem dritten Eingangswert des Logikbausteins von Wh in kWh in einfacher Multiplikation.
"X1*X2"

["CalcFormula",["$Out1","$In3"], "$Out2", "$F3"]



Die letzten beiden Module sind dann die Latch-Module zur Fixierung des Eingangswertes und des weitergerechneten Zählers für den nächsten Logikdurchlauf.
["Latch","$In1","$Last_input","$Was_new_input",0]
["Latch","$Continued_value","$Last_continued","$Was_new_input",0]


Was ich noch intensiver austesten muss, ist wie stabil die Speicherung des letzten Wertes im TWS selbst ist.

Code: Alles auswählen

/**===========================================================
Nimmt einen Zählerwert entgegen
und plausibilisiert ihn (versucht bei Zählerreset weiterzuzählen)
und reichert Ihn um einen Initialisierungswert / Korrekturwert an
und gibt ihn in zwei Werten aus, die um einen Umrechnungsfaktor auseinander liegen (z.B. 0.001 Wh >> KWh)
============================================================*/

{
"Level": [
        // Input1 raw value
    ["$In1","float",0],
        // Input2 value to give an offset to the raw value
    ["$In2","float",0],
        // Input3 conversion factor to scale Outpu1 to Output2
    ["$In3","float",0],
        // formula to check input and continue counting
    ["$F1","string","X1?X2+X3:X2+X3-X4"],
        // formula to add correction initialise value
    ["$F2","string","X1+X2"],
        // formula to convert Output1 to Output 2
    ["$F3","string","X1*X2"],
        // Output value 1
    ["$Out1","float",0],
        // Output value 2
    ["$Out2","float",0],
        // internal variable a new value input was triggerd
    ["$Was_new_input","bool",true],
        // if input was reset
    ["$Found_reset","bool",false],
        // internal variable continued raw values
    ["$Continued_value","float",0],
        // interneal variable last raw value of input1
    ["$Last_input","float",0],
        // interneal variable last value continued counter
    ["$Last_continued","float",0]
    
  ],
"Module": [
    // set true if logic trigger was a new raw measurment Input
    ["Triggered", "$In1", "$Was_new_input"],
        // Output input reset y/n
    ["Comparator" , "-$In1" , "$Found_reset" , "-$Last_input"],
        // if reset then last continued counter + input value else last continued counter + input value - last input value
    ["CalcFormula",["$Found_reset","$Last_continued","$In1","$Last_input"], "$Continued_value", "$F1"],
        // Add correction value to continued counting value
    ["CalcFormula",["$Continued_value","$In2"], "$Out1", "$F2"],
        // scale Output value1 to Output value2
    ["CalcFormula",["$Out1","$In3"], "$Out2", "$F3"],
        // safe new input value as last value for next run of logic  
    ["Latch","$In1","$Last_input","$Was_new_input",0],
        // safe new continued value as last value for next run of logic
    ["Latch","$Continued_value","$Last_continued","$Was_new_input",0]
  ],
"Input": [
    ["Eingang 1","Zählerrohwert","$In1","c" ],
    ["Eingang 2","Korrektur- / Initialisierungswert","$In2","u" ],
    ["Eingang 3","Umrechnungsfaktor","$In3","u" ]
  ],
  
 "Output": [
    ["Ausgang 1","Zählerwert weitergezählt + korrigiert","$Out1","a" ],
    ["Ausgang 2","Zählerwert weitergezählt + korrigiert + umgerechnet","$Out2","a" ],
    ["Ausgang 3","Reset am Inputzähler","$Found_reset","c" ]
    // Output internal results for debuging
    ,["Internal_1","Wert war Trigger","$Was_new_input","a" ]
    ,["Internal_2","Zwischenspeicher letzter Input","$Last_input","a" ]
    ,["Internal_3","Zwischenspeicher letzter weitergezählter","$Last_continued","a" ]
    ,["Internal_4","Zwischenspeicher weitergezählter","$Continued_value","a" ]
  ]
}
/**Der Schöpfer dieser Custom Logik überträgt die Nutzungsrechte gemäß der TOLL ("Timberwolf Open Logikblock License") die unter https://wrgt.news/TOLL zum Download zur Verfügung steht.*/