Hallo zs,
ich habe angefangen mich mit FHEM zu beschäftigen und habe auch schon einige gute tipps aus dem Forum bekommen und konnte bisher meine Anfängerfragen so beantworten.
Nun komme ich aber bei einem Thema nicht weiter:
Ich habe einen Stromzähler mit S0 Ausgang den ich per IP-Switch auslese und an mein FHEM verarbeiten will.
Dazu habe ich folgendes in der Config definiert:
#-----Verbrauch--------------------------------
define KWH_aktuell_i dummy
attr KWH_aktuell_i room Wärmepumpe
define KWH_Gesamt_i dummy
attr KWH_Gesamt_i room Wärmepumpe
#------zum Testen------------------------------
define KWH_Time_i dummy
attr KWH_Time_i room Wärmepumpe
define IPs_IB dummy
#attr IPs_IB room Wärmepumpe
define act_Waermepumpe at +*00:00:10 set
{\
my $time= Value("KWH_Time_i");;\
my $ges= Value("KWH_Gesamt_i");;\
my $akt= Value("KWH_aktuell_i ");;\
my $dat= sprintf("%.1f %.1f %.1f",$time, $ges,$akt);;\
fhem ("set IPs_IB $dat");;\
}
define FileLog_IPs_IB FileLog /home/pi/tmp/IPs_IB__-telnet.txt IPs_IB
attr FileLog_IPs_IB logtype text
define SVG_FileLog_IPs_IB SVG FileLog_IPs_IB:SVG_FileLog_IPs_IB:CURRENT
attr SVG_FileLog_IPs_IB room Wärmepumpe
Dazu habe ich mir eine Utils-Datei erzeugt:
sub IPs_IB__($)
{
my ($st) = @_;
my @sta = split(',', $st);
{fhem ("set KWH_Time_i ".$sta[0])};
{fhem ("set KWH_Gesamt_i ".$sta[6])};
{fhem ("set KWH_aktuell_i ".$sta[7])};
}
soweit klappt alles, wenn ich auf meinem Menüpunkt gehe, erscheinen die aktuellen Werte in meinen Variablen.
So nun will ich den aktuellen Wert in einem Diagramm darstellen:
# Created by FHEM/98_SVG.pm, 2020-05-24 22:26:08
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
set ylabel "Humidity"
set y2label "Leistung"
#FileLog_IPs_IB 7:IPs_IB.*::
plot "<IN>" using 1:2 axes x1y2 title 'KWH' ls l0 lw 1 with lines
Ich kann in der Oberfläche die Spalte nicht auswählen, es wird immer nur 3 und 4 angezeigt. Meiner Meinung nach
habe ich einen Fehler bei der zuweisen des Dateiinhalts an die SVG, aber ich finde den Fehler nicht.
Hat jemand einen Tip für mich?
Vielen Dank
Hmm, also irgendwie kommt mir das etwas "von hinten durch die Brust..." vor.
Mir ist z.B. völlig schleierhaft, wo die Daten überhaupt herkommen ("list <device>" der Datenquelle fehlt, oder?). Dann ist mir völlig unklar, warum du nicht einfach userReadings an diesem Device nimmst, um die Elemente zu splitten und als Readings dort abzulegen, wo sie hingehören, statt das ganze erst auf viele dummy-Devices zu verstreuen, um es hinterher wieder irgendwie zusammenzubasteln?
(Der winzige Schnipsel, den man von der eigentlichen file sieht, die du auswerten willst, deutet eher darauf hin, dass da auch "komische" Sachen drinstehen).
Dann: Der Plot-Editor ist mMn. irgendwie suboptimal bzw. nur zur Prüfung zu gebrauchen, ob die Daten richtig ausgewertet wurden und ggf. plotReplace-Argumente passend gesetzt sind (siehe dazu auch "SVG" im Wiki, da sind zwar nur zwei Beispiele drin, die aber mMn. die Möglichkeiten sehr gut erkennen lassen).
Für diese ganzen statistischen Sachen gibt es dann auch noch die ".*-Calculator"-Module, und (v.a.) statistics. Damit kann man mMn. solche Aufgaben etwas standardisierter und generischer lösen.
Und zu guter Letzt: stop editing fhem.cfg... "list" ist das Schlüsselwort, siehe angepinnte Beiträge hier.
Hallo Beta-User,
ich habe mir das von dem Hersteller des S0-Datenloggers geklaut und nur etwas angepasst.
Die Daten werden aktuell durch den Datenlogger in einer Text-File im /tmp/IPs_IB__-telnet.txt abgelegt
von dort will ich Sie auslesen,speichern und auswerten. Die Dummy-Variablen habe ich mir eingesetzt ob überhaupt Werte verarbeitet werden von meiner Utils.
Das ich das richtig verstehe, ich definiere doch hier die Datenquelle:
define FileLog_IPs_IB FileLog /home/pi/tmp/IPs_IB__-telnet.txt IPs_IB
attr FileLog_IPs_IB logtype text
und übergebe das dann an das Diagramm:
define SVG_FileLog_IPs_IB SVG FileLog_IPs_IB:SVG_FileLog_IPs_IB:CURRENT
attr SVG_FileLog_IPs_IB room Wärmepumpe
oder ist mein Ansatz völlig falsch?
Völlig falsch vielleicht nicht...
...aber eigenartig ;)
Ok, die dummy sind nur "Hilfskonstrukt" für dich zum Testen!?
Was mir auffällt:
kann fhem die Datei lesen: /home/pi/tmp/IPs_IB__-telnet.txt
Sie liegt im Home des Users pi (gut, lesen kann gehen)...
Da die Daten von "woanders" kommen, brauchst du kein RegEx!
Es sollen ja keine Daten durch fhem geschrieben werden (was verm. eh nicht geht/gehen würde, siehe oben)...
Sondern du musst dann das FileLog readonly definieren:
define FileLog_IPs_IB FileLog /home/pi/tmp/IPs_IB__-telnet.txt readonly
Siehe: https://fhem.de/commandref.html#FileLogdefine
Gruß, Joachim
Na ja, wenn (!) in der file schon alles relevante steht, kannst du auch direkt auswerten. Aber die eine Zeile auf dem Screenshot (Bilder sind eigentlich sch...), beginnend mit einer "{" dürfte schon Schwierigkeiten machen...
(@MadMax-FHEM: diese eine Zeile deutet darauf hin, dass man z.B. kein "FHEM-konformes" Datum hat; kann aber natürlich sein, dass das trotzdem irgendwie geht...? Es scheint jedenfalls auch was geschrieben worden zu sein...?) (Vielleicht mag uns der TE ein längeres Schnippselchen ohne die Modifikationen zeigen?)
Ich habe auch nicht die große Erfahrung mit dem Auswerten von Daten, die "irgendwo" liegen, aber grundsätzlich würde ich Ausgangsdaten und Logfile (=> SVG) trennen; da scheinst du bisher dieselbe (endlose!) file zu nutzen. Für SVG+FileLog sind kurze Files besser (v.a. schneller), also lieber Wochen- oder Monatsweise anlegen (und "gluedfiles" (?) nutzen). Diese "Einheitsfile" legt auch nahe, dass das "Erstellungsgerät" die auch wieder löscht/überschreibt.
Stichwort zur Reaktion von Schreibaktivitäten auf der Disk: inotify
Wenn es strikt periodisch sein soll, wäre ein Blick auf CustomReadings vielleicht hilfreich.
Geht beides aber nur unter Linux.
Bei einer inotify-Lösung würde ich alle Readings via "setreading" in ein dummy-Device schreiben und darauf dann "ganz normal" ein FileLog-Device ansetzen, das die Werte wegschreibt (letzteres dto. für CustomReadings, nur dass man da keinen dummy braucht).
also die Datendatei wird bei jedem neuem Datensatz überschrieben und sieht wie folgt aus:
{ IPs_IB__("2020.05.25_10:27:45,192.168.66.160,IPs_IB__,m3-11e,IPs_IB__,500291B044E7,11498,4,1,0,0,3.16,-79,37665,1590402466,________________________________________________________________________________________________________________________________________________________________________, ") }1
Auch das ist nur ein Hilfsmittel, die Daten werden vom Datenlogger per UDP an meinen Rasb gesendet, vom Hersteller des Datenloggers gibt es ein Tool das die Daten in eine Datei umlenkt. Und die versuche ich nun auszuwerten. Warum gehe ich diesen Weg: ich will mehr als nur 1 Stromzähler auswerten.
https://www.sms-guard.org/downloads/App-IPswitch-E-WiFi-S0-FHEM/index.htm (https://www.sms-guard.org/downloads/App-IPswitch-E-WiFi-S0-FHEM/index.htm)
das ist die Anleitung an die ich mich gehalten hatte:
Zitat
./ipsfs /tmp/ -T -i >> /dev/null 2>&1 &
so werden die udp-Telegramme in das RAM-Disk-Verzeichnis /tmp/ als Textfile geschrieben mit dem
Namen des IPswitch (hier LAGERi__), z.B.
/tmp/LAGERi__-telnet.txt
und kann angesehen werden mit:
cat /tmp/LAGERi__-telnet.txt
{ LAGERi__("2019.02.08_14:42:30,192.168.1.96,LAGERi__,m3-
23b,LAGERi__,68C63AABC148,24.7,29.5,24.5,24.6,0,1,0,0,0,1,1,0,0,0,0,0,3.11,52947,1549636950,0,_______________
________________________________________________________________________________________________
_____________________________, ") }
quit
Es wird eine Telnet Variable (zwischen den Anführungszeichen) an FHEM (getestet mit 5.8 und 5.9)
übergeben. Der Aufbau des csv-Strings ergibt sich weitestgehend aus dem Aufbau der csv.html des
IPswitch. Der csv-String ist in FHEM zu zerlegen im Perl-Modul 99_Utils.pm mit einer sub Lageri__ (Anzahl
der _ beachten):
################################################Start ./ipsfs /tmp/ -T -i >> /dev/null 2>&1 &
sub LAGERi__($) {
my ($st) = @_;
my @sta = split(',', $st);
{fhem ("set LAGERi_t ".$sta[0])};
{fhem ("set LAGERi_Ti ".$sta[6])};
{fhem ("set LAGERi_rLFi ".$sta[7])};
{fhem ("set LAGERi_Ta ".$sta[8])};
{fhem ("set LAGERi_rLFa ".$sta[9])};
}
################################################Ende ipsfs
Jetzt kennt das FHEM die Variablen, sofern diese vorher in der fhem.cfg definiert wurden:
#-----LAGERi mit Grafik--------------------------------
define LAGERi_t dummy
attr LAGERi_t room RaPi
define LAGERi_Ti dummy
attr LAGERi_Ti room RaPi
define LAGERi_rLFi dummy
attr LAGERi_rLFi room RaPi
define LAGERi_Ta dummy
attr LAGERi_Ta room RaPi
define LAGERi_rLFa dummy
attr LAGERi_rLFa room RaPi
define LAGERi dummy
#attr LAGERi room RaPi
define act_LAGERi at +*00:05:00 {\
my $Ti= Value("LAGERi_Ti");;\
my $rLFi= Value("LAGERi_rLFi");;\
my $Ta= Value("LAGERi_Ta");;\
my $rLFa= Value("LAGERi_rLFa");;\
my $dat= sprintf("%.1f %.1f %.1f %.1f",$Ti,$rLFi,$Ta,$rLFa);;\
fhem ("set LAGERi $dat");;\
}
define FileLog_LAGERi FileLog ./log/log-LAGERi.log LAGERi
attr FileLog_LAGERi logtype text
define SVG_FileLog_LAGERi SVG FileLog_LAGERi:SVG_FileLog_LAGERi:CURRENT
attr SVG_FileLog_LAGERi room RaPi
#Ende
@Beta-User mehr habe ich aktuell nicht verändert, mein Fhem ist fast "jungfreulich"
Hmmm...
Also gut.
Ich würde das hier:
Zitat
sub LAGERi__($) {
my ($st) = @_;
my @sta = split(',', $st);
{fhem ("set LAGERi_t ".$sta[0])};
{fhem ("set LAGERi_Ti ".$sta[6])};
{fhem ("set LAGERi_rLFi ".$sta[7])};
{fhem ("set LAGERi_Ta ".$sta[8])};
{fhem ("set LAGERi_rLFa ".$sta[9])};
}
Umbauen auf setreading, also in etwa so:
sub LAGERi__($) {
my ($st) = @_;
my @sta = split(',', $st);
{fhem ("setreading LAGERi MeinGewünschterReadingNameHierfür ".$sta[0])};
{fhem ("setreading LAGERi MeinGewünschterReadingNameHierfür ".$sta[6])};
{fhem ("setreading LAGERi MeinGewünschterReadingNameHierfür ".$sta[7])};
{fhem ("setreading LAGERi MeinGewünschterReadingNameHierfür ".$sta[8])};
{fhem ("setreading LAGERi MeinGewünschterReadingNameHierfür ".$sta[9])};
}
Dann stehen alle Werte in EINEM dummy (LAGERi) als verschiedene Readings (deren Name du ja jeweils festlegen kannst).
Den Rest brauchst du dann nicht mehr und auch nicht die ganzen dummy, also bis auf den einen nat. LAGERi (und das sind keine "Variablen" ;) )...
Dann ein Filelog:
define FileLog_LAGERi FileLog ./log/log-LAGERi.log LAGERi:(Name1|Name2|Name3|Name4).*
Das .* hängt halt davon ab was da so kommt...
...schadet aber vermutlich nicht.
Darauf lassen sich dann eigentlich einfach pro geloggtes Reading auch einzelne Grafen-Linien etc. machen.
Und wie bereits von Beta-User vorgeschlagen würde ich "kürzere" Logs machen, also beim Define vom FileLog Tages/Monats etc. Logs...
Gruß, Joachim
Hat sich überschnitten... Würde aber die Schwerpunkte/das Vorgehen nochmal in Teilen anders legen/machen...
Der inotify-Weg sollte eigentlich passen (statt des at), weiß aber nicht, ob das mit einer Ramdisk (?) auch klappt.
Insgesamt ist die verlinkte Lösung imo irgendwie "verbogen" (u.a. deswegen ist sie auch "irgendwo" zu finden, und nicht im Wiki, und deine Modifikationen machen es nicht besser (der Zielfile-Name des FileLog paßt nicht).
Heute würde man m.E. besser diesen "service" (http://www.sms-guard.org/downloads/ipsfs-raspi.zip (http://www.sms-guard.org/downloads/ipsfs-raspi.zip)) so gestalten, dass er nicht telnet nutzt (tut er das überhaupt?), sondern MQTT, und der Inhalt der File sieht auch anders aus als bei dir, warum auch immer...
Würde also vorschlagen, du machst als erstes mal die Modifikationen auf der FHEM-Seite raus und wir schauen uns dann inotify näher an. Wenn die Datei im Ausgangszustand noch so aussieht wie in der Anleitung, braucht man sie eigentlich nur einzulesen und dann zeilenweise auszuführen. Das wäre nicht besonders schwer, und telnet (warum steht das in der Anleitung?) braucht man auch nicht...
Aber erst mal brauchen wir eine "intakte" Ausgangsfile.
okay hab jetzt wieder ein jungfreuliches System, alle Änderung sind raus. Alle Log-Dateien sind gelöscht, ipsfs gelöscht.
Dann würde ich mich als erstes mit MQTT auseinandersetzen und mich mit dieser Anleitung beschäftigen???:
https://smarthome-blogger.de/tutorial/mqtt-raspberry-pi-einfuehrung/
(https://smarthome-blogger.de/tutorial/mqtt-raspberry-pi-einfuehrung/)
Hmmm, also......:
MQTT ist ein Thema für sich, und MQTT@FHEM sind nochmal zwei spezielle Themen...
Vermutlich ist es ein einfacherer Start, wenn du von Otto123 hier abkupferst: https://heinz-otto.blogspot.com/2019/11/mqtt-ich-muss-das-testen.html (https://heinz-otto.blogspot.com/2019/11/mqtt-ich-muss-das-testen.html). Aber eigentlich kann man das kaum verstehen, wenn man nicht schonmal irgendeine Hardware in der Hand hatte, die "ordentlich" MQTT spricht und dann eines der Beispiele in den "Praxisbeispielen" durch hat (https://wiki.fhem.de/wiki/MQTT2-Module_-_Praxisbeispiele (https://wiki.fhem.de/wiki/MQTT2-Module_-_Praxisbeispiele)).
(Dass ich hier überhaupt mal ausnahmsweise nach außerhalb der FHEM-Doku verlinke hat damit zu tun, dass wir bisher wenige Fälle hatten, wo das nicht "mit Bordmitteln" zu lösen gewesen wäre. Hier ist vermutlich die inotify-Lösung einfacher, aber dazu würden wir input benötigen (=die "jungfräuliche" file).)
EDIT: unbedingt eine Client-ID angeben bei Versuchen, irgendwas an MQTT2_SERVER zu publishen; der weist das sonst eventuell ab, insbesondere, wenn mosquitto_sub verwendet wird!
okay dann backen wir mal kleine Brötchen :)
ich habe die IPsfs runtergeladen und mit
/home/pi/ipsfs /tmp/ -t &
gestartet, es wurde 2 Dateien erzeugt, eine Datei ist leer in der 2. Datei ist im Anhang
OK, dann würde ich mal vorschlagen, wir machen _einen_ dummy, in den wir dann die Werte schreiben, die wir wirklich haben wollen, ein inotiy und dann mal etwas Perl-Code...
defmod IPs_IB dummy
defmod int_IPs_IB inotify /tmp IPs160IPs_IB__-telnet.txt
Dann setzt du mal ein notify auf das inotify an (das erzeugt der Doku nach nur die Info, dass ein update vorliegt und an welcher Datei) und schreibst den Dateinamen in den dummy. Nutze dazu den Event-Monitor.
Später können wir dann den notify-Code aufbohren und einige setreading-Anweisungen auf den dummy aus der file selbst (modifiziert) ableiten.
Bekommst du das hin?
Mal ganz davon ab: Schon mal das Stichwort "Arducounter" gehört? Gibt es auch in Wifi-Form und kann S0-Pulse zählen, auch mehrere...
mhh steh da ein bissel auf dem Schlauch :o
ich habe das Inotify-tools über apt-get installiert, müssen die defmod-Befehle als Script in mein Utils-Datei ?
Sorry für die blöden Fragen
...ja ja, Anfängerdoku nicht gelesen...
defmod ist ein "anderes" define, das gehört schlicht in die (erweiterte) Kommandozeile (erweitert= "grünes +").
Hab's noch etwas aufgebohrt:
defmod IPs_IB dummy
attr IPs_IB readingList r00 r01 r02 r03 r04 r05 r06 r07 r08 r09 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20
Dann brauchst du "etwas Perl" in einer myUtils, siehe Anhang ;) .
Der Aufruf wäre dann:
{mySet_IPsfs_dummyvalues("/tmp/IPs160IPs_IB__-telnet.txt", "IPs_IB")}
Kannst du nach Definition des Dummy's auch erst mal in die Kommandozeile werfen, dann den Dummy ansehen (braucht uU. einen Browser-refresh).
Dann solltest du ggf. die files in der ZIP mal durchforsten, ob da irgendwo noch versucht wird, was an FHEM via telnet zu senden. Das dann deaktivieren (bzw. später als Basis für MQTT-Commands nehmen...).
Sorry, Brett vorm Kopf gehabt,
So, sieht doch gut aus, oder?
Sobald du also via inotify+notify den Code ausführst, bekommst du neue Readings in den Dummy.
Hast du mehrere von den Geräten, machen die ja jeweils eine eigene file, oder? Dann kannst du filename und Dummy-Name entsprechend ändern, eventuell muß dann der Code noch an einer Stelle angepaßt werden, weil vermutlich dann auch der Dienst eine andere Bezeichnung verwendet:
my @setData = grep {
$_ =~ s/\A(setreading)[\s]+[^\s]+([0-9]+)[\s]+state[\s]+(.*)\z/$name r$2 $3/gx #reformat everything starting by setreading line by line
} @dataAll;
Jetzt brauchst du "nur noch" ein passendes FileLog-Gerät bauen, dass dann die Readings daraus loggt, die du eigentlich dann in dem Plot haben willst. Ist der Weg damit vollends halbwegs erkennbar? (Man könnte bestimmt auch direkt einen Log wegschreiben, aber das ist mir jetzt auch grade zu viel...)
Edit: Kleiner Fund noch zu inotfy+notify: https://forum.fhem.de/index.php/topic,83538.msg760260.html#msg760260
Vielen Dank, ich teste das heute Abend dann nochmal und melde mich dann mit hoffentlich Erfolgsnachricht ;-)
Hallo Beta-User,
kleines Update, ich habe festgestellt das mir doch erheblich viel Hintergrundwissen fehlt und werde mich erst einmal mit den grundlegenden Tutorials beschäftigen und dann erst mit dem Thema weitermachen.
Ich melde mich sobald ich da weitermachen kann.
Kein Ding.
Mir ging es vor allem auch drum klarzumachen, dass dieses "Tutorial" Mist ist, jedenfalls was den FHEM-Teil angeht (und auch die Vorverarbeitung der Daten ist imo irgendwie "komisch"; ich bin aber kein Experte, wie man sowas "gut" löst und habe daher per myUtils einfach verworfen, was offensichtlicher Datenmüll war).