Ertragsmessung Solarthermie

Aus FHEMWiki


Grafische Auswertung (Plot)

Eine Ertragsmessung Solarthermie (Momentanleistung, Energieertrag) lässt sich mit den folgenden Maßnahmen umsetzen.

Technische Voraussetzungen

Info green.pngBitte beachten, dass in der beschriebenen Implementierung nicht FileLog sondern DbLog verwendet wird.
Konzeptübersicht
  1. Wasserzähler mit S0-Ausgang im Rücklauf des Solarkreises
  2. 1-Wire Zählermodul z.B. von [www.eservice-online.de] verbunden mit dem S0 Ausgang des Wasserzählers
  3. 1-Wire Temperatursensor (DS18B20) an der Rohrleitung im Vorlauf des Solarkreises
  4. 1-Wire Temperatursensor (DS18B20) an der Rohrleitung im Rücklauf des Solarkreises

Theoretische Vorarbeiten

Die am häufigsten verwendete Solarflüssigkeit ist [TYFOCOR LS http://www.tyfo.de/product/tyfocor-ls/], basierend auf Propylenglykol. Damit kann man den pro Liter transportierter Solarflüssigkeit erhaltenen Energiegewinn näherungsweise aus Vorlauf- und Rücklauftemperatur (TV,TR in Grad Celsius) des Solarkreislaufes bestimmen als

delta-E [in Wh/l] = Dichte [in g/l] * Wärmekapazität [in J/(g K)] * ( TV - TR )/3600

Multipliziert man das mit dem Volumen [in l], ergibt sich der Energiegewinn, bei Multiplikation mit dem Volumenstrom [in l/h] die Leistung in kW.

Ungefähre Werte sind für die Dichte 993 g/l und für die Wärmekapazität 3.8 J/(g K).

Allerdings variiert die Dichte ebenso mit der Temperatur, wie die Wärmekapazität. Eine genauere Darstellung erhält man daher mit

delta-E [in Wh/l] = C11 + (C21 + C22*(TR-20)+C23*(TR-20)^2)*(TV-TR) + C31*(TV-TR)^2

wobei

C11 = -0.00064
C21 = 1.03392
C22 = 0.00055
C23 = 0.000002
C31 = 0.00057

Definitionen in FHEM

Mit den nachfolgend beschriebenen Definitionen und Hilfsfunktionen werden diese Berechnungen von FHEM durchgeführt.

Konfiguration

Erforderliche Einträge in der Konfiguration für die Sensoren und den Zähler anlegen (Adressen der Sensoren müssen ggf. angepasst werden):

# Das VORHANDENE attr global userattr um die nachfolgenden Werte ERWEITERN. 
# Bitte keine neue attr global userattr Zeile anlegen!!!
attr global userattr ctsperm3 dichte waermekapazitaet offset

# ctsperm3: Anzahl der Impulse des Wasserzählers pro m3
# dichte: Dichte der Solarträgerflüssigkeit. Bei Propylenglykol ca 993kg/m3
# waermekapazität: Wärmekapazität der Solarträgerflüssigkeit, Propylenglykol ca 3.8 bei 80C
# offset: Initialer Zählerstand des Wasserzählers bei Inbetriebnahme dieser Lösung

#
# Solarkreis Vorlauftemperatur
#

define T_SOLARKREIS_VORLAUF OWDevice 28.A234AB040000 120
attr T_SOLARKREIS_VORLAUF IODev myLocalOWServer
attr T_SOLARKREIS_VORLAUF alias Solarkreis Vorlauf
attr T_SOLARKREIS_VORLAUF event-min-interval temperature:240
attr T_SOLARKREIS_VORLAUF event-on-change-reading temperature
attr T_SOLARKREIS_VORLAUF event-on-update-reading temperature
attr T_SOLARKREIS_VORLAUF fp_Heizung 455,820,0,
attr T_SOLARKREIS_VORLAUF group Heizungswerte
attr T_SOLARKREIS_VORLAUF icon sani_solar_temp
attr T_SOLARKREIS_VORLAUF model DS18B20
attr T_SOLARKREIS_VORLAUF room 3.01 Heizung
attr T_SOLARKREIS_VORLAUF stateFormat {sprintf("%.1f°;",ReadingsVal("T_SOLARKREIS_VORLAUF","temperature",0))."C"}
#Ausgabeformat bei 18B20 Sensoren: temperature: 56.1875 alarm: 1

#
# Solarkreis Rücklauftemperatur
#

define T_SOLARKREIS_RUECKLAUF OWDevice 28.9FB1AA040000 120
attr T_SOLARKREIS_RUECKLAUF IODev myLocalOWServer
attr T_SOLARKREIS_RUECKLAUF alias Solarkreis Rü;cklauf
attr T_SOLARKREIS_RUECKLAUF event-min-interval temperature:240
attr T_SOLARKREIS_RUECKLAUF event-on-change-reading temperature
attr T_SOLARKREIS_RUECKLAUF event-on-update-reading temperature
attr T_SOLARKREIS_RUECKLAUF fp_Heizung 520,820,0,
attr T_SOLARKREIS_RUECKLAUF group Heizungswerte
attr T_SOLARKREIS_RUECKLAUF icon sani_solar_temp
attr T_SOLARKREIS_RUECKLAUF model DS18B20
attr T_SOLARKREIS_RUECKLAUF room 3.01 Heizung
attr T_SOLARKREIS_RUECKLAUF stateFormat {sprintf("%.1f°;",ReadingsVal("T_SOLARKREIS_RUECKLAUF","temperature",0))."C"}

#
# Solarkreis Plot
#
define PL_SOLARKREIS SVG myDbLog:myDbSolarkreis:HISTORY
attr PL_SOLARKREIS group Heizungsverlauf
attr PL_SOLARKREIS label "Vorlauf min: $data{min1}, max: $data{max1}, last: $data{currval1}"::"Ruecklauf min: $data{min2}, max: $data{max2}, last: $data{currval2}"
attr PL_SOLARKREIS plotfunction T_SOLARKREIS_VORLAUF T_SOLARKREIS_RUECKLAUF
attr PL_SOLARKREIS room 3.01 Heizung
attr PL_SOLARKREIS title "Solarkreis"

# #
# # Solarkreis Volumenstrommessung
# #
#
# Folgende Parameter müssen an die individuelle Konfiguration angepasst werden:
# ctsperm3: Anzahl der Impulse des Wasserzählers pro m3
# dichte: Dichte der Solarträgerflüssigkeit. Bei Propylenglykol ca 993kg/m3
# waermekapazität: Wärmekapazität der Solarträgerflüssigkeit, Propylenglykol ca 3.8 bei 80C
# offset: Initialer Zählerstand des Wasserzählers bei Inbetriebnahme dieser Lösung

define C_SOLARZAEHLER OWDevice 1D.950A10000000 60
attr C_SOLARZAEHLER IODev myLocalOWServer
attr C_SOLARZAEHLER alias Solarzähler
attr C_SOLARZAEHLER ctsperm3 1000
attr C_SOLARZAEHLER dichte 993
attr C_SOLARZAEHLER waermekapazitaet 3.8
attr C_SOLARZAEHLER event-on-update-reading counters.A,volumenstrom,d_volumen,solarleistung,solartagesertrag,solargesamtertrag
attr C_SOLARZAEHLER group Heizungswerte
attr C_SOLARZAEHLER icon sani_solar
attr C_SOLARZAEHLER model DS2423
attr C_SOLARZAEHLER offset 134.784
attr C_SOLARZAEHLER room 3.01 Heizung
attr C_SOLARZAEHLER stateFormat {sprintf("V: %.2fm3",solarzaehlerstand("C_SOLARZAEHLER","counters.A",0)).sprintf(" E: %.2fkWh",ReadingsVal("C_SOLARZAEHLER","solartagesertrag",0)).sprintf(" P: %.2f kW",ReadingsVal("C_SOLARZAEHLER","solarleistung",0));;}
attr C_SOLARZAEHLER userReadings volumenstrom:counters.A differential {solarzaehlerstand('C_SOLARZAEHLER', 'counters.A');;}, d_volumen:counters.A difference {solarzaehlerstand('C_SOLARZAEHLER', 'counters.A');;}, solarleistung:volumenstrom { get_solarleistung('C_SOLARZAEHLER', 'T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');;}, solargesamtertrag {get_solarertrag('C_SOLARZAEHLER','T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');; }, solartagesertrag { get_d_solarertrag('C_SOLARZAEHLER', 'D_SOLARCNTATMIDNIGHT');;}, solarmonatsertrag { get_d_solarertrag('C_SOLARZAEHLER', 'D_SOLARCNTAT1STDAYOFMONTH');;}, solarjahresertrag {  get_d_solarertrag('C_SOLARZAEHLER','D_SOLARCNTAT1STDAYOFYEAR');;}


#
# # Solarenergie=Wärmekapazität * Masse * (T_SOLARKREIS_VORLAUF - T_SOLARKREIS_RUECKLAUF)
# Leistung wird in kW berechnet
# Solarenergie liefert kWs, da das Differential über s gebildet wird.
#
define D_SOLARCNTATMIDNIGHT dummy
attr D_SOLARCNTATMIDNIGHT event-on-change-reading state
attr D_SOLARCNTATMIDNIGHT room 9.02_Steuerung

define D_SOLARCNTAT1STDAYOFMONTH dummy
attr D_SOLARCNTAT1STDAYOFMONTH event-on-change-reading state
attr D_SOLARCNTAT1STDAYOFMONTH room 9.02_Steuerung
 
define D_SOLARCNTAT1STDAYOFYEAR dummy
attr D_SOLARCNTAT1STDAYOFYEAR event-on-change-reading state
attr D_SOLARCNTAT1STDAYOFYEAR room 9.02_Steuerung
#
#
define S_SOLARCNTSCHEDULER at *00:00:00 { set_solarcounters(ReadingsVal("C_SOLARZAEHLER","solargesamtertrag",0));;}
attr S_SOLARCNTSCHEDULER room 9.02_Steuerung
#
# #
# # Solarzaehler Plot
# #
define PL_SOLARZAEHLER SVG myDbLog:myDbSolarzaehler:HISTORY
attr PL_SOLARZAEHLER group Heizungsverlauf
attr PL_SOLARZAEHLER label "E min: $data{min1}, max: $data{max1}, last: $data{currval1}"::"P min: $data{min2}, max: $data{max2}, last: $data{currval2}"
attr PL_SOLARZAEHLER plotfunction C_SOLARZAEHLER
attr PL_SOLARZAEHLER room 3.01 Heizung
attr PL_SOLARZAEHLER title "Solarzaehler"

#
# Floorplans
#
 
define Heizung FLOORPLAN fp_Heizung.png
#attr Heizung fp_arrange detail

Hilfsfunktionen

Definitionen in der 99_my??Utils.pm:

#Ganz am Anfang des Moduls folgenden Eintrag vornehmen:
use DateTime;

# Irgendwo weiter unten in 99_Utils folgende Hilfsfunktionen eintragen:
sub solarzaehlerstand
{
  my($device, $counter)=@_;
  # Berechnung des Gaszaehlerstandes in m3
  # V=m3offset+counts/countsperm3
  my($zaehlerstand)=
     AttrVal($device,"offset",0)+ReadingsVal($device,$counter,0)/AttrVal($device,"ctsperm3",1000);
  return($zaehlerstand);
}

sub set_solarcounters
{
  my($cts) = @_;
  fhem("set D_SOLARCNTATMIDNIGHT ".$cts);
  if (DateTime->today(time_zone => $ENV{TZ})->day()==1)
  {
    fhem("set D_SOLARCNTAT1STDAYOFMONTH ".$cts);
    fhem("set D_SOLARCNTAT1STDAYOFYEAR ".$cts) if (DateTime->today(time_zone => $ENV{TZ})->month()==1);
  }
}

sub get_solarenergie
{
  my($device,$t_vorlauf,$t_ruecklauf) = @_;
  #Solarenergie=Wärmekapazität * Volumen * Dichte * (T_SOLARKREIS_VORLAUF - T_SOLARKREIS_RUECKLAUF)
  # Wärmeträger Propylenglykol
  # waermekapazität: 3.8 kJ/kgK
  # ctsperm3: 1000 Impulse/m3
  # Dichte: 993kg/m3
  # EInheiten: kJ/kgK*kg/m3*cts*1/cts/m3*K=kJ
  # Berechnung in kWs bzw kJ *1h/3600s
  my($solarenergy) = AttrVal($device,"waermekapazitaet",3.8)
                     * AttrVal($device,"dichte", 993)
                     * ReadingsVal($device,'d_volumen', 0)
                     * (ReadingsVal($t_vorlauf, "temperature",0)-ReadingsVal($t_ruecklauf, "temperature",0))
                     *1/3600;
  return($solarenergy);
}

sub get_solarleistung
{
  my($device,$t_vorlauf,$t_ruecklauf) = @_;
  # Solarleistung=Wärmekapazität * Volumenstrom * Dichte * (T_SOLARKREIS_VORLAUF - T_SOLARKREIS_RUECKLAUF)
  # Wärmeträger Propylenglykol
  # waermekapazität: 3.8 kWs/kgK
  # volumenstrom: m3/s
  # Dichte: 993kg/m3
  # EInheiten: kWs/kgK*kg/m3*m3/s*K=kJ
  # Berechnung in kWs bzw kJ
  my($solarenergy) = AttrVal($device,"waermekapazitaet",3.8)
                     * AttrVal($device,"dichte", 993)
                     * ReadingsVal($device,'volumenstrom', 0)
                     * (ReadingsVal($t_vorlauf, "temperature",0)-ReadingsVal($t_ruecklauf, "temperature",0));
  return($solarenergy);
}

sub get_solarertrag
{
  my($device,$t_vorlauf,$t_ruecklauf) = @_;
  my($solarenergy)=ReadingsVal($device, "solargesamtertrag",0)
     + get_solarenergie($device, $t_vorlauf,$t_ruecklauf);
  return($solarenergy);
}

sub get_d_solarertrag
{
  my($device, $startdummy) = @_;
  my($solarenergy)=ReadingsVal($device, "solargesamtertrag",0)
                 - ReadingsVal($startdummy,'state',0);
  return($solarenergy);
}

.gplot Definitionen

Um die gezeigten Auswertungen zu erhalten, müssen die folgenden Plot-Definitionen angelegt werden:

# Datei myDbSolarkreis.gplot mit folgendem Inhalt im gplot-Verzeichnis anlegen
# Achtung: Die Definition basiert auf der Verwendung von DbLog

# Created by FHEM/98_SVG.pm, 2014-01-20 14:45:44
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title '<TL>'
set ytics
set y2tics
set grid xtics y2tics
set ylabel 'Temperatur (C)'
set y2label 'Temperatur (C)'
#set yrange [10:60]
#set y2range [10:60]


#FileLog 4:T_SOLARKREIS_VORLAUF.temperature\x3a::
#FileLog 4:T_SOLARKREIS_RUECKLAUF.temperature\x3a::
#DbLog <SPEC1>:temperature:20:
#DbLog <SPEC2>:temperature:20:

plot "<IN>" using 1:2 axes x1y2 title 'Vorlauf' ls l0 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Ruecklauf' ls l1 lw 1 with lines
# Datei myDbSolarkreis.gplot mit folgendem Inhalt im gplot-Verzeichnis anlegen
# Achtung: Die Definition basiert auf der Verwendung von DbLog

# Created by FHEM/98_SVG.pm, 2014-01-20 14:45:44
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title '<TL>'
set ytics
set y2tics
set grid xtics y2tics
set ylabel "Momentanleistung [kW]"
set y2label "Gesamtertrag [kWh]"

#DbLog <SPEC1>:solarleistung:0:
#DbLog <SPEC1>:solartagesertrag:0:

plot \
  ls l0 axes x1y1 title 'Momentanleistung [kW]' with lines lw 2, \
  ls l2fill axes x1y2 title 'Tagesertrag [kWh]' with lines

Links

  • Thread im Forum, in dem die Lösung vorgestellt wurde; Diskussionen / Kommentare bitte dort