Hallöchen,
ich habe nun nach mehreren Stunden, an mehreren Tagen keine Lösung gefunden, weil ich grundlegende Dinge nicht verstehe.
Mir ist bewusst, dass ich mir das bestimmt irgendwie selbst beibringen könnte, wenn ich bei 0 anfange (und mir das bisherige nicht zusammenkopiert hätte). Das Problem ist nur, eigentlich liegt die Lösung schon vor mir. Wenn man bis knapp unter den Gipfel geflogen wurde, dann aber auf den letzten 10m den Weg nicht findet, ist die Motivation wieder komplett von unten hochzuklettern eher gering...
Die sub in der myUtils.pm werde ich nie verstehen, das wird auch nie mein Ansrpuch sein, wie ich die sub aufrufe und die Ergebnisse würde ich gerne verstehen.
Kurz: ich hab mir diese readingsgroup hier kopiert:
https://wiki.fhem.de/wiki/FTUI_Widget_Readingsgroup (https://wiki.fhem.de/wiki/FTUI_Widget_Readingsgroup)
Ich würde gerne die Ergebinsse, also die Zeit des letzten Updates ohne das widget "Readingsgroup" in FTUI integrieren, also einzeln auf die Updatezeiten zugreifen können.
Wie bekomme ich die Ergebnisse der sub in userreadings, damit ich diese via Label in FTUI integrieren kann? Der Aufruf bzw. die Übergabe funktionieren nicht.
Habe in einem dummy folgendes userreading erstellt:
Clara_Update {getTimeDiffDesc(getNewestTimestamp("DHT_Clara", "temperature","humidity" ) )}
und Variationen davon versucht.
Die DHT-Geräte heißten z.B. DHT_Clara oder DHT_SZ oder DHT_Garten (Internetchno, Werte werden so alle 20Sek aktualisiert)
Vielen Dank für eure Hilfe
Jonathan
Hallo
Das Wiki kennst Du? -> https://wiki.fhem.de/wiki/99_myUtils_anlegen
Hab sogar ich soweit verstanden dass ich es nutzen kann.
Sprich hier kann man eingenen Code unterbringen der dann in FHEM z.B. aus Notify's, DOIF's etc. heraus aufgerufen werden kann. In deinem Beispiel passiert das auch im Code für die Readingsgroup sub getTimeDiffDesc & sub getNewestTimestamp
Beliebt ist z.B. die Möglichkeit Mails versenden zu können oder MAC-Adressen auf der FritzBox zwecks Anwesenheit abzufragen.
##############################################
# $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;
use Blocking;
sub
myUtils_Initialize($$)
{
my ($hash) = @_;
}
# Enter you functions below _this_ line.
############
#Netzwerk Gerät über Fritzbox abfragen
#
sub MACDa($){
my $n = 0;
my ($Reading) = @_;
$Reading =~ tr/:/_/;
my @fbs = devspec2array("NAME=Fritzbox");
foreach( @fbs ) {
my $Name = ReadingsVal($_,"mac_" . $Reading,"");
if( ($Name ne "") && ($Name ne "inactive") ) {
$n++;
}
}
if( $n == 0) {
return 0;
} else {
return 1;
}
}
############
## DebianMail Mail auf dem RPi versenden #######
#
sub DebianMail {
# auch hier werden beim Aufruf 4 Parameter übergeben: {DebianMail('%DEVICE%','%TITLE%','%MSG%',"")}, auch wenn hier keine () hinter sub DebianMail steht
my ($rcpt, $subject, $text, $attach) = @_ ;
my ($sender, $konto, $passwrd, $provider) = ("fhem\@provider.de","fhem\@provider.de","xyzPASSWORD","mail.provider.de:587") ;
my $ret = "";
Log 4, "sendEmail RCP: $rcpt";
Log 4, "sendEmail Subject: $subject";
Log 4, "sendEmail Text: $text";
Log 4, "sendEmail Anhang: $attach";
$ret .= qx(sendEmail -f '$sender' -t '$rcpt' -u '$subject' -m '$text' -a '$attach' -s '$provider' -xu '$konto' -xp '$passwrd' -o tls=yes -o message-charset=utf-8 );
$ret =~ s,[\r\n]*,,g; # remove CR from return-string
Log 3, "sendEmail Subroutine returned: $ret";
}
#############
1;
In FHEM kannst Du dann einfach "DebianMail" oder "MACDa" aufrufen oder eben "getTimeDiffDesc" bzw. "getNewestTimestamp".
Readingsgroups hab ich mich noch nicht mit beschäftigt und kann daher nicht sagen wie man die Parameter setzt. Die beiden Sub's dienen zur Ermittlung von irgendwelchen Zeitstrings.
Zitat von: joschre am 17 April 2023, 21:53:01Wenn man bis knapp unter den Gipfel geflogen wurde, dann aber auf den letzten 10m den Weg nicht findet, ist die Motivation wieder komplett von unten hochzuklettern eher gering...
Du wurdest aber nicht bis knapp unter den Gipfel geflogen, sondern Du warst mit Deiner unverstandenen Kopiererei eher als Schwarzfahrer oder als "blinder Passagier" unterwegs. Und was man früher mit blinden Passagieren gemacht hat, wirst Du ja wohl wissen...
Was Du tun möchtest, solltest Du gedanklich so weit abstrahieren, bis Dir selbst klar wird, was Du eigentlich tun willst. Das Ergebnis dieser Überlegungen ist an sich ganz simpel: Du möchtest das Alter eines (oder mehrerer) readings in einer von Menschen einfach lesbaren Form ermitteln.
Verabschiede Dich von dem Code, der für die readingsGroup gebraucht wird, der wird Dir nicht weiterhelfen.
Außerdem ist der Code im Wiki einfach nur haarsträubend schlecht.
Was Du brauchst:
1. Ermittlung des Alters eines readings - nichts leichter als das!ReadingsAge('deviceName','readingName',0)
Die Werte für deviceName und readingName musst Du natürlich korrekt eintragen.
2. Eine einfache (!) Funktion, die aus dem Alter einen sinnvollen "Text" produziert.sub ageText {
my $age = shift;
return "???" if ($age < 0);
return "<1m" if ($age < MINUTESECONDS);
return sprintf("%2dm",round($age/MINUTESECONDS,0)) if ($age < HOURSECONDS);
return sprintf("%2dh",round($age/HOURSECONDS,0)) if ($age < DAYSECONDS);
return sprintf("%2dd",round($age/DAYSECONDS,0)) if ($age >= DAYSECONDS);
}
Wenn Du diese Funktion in die 99_myUtils.pm packst, kannst Du schonmal testen:
{ageText -1}
{ageText 20}
{ageText 200}
{ageText 2000}
{ageText 20000}
{ageText 200000}
Die Zeilen kannst Du jeweils einzeln in die FHEM-Befehlszeile eingeben und sehen, was als Ergebnis kommt.
3. Die Kombination aus 1+2 in Deinem userreadingClara_Update_temp:DHT_Clara.* { ageText(ReadingsAge("DHT_Clara", "temperature",-1)) }
Zitat von: RalfRog am 17 April 2023, 22:21:44Das Wiki kennst Du? -> https://wiki.fhem.de/wiki/99_myUtils_anlegen
Hab sogar ich soweit verstanden dass ich es nutzen kann.
...
Readingsgroups hab ich mich noch nicht mit beschäftigt und kann daher nicht sagen wie man die Parameter setzt.
Hier geht es überhaupt nicht um readingsGroup...
Und vielleicht noch ein kleiner Hinweis: Es macht überhaupt keinen Sinn, alle 20 Sekunden einen Temperatursensor abzufragen - so schnell ändert sich das nicht.
LG
pah
@betateilchen:
Das mit dem Schwarzfahrer ist wohl eine gute Ergänzung :-)
Ich denke auch, dass der Code im Wiki zu kompliziert ist.
Danke für deine kurze Funktion, die kann sogar ich nachvollziehen und das macht das lernen deutlich einfacher.
Es gibt nur noch ein Problem. Nutze ich den Trigger im Beispiel Clara_Update_temp:DHT_Clara.* {Befehl...)
wird das Reading immer dann aktuallisiert, sobald es von DHT_Clara ein neues Event gibt. Damit ist die Zeit des letzten Readings immer "<1m".
Werden dann die nächsten Daten erst 2 Tage später empfangen steht bis dahin immer noch "<1m" in Clara_Update_temp und sobald die neuen Daten kommen steht wieder "<1m" im Reading.
Der Trigger für das userreading müsste z.B. auf alle 10Min oder jede Stunde gesetzt werden und nicht in Abhängigkeit des eigenen Datenempfangs.
Gebe ich gar keinen Trigger an, wird das Reading "Clara_Update_temp" gar nicht aktualisiert. Ich habe noch nicht verstanden, wann der Befehl des userreadings ausgeführt wird, sobald kein Trigger gesetzt ist.
Das ist beim Readingsgroup-Beispiel-Code auf jeden Fall anders, ich habe aber noch nicht herausgefunden in welchem Intervall dort das Alter der Readings gecheckt werden.
@Peter Henning: Die Sensoren senden alle paar Sekunden ihre neuen Werte, Events werden frühestens nur alle 15 Minuten zugelassen. Wollte damit nur sagen, dass die Werte sehr oft empfangen und aktualisiert werden.
Ich versuche mich jetzt zu informieren, wie ich das mit dem Trigger alle 20Min richtig hinbekomme.
VIELEN Dank schonmal für die Hilfe!
Zitat von: joschre am 19 April 2023, 09:31:19Der Trigger für das userreading müsste z.B. auf alle 10Min oder jede Stunde gesetzt werden und nicht in Abhängigkeit des eigenen Datenempfangs.
Gebe ich gar keinen Trigger an, wird das Reading "Clara_Update_temp" gar nicht aktualisiert. Ich habe noch nicht verstanden, wann der Befehl des userreadings ausgeführt wird, sobald kein Trigger gesetzt ist.
Der zweite Teil Deiner Frage ist einfach zu beantworten:
Wenn es keinen Trigger gibt, wird auch kein userreading erzeugt.
Zum ersten Teil:
Du kannst den Trigger auf das konkrete reading erweitern
Clara_Update_temp:DHT_Clara:temperature.* { ageText(ReadingsAge("DHT_Clara", "temperature",-1)) }
Dann wird das userReading zum Alter nur erzeugt, wenn das zugehörige reading temperature aktualisiert wird.
Wenn Du komplett zeitgesteuert die Alterstexte in bestimmten Intervallen erzeugen möchtest, solltest Du nicht mit userReading arbeiten, sondern ein at verwenden, das die zusötzlichen readings erzeugt. Dazu müsste man die Funktion in der 99_myUtils.pm etwas umbauen, aber der Aufwand hält sich in Grenzen.
sub ageText {
my ($device,$reading) = @_;
my $age = ReadingsAge($device,$reading,-1);
sub _getText {
my $age = shift;
return "???" if ($age < 0);
return "<1m" if ($age < MINUTESECONDS);
return sprintf("%2dm",round($age/MINUTESECONDS,0)) if ($age < HOURSECONDS);
return sprintf("%2dh",round($age/HOURSECONDS,0)) if ($age < DAYSECONDS);
return sprintf("%2dd",round($age/DAYSECONDS,0)) if ($age >= DAYSECONDS);
}
fhem("setreading $device $reading"."_update "._getText($age));
}
Dann kannst Du (manuell) in der FHEM Befehlszeile testen mit
{ageText("DHT_Clara","temperature")}
und Dir das dadurch entstandene neue reading "temperature_update" anschauen.
Den Aufruf würde man dann in ein at (z.B. für alle 10 Minuten) packen:
define at_ageText at +*00:10:00 {ageText("DHT_Clara","temperature")}
(im gleichen at kann man natürlich auch noch die Aktualisierung weiterer readings unterbringen)