Hallo Markus
Am Besten versuche ich es an meinem persönlichem Projekt (leider noch nicht ganz abgeschlossen) erkläre.
Ich will meinen Wärmeverbrauch der bezogenen Fernwärme loggen. In meiner Heizung ist zwar ein Wärmemengenzähler vom Energieversorger (Sharky 775 von Diehl) aber der ist verblomt und die Infrarotschnittstelle sendet nix...

Mit Google und Wiki und Restwissen vom Studium habe ich herausgefunden:
Um die aktuelle Leistung der Fernwärmeübergabe zu berechnen benötigt man 3 Werte:
- Temperatur Vorlauf
- Temperatur Rücklauf
- Volumenfluss vom Wasser
Die Aktuelle Leistung berechnet sich nach folgender Formel:
P = VolumenFluss * Spezifische Wärmekapazität Wasser * (TempVorlauf - TempRücklauf)
Die Bezogene Wärmemenge (das was ich bezahlen muss) ist dann das Integral bzw die Fläche unter dem Graphen.
Angenommen die Leistung ist 1 Stunde konstant:
E = P * 1h
Ändert sich die Leistung ist es die Summe von mehreren kleinen Zeitintervallen * Leistung
E = P1 * t1 + P2 * t2 + P3 *t3
Genau dieses tut meine Erweiterung nun.
Mittels 2 Temperatursensoren messe ich Vor und Rücklauf, den Volumenfluss kann ich bis jetzt leider nur Raten, weshalb ich noch nicht ganz glücklich bin.
Der Volumenfluss wird durch die Heizung durch ein Stellglied eingestellt (mein Ansatz hier was ab zugreifen). Mein Wärmezähler misst den und zeigt den auch an, weshalb ich jetzt immer mit 135 Liter/h rechne.
Da das Stellglied aber nicht immer offen ist, muss ich außerdem noch raten, wann es offen ist. Das ist offensichtlich dann der Fall, wenn der Vorlauf plötzlich heiß wird (von ca. 28° auf 55°). Momentan frage ich einfach ab ob die Vorlauftemperatur größer als 45 ° ist.
Per notify ausgelöst durch die Vorlauftemperatur berechne ich nun die Leistung und speichere sie als reading einem dummy. Der Dummy berechnet dann per "userReading integral "die Wärmemenge.
Hier mein Code aus der fhem.cfg
define Fernwaerme dummy
attr Fernwaerme alias Fernwaerme
attr Fernwaerme icon sani_earth_source_heat_pump
attr Fernwaerme stateFormat {sprintf("%.1f kWh %.1f kW\n", ReadingsVal("Fernwaerme","Energie",0), ReadingsVal("Fernwaerme","Leistung",0));;}
attr Fernwaerme userReadings Energie integral {ReadingsVal("Fernwaerme","Leistung",0)/3600}
define notiVor notify Vorlauf {\
fhem("setreading Fernwaerme Vorlauf ". $EVENT);;\
fhem("setreading Fernwaerme Ruecklauf ". Value("Ruecklauf"));;\
my $tempdiff = $EVENT - Value("Ruecklauf");;\
if ($tempdiff < 0) \
{\
$tempdiff = 0;;\
}\
fhem("setreading Fernwaerme TempDiff ". $tempdiff);;\
if ($EVENT > 45)\
{\
my $Leistung = 0.135 * 4.182 / 3.6 * $tempdiff;;\
fhem("setreading Fernwaerme Leistung $Leistung");;\
}\
else\
{\
fhem("setreading Fernwaerme Leistung 0");;\
}\
}
define FileLog_Fernwaerme FileLog log/Fernwaerme-%Y-%m.log Fernwaerme
define SVG_FileLog_Fernwaerme_1 SVG FileLog_Fernwaerme:SVG_FileLog_Fernwaerme_1:CURRENT
(http://M:\fernwaerme.png)