kWH Zähler für Solarthermie

Begonnen von g.carls, 21 März 2014, 08:11:12

Vorheriges Thema - Nächstes Thema

g.carls

Hallo zusammen!
Ich möchte gerne vorstellen, wie sich mit relativ einfachen Mitteln Momentanleistung und Energieertrag einer Solarthermie-Anlage messen lässt.
Folgende technischen Voraussetzungen müssen geschaffen werden:

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 1-wire Temperatursensor (DS18B20) an der Rohleitung im Vorlauf des Solarkreises
4) 1 1-wire Temperatursensor (DS18B20) an der Rohrleitung im Rücklauf des Solarkreises

Über den Volumenstrom im Solarkreis und die Temperaturdifferenz zwischen Vorlauf und Rücklauf des Solarkreises können dann
Energie und Momentanleistung wie folgt berechnet werden:

Solarleistung=Wärmekapazität * Volumenstrom * Dichte * (T_SOLARKREIS_VORLAUF - T_SOLARKREIS_RUECKLAUF)
Solarenergie=Wärmekapazität * Volumen * Dichte * (T_SOLARKREIS_VORLAUF - T_SOLARKREIS_RUECKLAUF)

Mit den nachfolgenden Defines und Hilfsfunktionen werden diese Berechnungen von FHEM durchgeführt.
Bitte beachten, dass ich in der nachfolgenden Implementierung keine FileLogs sondern DbLog verwende!

Um einen Eindruck zu bekommen, wie das Ergebnis aussieht, habe ich zwei Screenshots beigefügt.

in fhem.cfg folgende defines für die Sensoren und den Zähler anlegen (dabei natürlich die Adressen der Sensoren anpassen):


# vorhandenes global userattr um folgende attribute erweitern (kein neues attr global in fhem.cfg eintragen!!!)
# 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

# VORHANDENES global userattr ERWEITERN!!!!
attr global userattr ctsperm3 dichte waermekapazitaet offset

#
# 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"
[/tt]

#
# Floorplans
#

define Heizung FLOORPLAN fp_Heizung.png
#attr Heizung fp_arrange detail



Folgende Hilfsfunktionen in 99_myUtils.pm hinzufügen:

Diese Funktionen verwenden das Perlmodul DateTime. Um dieses Modul zu nutzen, muss man die entsprechende use Anweisung am Beginn des myUtils.pm Moduls aufnehmen:

package main;

use strict;
use warnings;
use POSIX;
use DateTime;


Auf Debian und Ubuntu Systemen lässt sich dieses Paket auf einfache Weise wie folgt installieren:

apt-get update
apt-get install libdatetime-perl


Sollte kein vorkonfektioniertes Installationspaket verfügbar sein, dann kann man sich das Paket auch bei www.cpan.org herunterladen.

Einige der Funktionen werten die Umgebungsvariable $TZ aus, um die Zeitzone zu ermitteln.
Wenn diese Variable nicht oder falsch in der Startumgebung von FHEM gesetzt ist, kann dies zu Problemen führen.
Man kann dann auch einfach

$ENV{TZ}
durch
'Europe/Berlin'

im nachfolgenden Code ersetzen.


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);
}


Diagramm für Solar-Vorlauf- und Rücklauftemperaturen: myDbSolarkreis.gplot

# Datei myDbSolarkreis.gplot mit folgendem Inhalt im gplot-Verzeichnis anlegen
# Achtung: Ich verwende 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


Diagramm für solare Leistung und solaren Energieertrag: myDbSolarzaehler.gplot


# Datei myDbSolarzaehler.gplot mit folgendem Inhalt im gplot-Verzeichnis anlegen
# Achtung: Ich verwende 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


ph1959de

@g.carls: mMit Verlaub, diese Beschreibung gehört unbedingt ins Wiki!

... deshalb habe ich das gleich gemacht (http://www.fhemwiki.de/wiki/Ertragsmessung_Solarthermie, zu finden über http://www.fhemwiki.de/wiki/Anwendungsszenarien) - ich hoffe, Du bist damit einverstanden.

Eine kleine Änderung ist meiner Meinung nach nötig: die Hilfsfunktionen sollten besser nicht in die 99_Utils.pm, sondern in eine 99_my???Utils.pm, damit sie dauerhaft sind und nicht vom nächsten Update überschrieben werden. Ich hab das mal mit den ??? in den Artikel übernommen - wenn Du das bitte noch korrigieren würdest.

Gruß, Peter
Aktives Mitglied des FHEM e.V. | Moderator im Forenbereich "Wiki"

g.carls

Vielen Dank für die Mühe, das so sorgfältig ins Wiki zu übertragen!

VG, Guido

Papaloewe

Sehr, sehr interessant.
Vielen Dank für diesen Beitrag.

Welchen Wasserzähler verwendest du?

Gruß
Thomas

ph1959de

Zitat von: g.carls am 21 März 2014, 11:22:42
Vielen Dank für die Mühe, das so sorgfältig ins Wiki zu übertragen!
Bei der guten Vorlage war das leicht und schnell gemacht.

Wie schon gesagt: nur an die 99_Utils-Geschichte müsstest Du noch mal ran.

Gruß, Peter
Aktives Mitglied des FHEM e.V. | Moderator im Forenbereich "Wiki"

Franz Tenbrock

#5
Hallo super Sache.
Habe auch PV und Solarthermie.
Hole mir mit 1 Wire auch die Temperaturen vom Vor und Rücklauf der Solar und Heizungsanlage, sowie vom Speicher oben und unten sowie die Aussentemperatur.
Ich logge Aussentemperatur, Speicher oben Speicher unten. So sieht man schön wie der Speicher bei gutem Wetter aufgeladen wird.
Ebenso hab ich ein EM1000GZ am Gaszähler hängen,
Man erkennt sofort wenn die Heizungsanlage den Speicher aufeizt.
Bei uns wird meistens nachmittags oder abends geduscht. Da meine Frau aber auch mittags richtig warmes Wasser haben will wird morgens kurz der Speicher geladen.
Es wäre schön wenn man über die Wettervorhersage das morgendliche aufheizen des Speichers bei schönen Wetter verhindern könnte.
Leider gibt es da bei Wolf Anlagen bisher keine Möglichkeit oder ??

Ich habe schon vor Jahren gegen den Rat des Heizungsfachmanns? ein Dreiwegeventil direkt vor dem Fußpunkt des Speichers angebracht , so dass das Trägermedium nur durch den Speicher geht wenn es auch tatsächlich wärmer ist als der Speicher . So hab ich die  Effektivität der Anlage schon deutlich verbessert.

Mit diesem Modul steht wohl erstmals eine Möglcihkeit offen die tatsächliche Einsparung zu berechnen, um dann eventuelle Anpassungen zu realisieren.

Was fehlt wäre der Stromverbrauch der Umwälzung, was sich ja leicht mittels 1wire Stromzähler realisieren ließe.


Ich were immer mehr zum FHEM Fan :-)
cubi3, Cul 868, ESA2000WZ, EM1000GZ,  FS20, dashboard, 1-Wire, Max Thermos, Max Wandthermo, Max Lan, Fritzbox callmonitor, , nanocul, HM Led16, HM Bewegungsmelder, HM Schalter, RPi, banana, ESP8266, DoorPi

kdeb

Hallo Guido,

danke für die Arbeit, das war genau das, was ich jetzt gebraucht habe. :)

Ich hab grade mal die HW in meine Anlage reingebastelt und den Code in meine Config eingeklebt.
Dabei ist mir aufgefallen, daß beide Plotdateien denselben Namen haben (zumindest im Komentar). Ich rate mal, daß die zweite myDbSolarzaehler.gplot heißen soll, oder?
Hardwaretechnisch scheint alles zu funktionieren, der Zähler zählt, und die beiden Temperaturfühler messen. So weit, so gut.

Bei Starten des fhem-Servers habe ich jetzt aber zwei Fehlermeldungen, an denen ich mir die Zähnchen ausbeiße:

Error messages while initializing FHEM:
configfile: T_SOLARKREIS_VORLAUF: unknown attribute fp_Heizung. Type 'attr T_SOLARKREIS_VORLAUF ?' for a detailed list.

Unknown command ",ReadingsVal("T_SOLARKREIS_VORLAUF","temperature",0))."C"}, try help.
Unknown command cklauf, try help.

Hast Du ne Idee, woran das liegen kann?

Schönen Gruß

Kai

kdeb

ok, den Fehler mit dem "Unknown command" habe ich gerade selber gefunden: Das Wiki macht aus %.1f&deg;; ein %.1f°;, und wenn man das einfach per c&p übernimmt, ist plötzlich ein freies Semikolon übrig, und das macht Streß. Im Quelltext steht es richtig. Ich spreche nur leider nicht fließend Wiki, deshalb weiß ich nicht, wie man ihm das austreiben kann. Kann da jemand helfen?

Bei dem anderen Fehler scheint eine Definition zu fehlen. Ein Attribut fp_Heizung habe ich nirgens. Muß ich das noch irgendwo einzwicken, oder brauche ich noch irgend einen Codeschnipsel, in dem das definiert wird?

Schönen Gruß

Kai

ph1959de

Zitat von: kdeb am 25 April 2014, 10:37:43
ok, den Fehler mit dem "Unknown command" habe ich gerade selber gefunden: Das Wiki macht aus %.1f&deg;; ein %.1f°;, und wenn man das einfach per c&p übernimmt, ist plötzlich ein freies Semikolon übrig, und das macht Streß. Im Quelltext steht es richtig. Ich spreche nur leider nicht fließend Wiki, deshalb weiß ich nicht, wie man ihm das austreiben kann. Kann da jemand helfen?
Ist eher der Browser, als das Wiki, aber ich hab's mal geändert ...

Danke, Peter
Aktives Mitglied des FHEM e.V. | Moderator im Forenbereich "Wiki"

g.carls

Zitat von: kdeb am 25 April 2014, 10:37:43
ok, den Fehler mit dem "Unknown command" habe ich gerade selber gefunden: Das Wiki macht aus %.1f&deg;; ein %.1f°;, und wenn man das einfach per c&p übernimmt, ist plötzlich ein freies Semikolon übrig, und das macht Streß. Im Quelltext steht es richtig. Ich spreche nur leider nicht fließend Wiki, deshalb weiß ich nicht, wie man ihm das austreiben kann. Kann da jemand helfen?

Bei dem anderen Fehler scheint eine Definition zu fehlen. Ein Attribut fp_Heizung habe ich nirgens. Muß ich das noch irgendwo einzwicken, oder brauche ich noch irgend einen Codeschnipsel, in dem das definiert wird?

Schönen Gruß

Kai


Hallo Kai,

fp_Heizung referenziert den Floorplan, in dem ich den ganzen Heizkreis grafisch darstelle (siehe Screenshot). Du musst dafür in der fhem.cfg folgende Konfiguration ergänzen:

#
# Floorplans
#

define Heizung FLOORPLAN fp_Heizung.png
#attr Heizung fp_arrange detail


Für fp_Heizung.png solltest du eine Grafik gem deiner Heizungsinstallation erstellen und anschliessend die Koordinaten der Messwerte anpassen.
Die Koordinaten der Messwerte im Floorplan werden dann jeweils z.B. wie folgt angegeben:

attr T_SOLARKREIS_RUECKLAUF fp_Heizung 520,820,0,


Das Platzieren der Messwerte an den passenden Koordinaten kann man auch mit Unterstützung von fhem machen, in dem man
attr Heizung fp_arrange detail
temporär auskommentiert und damit die Koordinaten dann direkt im Floorplan setzen kann.

Viele Grüße,

Guido

Prof. Dr. Peter Henning

Ich habe mir den Spaß gemacht und die Näherung für die Wärmeberechnung etwas verbessert. Denn die angegebenen mittleren Werte für Propylenglykol weichen um bis zu ca. 5% von den realen Daten ab. Ist bereits ins Wiki eingetragen als

http://www.fhemwiki.de/wiki/Ertragsmessung_Solarthermie#Theoretische_Vorarbeiten

Die Codierung dafür habe ich mir gespart, das ist ganz einfach.

LG

pah

rori

#11
Hallo, ich würde gerne eine Solarthermieanlage von Anfang an korrekt über Fhem/Raspberry "tracken". Ich bin allerdings bei der Auswahl konkreter Hardware leicht überfordert. Ist es möglich, dass jemand einen konkrete Einkaufsliste/Produktvorschläge zu der hier vorgestellten Lösung postet?

Ich bin einigermassen vertraut mit CUL,HomeMatic und Lacrosse/JeeLink, habe allerdings noch keine Erfahrung mit s0, 1-Wire und Arduino. Ich möchte nur ungern falsche/inkompatible Komponenten einkaufen und einbauen, die nachher nicht harmonierenoder nicht an FHEM anbindbar sind...

Wer kann mir bitte einen guten Tipp (gerne mit Link, falls das die Forenregeln erlauben)  bezgl. Hardware zu den oben genannten 4 Vorraussetzungen geben? Das wäre eine Super-Starthilfe in ein neues Kapitel Hausautomatisierung für mich :-)

Danke und Gruß

rori

devien

ich hab mal deine schicke Vorlage bei mir reichgepatcht (und gemäß meiner Parameter angepast.

Das ich über den ersten Tag keine Werte in Solartagesertrag hab kam mir etwas unfein vor, aber ich hab das darauf geschoben das die Mitternachtsberechnung aussteht.
nun nach Mitternacht habe ich im Log jedoch
2017.07.06 00:00:00 1: ERROR evaluating { set_solarcounters(ReadingsVal("i01","solargesamtertrag",0));}: The 'time_zone' parameter (undef) to DateTime::from_epoch was an 'undef', which is not one of the allowed types: scalar object
at /usr/lib/perl5/DateTime.pm line 488
DateTime::from_epoch(undef, 'epoch', 1499292000, 'time_zone', undef) called at /usr/lib/perl5/DateTime.pm line 514
DateTime::now('DateTime', 'time_zone', undef) called at /usr/lib/perl5/DateTime.pm line 516
DateTime::today('DateTime', 'time_zone', undef) called at ./FHEM/99_mySolarUtils.pm line 37
main::set_solarcounters(0) called at (eval 6170) line 1
eval '{ set_solarcounters(ReadingsVal("i01","solargesamtertrag",0));}
;' called at fhem.pl line 1073
main::AnalyzePerlCommand(undef, '{ set_solarcounters(ReadingsVal("i01","solargesamtertrag",0));}', 1) called at


was heißt das ?ich kann keine Timezone einstellen im Solarzählerdevice :/

ich gebe mal meine angepassten Datein mit zur Info:
der Solarzähler (am Unipi ein GPIO:
defmod i01 RPI_GPIO 4
attr i01 active_low no
attr i01 alias Solarzähler
attr i01 ctsperm3 1000
attr i01 dichte 1042
attr i01 direction input
attr i01 event-on-update-reading Counter,volumenstrom,d_volumen,solarleistung,solartagesertrag,solargesamtertrag
attr i01 icon sani_solar
attr i01 interrupt falling
attr i01 offset 134.7
attr i01 poll_interval 5
attr i01 pud_resistor up
attr i01 restoreOnStartup no
attr i01 room Solarsteuerung,UniPi
attr i01 stateFormat {sprintf("V: %.2fm3",solarzaehlerstand("i01","Counter",0)).sprintf(" E: %.2fkWh",ReadingsVal("i01","solartagesertrag",0)).sprintf(" P: %.2f kW",ReadingsVal("i01","solarleistung",0));;}
attr i01 userReadings volumenstrom:Counter differential {solarzaehlerstand('i01', 'Counter');;}, d_volumen:Counter difference {solarzaehlerstand('i01', 'Counter');;}, solarleistung:volumenstrom { get_solarleistung('i01', 'T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');;}, solargesamtertrag {get_solarertrag('i01','T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');; }, solartagesertrag { get_d_solarertrag('i01', 'D_SOLARCNTATMIDNIGHT');;}, solarmonatsertrag { get_d_solarertrag('i01', 'D_SOLARCNTAT1STDAYOFMONTH');;}, solarjahresertrag {  get_d_solarertrag('i01','D_SOLARCNTAT1STDAYOFYEAR');;}
attr i01 verbose 4
attr i01 waermekapazitaet 3.8


die Temperatursensoren für Vor und Rücklauf:
defmod DS18B20_Vorlauf_S OWDevice 28.FF293E011604 60
attr DS18B20_Vorlauf_S IODev ows
attr DS18B20_Vorlauf_S event-min-interval temperature:240
attr DS18B20_Vorlauf_S event-on-change-reading temperature
attr DS18B20_Vorlauf_S event-on-update-reading temperature
attr DS18B20_Vorlauf_S fp_Heizung 283,1043,0,temperature
attr DS18B20_Vorlauf_S fp_Solar 309,308,0,DS18B20_Vorlauf_S,
attr DS18B20_Vorlauf_S group Solar
attr DS18B20_Vorlauf_S icon sani_solar_temp
attr DS18B20_Vorlauf_S model DS18B20
attr DS18B20_Vorlauf_S room Solarsteuerung
attr DS18B20_Vorlauf_S stateFormat {sprintf("%.1f&deg;;",ReadingsVal("DS18B20_Vorlauf_S","temperature",0))."C"}

defmod DS18B20_Ruecklauf_S OWDevice 28.FF9C5C051603 60
attr DS18B20_Ruecklauf_S IODev ows
attr DS18B20_Ruecklauf_S event-min-interval temperature:240
attr DS18B20_Ruecklauf_S event-on-change-reading temperature
attr DS18B20_Ruecklauf_S event-on-update-reading temperature
attr DS18B20_Ruecklauf_S fp_Heizung 372,1041,0,temperature,
attr DS18B20_Ruecklauf_S fp_Solar 173,307,0,DS18B20_Ruecklauf_S
attr DS18B20_Ruecklauf_S group Solar
attr DS18B20_Ruecklauf_S icon sani_solar_temp
attr DS18B20_Ruecklauf_S model DS18B20
attr DS18B20_Ruecklauf_S room Solarsteuerung
attr DS18B20_Ruecklauf_S stateFormat {sprintf("%.1f&deg;;",ReadingsVal("DS18B20_Ruecklauf_S","temperature",0))."C"}


dazu meine 99_mySolarUtils.pm :
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;
#Ganz am Anfang des Moduls folgenden Eintrag vornehmen:
use DateTime;
sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
}

# Enter you functions below _this_ line.
##########################################
# 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);
}
1;

selbstredent das ich die Fhem.cfg mit den global useratrr "ctsperm3 dichte waermekapazitaet offset" ergänzt habe.

ich möcht wetten ich hab etwas vergessen anzupassen oder einzutragen, aber ich kann es nicht finden....
Sieht es jemand und hilft mir auf die Sprünge?
FHEM + UniPi + Arduino = gute Lösung

amenomade

https://forum.fhem.de/index.php?topic=21655.0

ZitatEinige der Funktionen werten die Umgebungsvariable $TZ aus, um die Zeitzone zu ermitteln.
Wenn diese Variable nicht oder falsch in der Startumgebung von FHEM gesetzt ist, kann dies zu Problemen führen.
Man kann dann auch einfach

$ENV{TZ}

durch
'Europe/Berlin'

im nachfolgenden Code ersetzen.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

devien

aha, nun ist die Fehlermeldung offenbar weg (hab im Solarsheduller 'execNow' ausgeführt und keine weitere Fehlermeldung dieser Art)

bei der Gelegenheit ist mir aufgefallen das in den UserReading des Solarcounters solarleistung:volumenstrom { get_solarleistung('i01', 'T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');;}, solargesamtertrag {get_solarertrag('i01','T_SOLARKREIS_VORLAUF', 'T_SOLARKREIS_RUECKLAUF');; }
stand, habe T_SOLARKREIS_VORLAUF und T_SOLARKREIS_RUECKLAUF gegen DS18B20_Vorlauf_S und DS18B20_Ruecklauf_S ausgetauscht, bislang erhalte ich jedoch noch immer keine werte >0 bei solartagesertrag.

irgendwo ist noch ein Wurm drinn
FHEM + UniPi + Arduino = gute Lösung