Hallo Forum,
nachdem ich an der Erstellung von Readings eines DHT22 Sensors in der classdef eines ECMDDevices kläglich gescheitert bin, habe ich nun innerhalb weniger Stunden mit einem notify und der passenden DEF die readings hin bekommen. Das würde mir ansich reichen, WENN ich nicht noch den Taupunkt benötigen würde. ::)
Der aktuelle Stand:
dht22.classdef
get DHT cmd {"dht temp" . "\ndht humid"}
get DHT postproc {s/(.*)\n(.*)/T: $1 H: $2/; $_;}
Damit lässt sich schon mal ein ordentlicher Logeintrag erzeugen, der auch für Plots verwendbar ist (Danke nochmal an Boris für Hilfe mit dem substitution operator!).
Weiterhin bediene ich den Sensor selbst alle 4 Minuten mit
define WZ_Klima ECMDDevice DHT22
attr WZ_Klima IODev NETIO_WZ
attr WZ_Klima alias Wohnzimmer
attr WZ_Klima room Wohnung
attr WZ_Klima stateFormat { sprintf("%s°C %s%%", ReadingsVal("WZ_Klima","temperature",0), ReadingsVal("WZ_Klima","humidity",0)) ;; }
define WZ_TH at +*00:04 get WZ_Klima DHT
attr WZ_TH verbose 1
und das neu erstellte notify enthält
define dht2readings notify WZ_Klima:DHT.* {\
my $value1 = "%EVTPART2";;\
my $value2 = "%EVTPART4";;\
my $state = "T: $value1 H: $value2";;\
my $hash = $defs{%NAME};;\
readingsSingleUpdate($hash, "temperature", $value1, 1);;\
readingsSingleUpdate($hash, "humidity", $value2, 1);;\
readingsSingleUpdate($hash, "state", $state, 1);;\
;;\
undef\
}\
womit ich temperature, humidity und ein bereinigtes state erzeugen kann. Das nutzlose reading DHT bekomme ich zwar mit deletreading weg, erzeuge aber jedes mal einen logeintrag. Das ist aber eher kosmetisch...
Nun zun eigentlichen Problem:
Das Modul dewpoint generiert aus den Temperaturen und Feuchtewerten aller vohandenen Sensoren das reading dewpoint für jedes Device. Das funktioniert aber nicht bei meinen erstellten Readings! Ich kann zwar mit attr WZ_Klima userReadings dewpoint:temperature { my $dp;; my $temperature = ReadingsVal($name,"temperature",0);; my $humidity = ReadingsVal($name,"humidity",0);; my $A = 17.2694;; my $B = ($temperature > 0) ? 237.3 : 265.5;; my $es = 610.78 * exp( $A * $temperature / ($temperature + $B) );; my $e = $humidity/ 100 * $es;; if ($e == 0) { Log 1, "Error: dewpoint() e==0: temp=$temperature, hum=$humidity";; return 0;; } my $e1 = $e / 610.78;; my $f = log( $e1 ) / $A;; my $f1 = 1 - $f;; if ($f1 == 0) { Log 1, "Error: dewpoint() (1-f)==0: temp=$temperature, hum=$humidity";; return 0;; } $dp = $B * $f / $f1 ;;}
einen Taupunkt mit beachtlichen 12 Nachkommastellen als userReading erstellen, halte das aber für Quatsch, zumal durch die vielfach geplanten DHT22 entsprechende Codevervielfachungen nötig wären.
Lösungsansätze/Ideen/Fragen:
1. Lässt sich der Code im notify soweit anpassen, das ich bereits dort den Taupunkt (mit einer Nachkommastelle!) erhalte?
2. Lässt sich ein so angepasstes Notify für mehrere regexp anwenden?
3. Warum "greift" das Modul dewpoint nicht?
4. Kann ich deletereading anwenden, ohne einen Logeintrag zu erzeugen? (verbose bewirkt nix)
Viele Grüße, Ricardo
1. sicher, Taupunktberechnung ist keine Hexerei, hast ja selbst gezeigt.
2. sicher, ob das noch sinnvoll/uebersichtlich ist, sei hingestellt.
3. weil dewpoint vor dem notify drankommt, damit notifies mit dem dewpoint rechnen koennen. Damit generiert dein readings*Update im notify kein neues Event.
4. falls man deletereading im notify ausfuehrt, und man kein forwardReturnValue gesetzt hat, sollte im log nichts erscheinen.
Zitat von: rudolfkoenig am 16 März 2014, 13:51:25
1. sicher, Taupunktberechnung ist keine Hexerei, hast ja selbst gezeigt.
Stimmt, auch wenn der Code aus dem wiki stammt, musste er angepasst werden, um an der Stelle zu funktionieren. Ich versuche mich daran!
Zitat von: rudolfkoenig am 16 März 2014, 13:51:25
2. sicher, ob das noch sinnvoll/uebersichtlich ist, sei hingestellt.
Ich sehe nur keine andere Möglichkeit, exotische Sensoren via ECMDDevice mit wenig Aufwand und ohne unnötig vielfachen Code einzubinden.
Zitat von: rudolfkoenig am 16 März 2014, 13:51:25
3. weil dewpoint vor dem notify drankommt, damit notifies mit dem dewpoint rechnen koennen. Damit generiert dein readings*Update im notify kein neues Event.
... was das Verhalten des dewpoint erklärt... Danke!
Zitat von: rudolfkoenig am 16 März 2014, 13:51:25
4. falls man deletereading im notify ausfuehrt, und man kein forwardReturnValue gesetzt hat, sollte im log nichts erscheinen.
Ich habe es nicht gesetzt! Standardmäßig ist es auch aus. Logeintrag kommt trotzdem.
Hallo kpwg
Ich hole den Faden noch mal aus der Gruft. Wie hast Du denn die Sache nun gelöst? Ich habe auch den DHT22 als ECMDDevice mit folgenden Eigenschaften implementiert:
Internals:
DEF DHT22M 1
IODev AVRNETIO
NAME KL_HumTemp2
NR 176
STATE T: 19.4 H: 54.0
TYPE ECMDDevice
Readings:
2014-10-23 21:24:07 DHT T: 19.4 H: 54.0
2014-10-23 21:24:07 state DHT T: 19.4 H: 54.0
Fhem:
classname DHT22M
Cache:
Specials:
%NAME KL_HumTemp2
%TYPE ECMDDevice
%devID 1
Params:
devID 1
Attributes:
IODev AVRNETIO
alias KL_DHT_Keller
room Interfaces
stateFormat {ReadingsVal("KL_HumTemp2", "DHT", 0)}
verbose 0
Darauf reagiert dewpoint mit
... dewpoint .* D H T
leider nicht.
Gruß
Gernot
Hallo Gernot,
sehr gerne, weil ich denke, das dieses Thema noch nicht ganz "durch" ist- auch hier sind noch Fragen.
Zuerst nochmals meine aktuell eingesetzte (und verbesserungswürdige) classdef:
# Uebergabeparameter DHT22 ID 0...n
params devID
# Umsetzung in ECMD Befehle fuer DHT22
get DHT cmd {"dht temp %devID\n\000dht humid %devID\n"}
get DHT expect "\d+.\d\n"
get DHT postproc {\
s/(.*)\n(.*)\n/T: $1 H: $2/; $_;\
my $hash = $defs{%NAME};\
my $temperature = $1;\
my $humidity = $2;\
my $state = $_;\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "humidity", $humidity, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
Damit läuft es zumindest schon mal zuverlässig, verursacht aber noch immer bei jeder Messung ein
2014.10.24 16:16:24 1: PERL WARNING: Useless use of a variable in void context at (eval 182446) line 1.
. Hier hilft weder Neustart noch was anderes. Ich kann daher nur Verbose auf Null setzen- auch keine Lösung. :-\
Weiterhin definiere ich den Taupunkt mit
define dew_all dewpoint dewpoint .* temperature humidity dewpoint
attr dew_all absFeuchte 1
und nutze das modifizierte Dewpoint-Modul aus dem Thread: http://forum.fhem.de/index.php/topic,21458.0.html (http://forum.fhem.de/index.php/topic,21458.0.html). Mit T: und H: arbeite ich nicht; nur mit temperature und humidity systemweit einheitlich. Damit erhalte ich dann aus allen Sensoren mit passenden readings die absFeuchte und den Taupunkt.
Versuch's mal.
Viele Grüße, Ricardo