Kilowatt
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Hallo. Wie kann ich die Werte aus jeder Spalte (sind 21 Spalten) in die Variablen schreiben ? Beim versuch die Spalten aus der Logdatei zu lesen, wird die ganze Spalte mit tausenden einträten ausgelesen, ich brauche nur den aktuellen Wert.
| cat /dev/ttyUSB0 | awk '{ print $1" "$2" "$3" "$4 "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15" "$16" "$17" "$18" "$19" "$20" }'
|
Habe mal dann so versucht: Mit diesem Script lese ich die Log Daten aus dem Regler aus:
| #!/bin/sh
stty -F /dev/ttyUSB0 19200 # Baudratte auf 19200 setzen, sonnst habe ich nach jedem Reboot keine Kommunikation da auf Defaultwert zurückgesetzt wird.
sed '/Typ/,/Messzeit/d' /dev/ttyUSB0 | while read line; do # Die Eingangsdaten werden geprüft, die Zeilen ohne Messzeit werden nicht weitergeleitet.
if [ -n "${line}" ]; then # sobald die Daten aus dem Regler bereitstehen, darf die Datum+Daten in die Logdatei geschrieben werden.
echo "$(date '+%d.%m.%Y') $line" # Am Anfang der Zeile aktuelle Datum und danach die empfangene Daten in die rec.log schreiben.
sed -i '$d' aktuell.txt # alte Daten in der Datei aktuell.txt werden gelöscht
echo "${line}" >> aktuell.txt # aktuelle Istwerte werden in die Datei aktuell.txt geschrieben.
# klappt eigentlich ganz gut, und man hat immer den letzten Stand in der Datei (nur eine zeile), nur die SD Karte für ständige schreiben/löschen nicht ausgelegt. Darum möchte ich die aktuelle Werte in Variablen schieben.
cat aktuell.txt | awk '{ print $1" "$2" "$3" "$4 "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15" "$16" "$17" "$18" "$19" "$20" }' # aktuelle Wert der Spalten wird gelesen und in die Variablen??? (das ist die Frage!) $1 bis $20 geschrieben ?
fi
done >> /home/pi/rec.log # in die Datei rec.log werden zeilenweise Datum + Daten geschrieben. Besser wäre, wenn die neue Daten oben in die Datei eingefügt werden, dann muss ich nicht tausende Zeilen nach unten scrollen. Weiß jemand wie das geht?
|
So sehen die Zeilen in der Logdatei rec.log aus:
06.12.2017 22:51:59 030,0 033,9 028,7 017,5 003,8 003,2 053,2 033,0 007,2 000 050 099 035 111 079315319 000943235 3,8 00210 06650
06.12.2017 22:52:09 030,0 033,9 028,7 017,5 003,7 003,1 053,3 033,0 007,2 050 050 099 035 111 079315334 000943240 3,9 00210 06900
06.12.2017 22:52:19 030,0 033,9 028,7 017,5 003,7 003,1 053,2 033,0 007,2 050 050 099 035 111 079315354 000943245 3,9 00210 06650
06.12.2017 22:52:29 030,0 033,9 028,7 017,5 003,7 003,1 053,2 033,0 007,2 050 050 099 035 111 079315369 000943250 3,9 00212 06900
06.12.2017 22:52:39 030,0 033,9 028,7 017,5 003,7 003,1 053,2 033,0 007,2 050 050 099 035 111 079315389 000943255 3,9 00210 06900
06.12.2017 22:52:49 030,0 034,0 028,7 017,5 003,7 003,1 053,2 033,0 007,2 050 050 099 035 111 079315404 000943260 4,0 00210 06900
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11229
Wohnort: München
|
Hallo, mir ist nicht ganz klar, was du da genau erreichen willst - wenn es nur darum geht sich die letzte Zeile aus einer Datei zu holen, kann man tail nutzen, wenn man die Reihenfolge von Zeilen in einer Datei umdrehen will tac. Wenn ich das richtig verstehe willst du einfach nur die zuletzt gelesene nicht-leere Zeile mit dem aktuellen Datum in eine Datei schreiben - da könnte man das Skript so vereinfachen:
| #!/bin/sh
stty -F /dev/ttyUSB0 19200
sed -u '/Typ/,/Messzeit/d' /dev/ttyUSB0 | while read line; do
[ -z "${line}" ] && continue
echo "$(date '+%d.%m.%Y') $line"
done >> /home/pi/rec.log
|
Dann stand in den Kommentaren noch, dass du Bedenken wegen der Schreibzyklen der SD-Karte hast - da könnte man z.B. eine RAM-Disk erstellen und darauf schreiben und mit logrotate regelmäßig aufräumen oder (falls dich wirklich nur der letzte gelesene Wert interessiert statt >> einfach > als Umleitung nutzen.
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Die Anlagenwerte werden die ganze Zeit in eine txt Datei geloggt. Siehe Auszug aus der Logdatei oben. Wie kann ich aus der letzten Zeile, (also der jungsten) der Logdatei die einzelne Spaltenwerte in Variablen schreiben
(20 Variablen), z.b. Sollwert, Istwert_Vorlauf, Istwert_Rücklauf, usw.) ?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11229
Wohnort: München
|
Kilowatt schrieb: Wie kann ich aus der letzten Zeile, (also der jungsten) der Logdatei die einzelne Spaltenwerte in Variablen schreiben (20 Variablen, z.b. Sollwert, Istwert_Vorlauf, Istwert_Rücklauf, usw.) ?
Du könntest einen Bash-Array bemühen (die Shell splittet Zeilen auf Wunsch am IFS auf) und die Werte über ihren Index ansprechen:
| read -r -a variables < <(tail -n1 /home/pi/log)
for i in "${!variables[@]}"; do
echo "index: $i value: ${variables[$i]}"
done
|
Alternativ kann man natürlich auch sprechende Namen und einzelne Variablen verwenden:
| read -r datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf var_{6..21} < <(tail -n1 /home/pi/log)
|
Wie kann ich es so drehen, dass die Logdaten von oben nach unten geschrieben werden, damit man die Logdatei mit tausend Zeilen nicht nach unten scrollen muss, sondern der neuste Wert oben steht.
Man kann nichts am Anfang einer Datei einfügen, ohne die komplette Datei neu zu schreiben. Für die Anzeige ist das aber egal - wenn man die Zeilenreihenfolge umdrehen (und in dem Fall mit less betrachten) will:
Oder die letzten 5 Einträge sehen will, wobei der neueste Eintrag zuerst kommt:
tail -n 5 /home/pi/log | tac
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
@sehawk1986 Vielen Dank für die Hilfe, es funktioniert genau so wie ich mir vorgestellt habe! Top! Wie kann ich z.B. jetzt aus der Logdatei $Var_0 (Datum) und $Var_4 (Istwert) die Werte der letzten 7 Zeilen anzeigen um daraus mit X und Y einen Chat zu zeichnen ? Wenn ich jetzt so auslese, "tail -n7" wird mir nur ein Wert angezeigt. Kann man aus dieser Konstellation die Werte der letzten 7 Tagen (also nach Datum sortieren)in die Variablen ausgeben ?
| tail -n 7 /home/pi/log | tac
|
| pi@raspberrypi:~ $ read -r var_{0..20} < <(tail -n7 /home/pi/rec.log)
pi@raspberrypi:~ $ echo $var_0
07.12.2017
pi@raspberrypi:~ $ echo $var_20
12420
pi@raspberrypi:~ $
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11229
Wohnort: München
|
Kilowatt schrieb: Wie kann ich z.B. jetzt aus der Logdatei $Var_0 (Datum) und $Var_4 (Istwert) die Werte der letzten 7 Zeilen anzeigen um daraus mit X und Y einen Chat zu zeichnen ?
Meinst du damit, dass du die Werte einzelner Spalten im Zeitverlauf darstellen willst? Für sowas kann man z.B. gnuplot (Beispiel für ein ähnliches Szenario) oder mathplotlib nutzen. Damit kann man sich die Arbeit sparen selber die Werte als einzelne Variablen aus der Datei zu pulen. Angesichts der eher kleinen zu erwartenden Änderungen bei einem 10-Sekunden Messintervall und 7 Wiederholungen würde ich mir überlegen, ob man da nicht lieber den Verlauf über Stunden oder Tage zeichnen lässt.
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Danke für die Links und dem Tipp die Logdatei rückwärts zu sehen!!! << tac /home/pi/log | less >> Eine Frage hätte ich noch. Wie aktualisiere ich die Daten in Variablen? Kann man es irgendwie mit antreffen des neuen Datensatzes verknüpfen ? Was kann man hier einbauen damit die Variablen automatisch aktualisiert werden ? | #!/bin/sh
stty -F /dev/ttyUSB0 19200
sed -u '/Typ/,/Messzeit/d' /dev/ttyUSB0 | while read line; do
[ -z "${line}" ] && continue
echo "$(date '+%d.%m.%Y') $line"
done >> /home/pi/rec.log
|
| read -r var_{0..20} < <(tail -n1 /home/pi/log)
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Kilowatt schrieb: Die Anlagenwerte werden die ganze Zeit in eine txt Datei geloggt. Siehe Auszug aus der Logdatei oben. Wie kann ich aus der letzten Zeile, (also der jungsten) der Logdatei die einzelne Spaltenwerte in Variablen schreiben
(20 Variablen), z.b. Sollwert, Istwert_Vorlauf, Istwert_Rücklauf, usw.) ?
Dazu hatte ich Dir ja schon in Deinem Vorgängerstrang den Vorschlag gemacht, der Protokolldatei mit | tail --follow /home/pi/rec.log | awk '{print "Vorwort ... und Zahlen:", $9, $10; fflush()}'
|
zu folgen ( = jeweils die neuen Zeilen abzuzweigen, - live ! - so wie sie kommen), und dann die Daten ggf. mit awk zurecht zu formatieren. (Beachte, dass auch awk seinen Buffer hat. - Nur macht awk das anders, dort wird der Buffer auf Kommando ge"flusht") Dort hatte ich ja schon die Vermutung, dass Du eigentlich den Temperaturverlauf (oder welche Zahlenkolonnen auch immer) als Diagramm in einem Fenster anzeigen wolltest. Also vielleicht ± so etwas wie hier beschrieben. (Ok, wenn das Gnuplot-Skript schon sein eigenes Timing mitbringt, brauchst Du vielleicht das tail --follow gar nicht mehr, sondern ein einfaches tail reicht schon ...) Letztendlich willst Du mit den Zahlenwerten ja was konkretes machen, und sie nicht nur blind "in Variablen speichern". Deshalb solltest Du hier vielleicht besser vom Ziel her denken (und programmieren !) ... - kannst Du uns schon verraten, was Du Dir da konkret vorstellst ? LG, track
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Klar, verrate ich sogar sehr gerne. Ich möchte ein Anlagenbild zeichnen und an bestimmten Stellen im Anlagenbild die aktuelle Istwerte anzeigen.T
Dafür brauche ich die Variablen mit aktuellen Werten.–––→ habe zwar bereits mit (tail -n1) gelöst. teste aber heute deine Lösung mit Aktualisierung der
Variablen.
| tail --follow /home/pi/rec.log | awk '{print "Vorwort ... und Zahlen:", $9, $10; fflush()}'
|
Zweitens: Langzeit Datenerfassung. ––→ ist erledigt, die Daten werden bereits alle 10 Sec.(später alle 60 Sec.) in die Logdatei geschrieben. Drittens Auswertung: Diagramme (Charts) von bestimmten Werten z.B. Abhängigkeit der Aussentemp. zu Stromaufnahme und zu COP der Wärmepumpe. Oder Stromverbrauch im Dezember zu Jahuar. Oder Dezember 2017 zu Dezember 2018. ––> Dafür sollen die Daten, so wie die in der Logdatei bereits sind, vollkommen reichen.
Statistiken erstellen-–→ automatisch brerechnen lassen wie hier: http://www.effiziente-waermepumpe.ch/messdaten/statistik.php Es soll ungefähr so was werden:http://www.effiziente-waermepumpe.ch/messdaten/index.php
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11229
Wohnort: München
|
Für HTML-Tabellen kann man das Problem zeilenweise lösen (damit wird es egal, wie viele Zeilen man auswertet) - also z.B.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | #!/bin/bash
(
cat <<EOF
<html>
<head>
<meta http-equiv="Content-Language" content="de">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Messdaten</title>
</head>
<body>
<h1>Beispieltabelle</h1>
<table border="1">
<tr>
<td>Datum</td>
<td>Uhrzeit</td>
<td>Wert</td>
</tr>
EOF
tail -n7 /home/pi/rec.log | tac | while read -r var_{0..20}; do
printf " <tr>\n"
printf " <td>%s</td>\n" $var_{0,1,4}
printf " </tr>\n\n"
done
cat <<EOF
</table>
</body>
EOF
) > table.html
|
Wenn man Daten aus einer Zeile in mehreren Tabellen unterbringen und nicht jedes Mal die Datei erneut einlesen will, kann man die Tabellenzeilen in einem Array oder String zwischenspeichern und später in der gewünschten Reihenfolge ausgeben. Einfachere Statistik-Berechnungen kann man z.B. mit GNU datamash machen: https://www.gnu.org/software/datamash/manual/html_node/index.html
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
@ Hallo track, Ich muss noch mal nachhaken. Es geht um diesen String:
Habe noch -n zugefügt, sonnst liest der Script gleich 10 Zeilen. Ich brauche nur die letzte.
| tail --follow -n /home/pi/rec.log | awk '{print "Vorwort ... und Zahlen:", $9, $10; fflush()}'
|
Wie bezeichne ich die Variablen ? Haben schon so versucht: | tail --follow -n /home/pi/record.log | awk '{print "datum","uhrzeit","sollwert","istwert_vorlauf","istwert_ruecklauf:",$1,$2,$3,$4,$5,$6; fflush()}'
|
pi@raspberrypi:~ $ tail --follow -n /home/pi/record.log | awk '{print "datum","uhrzeit","sollwert","istwert_vorlauf","istwert_ruecklauf:",$1,$2,$3,$4,$5,$6;fflush()}'
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:33:42 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:33:52 030,0 035,2 028,8 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:02 030,0 035,2 028,8 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:11 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:21 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:31 030,0 035,2 028,8 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:40 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:34:50 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:35:00 030,0 035,2 028,9 017,3
datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf: 08.12.2017 15:35:10 030,0 035,2 028,9 017,3 |
# Ich möchte die Variablen im Programmablauf aufrufen können.
# z.B.
$COP_WP = Var_$17 - Var_$18 # Die werte dann noch weiter verarbeiten
$SPR = Var_$3 - Var_4
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Es gibt grundsätzlich 2 verschiedene Möglichkeiten, die Daten zu verarbeiten.
Entweder statisch: dann rufst Du nur 1x pro Auswertung das Skrit auf, und tail braucht dann auch kein --follow sondern es wird 1x das Bildchen gemalt, und für den nächsten Datensatz startest Du Dein Skript wieder neu. Oder dynamisch: dann rufst Du Dein Skript nur 1x zu Anfang auf, und es schreibt die neuen Daten live in Echtzeit - genau so, wie sie hereinkommen, wie ein Event-rRecorder ! - auf den Schirm. Das geht natürlich nur mit --follow
Ich habe noch nicht verstanden, welche dieser beiden Möglichkeiten Dir jetzt sympathischer ist. Aber davon hängt natürlich ab, wie man jetzt weiter vorgeht. LG, track
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Dynamisch.. egal wo und wann ich die Variable aufrufe, muss aktuelle Stand drin sein. Der Wert soll automatisch überschrieben werden sobald ein neuer da ist. Wenn ich ein statischen Wert brauche, wofür auch immer, schiebe ich ihn einfach in eine weitere Variable. | tail --follow -n /home/pi/rec.log | awk '{print "Vorwort ... und Zahlen:", $9, $10; fflush()}'
|
was hast Du hier mit "Vorwort ... und Zahlen: gemeint? Einfach die Datenensatz Bezeichnung ? Ich dachte ich könnte hier jeder Variable einen Aussagekräftigen Nahmen geben.
So wie hier:
| read -r datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf var_{0..4} < <(tail -n1 /home/pi/record.log)
|
# allerdings nur statisch. Also muss Script nach Bedarf neue ausgeführt werden. Hier funktioniert die Zuweisung von Aussagekräftigen Nahmen. pi@raspberrypi:~ $ read -r datum uhrzeit sollwert istwert_vorlauf istwert_ruecklauf var_{0..4} < <(tail -n1 /home/pi/record.log)
pi@raspberrypi:~ $
pi@raspberrypi:~ $ echo $datum
08.12.2017
pi@raspberrypi:~ $ echo $uhrzeit
17:45:49
pi@raspberrypi:~ $ echo $sollwert
030,0
pi@raspberrypi:~ $ echo $istwert_vorlauf
035,4
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Kilowatt schrieb: Dynamisch.. egal wo und wann ich die Variable aufrufe, muss aktuelle Stand drin sein. Also vor spätestens 60 Sec. Der Wert soll überschrieben werden sobald ein neuen da ist. Wenn ich ein statischen Wert brauche, wofür auch immer, schiebe ich ihn einfach in eine weitere Variable.
Ok, also dynamisch. Das heißt aber, dass das Skript immer weiter läuft, damit es die neuen Zahlen abholen und in das Diagramm schreiben kann. | tail --follow -n /home/pi/rec.log | awk '{print "Vorwort ... und Zahlen:", $9, $10; fflush()}
|
––→ was hast Du hier mit "Vorwort ... und Zahlen: gemeint? Einfach die Datenensatz Bezeichnung ?
Ja, irgendwelchen Text - z.B. genau so wie Du es in Deinem Beispiel hier auch gemacht hast. Ich dachte ich könnte hier jeder Variablen einen Aussagekräftigen Nahmen geben. So wie hier:
aussagekräftige Namen kannst Du auch bei awk vergeben, aber eben nur "zu Fuß": | #!/usr/bin/awk -f
{
datum=$1;
uhrzeit=$2;
sollwert=$3;
# usw. ...
}
|
Aber letzten Endes musst Du ja sowieso Dein Anlagendiagramm malen, und das wirst Du ja wohl nicht mit awk programmieren, sondern eher mit irgendwas Graphischem. → Deshalb hatte ich vorgeschlagen, dass Du zuerst mal diesen Teil baust, und danach gucken wir mal, wie man dem dann die Messwerte zuschiebt. (womöglich braucht man da dann auch gar nicht mehr viel machen, sondern das Grafik-Dingens kann die Daten direkt so verarbeiten wie sie ankommen ...?) track
|
Kilowatt
(Themenstarter)
Anmeldungsdatum: 4. Dezember 2017
Beiträge: 63
Wohnort: Salzgitter
|
Das Anlagenbild ist ein anfachen anlage.png Bild, wo an bestimmten Stellen die Rechtecken mit Istwerten stehen. | <img border="0" src="anlage.png" width="823" height="842"> # Hier wird Bild geladen
<div class="wert_anz" style="left: 230px; top: 355px;">28.9°C</div> # und hier die Istwerte
<div class="wert_anz" style="left: 565px; top: 290px;">24.9°C</div>
|
|