Forum: PC-Programmierung Python: letzten Wert aus Logdatei lesen


von Chr. M. (snowfly)


Lesenswert?

Hallo Forum,

beim basteln an meinem SmartHome bin ich gerade auf ein Problem
gestossen bei dem ich nicht weiterkomme.

Vielleicht könnt ihr mir weiterhelfen.

Ich will Daten von meinem Solarlogger in OpenHab bekommen,
jetzt bin ich schon soweit dass ich ein Python Script habe
das diverse Daten sendet.

In dieses Pyton Script möchte ich nun eine "Funktion" einfügen
die den letzten Wert aus einer .csv Datei ausliest und als
String Variable zurückgibt.

zu erweiternder code:
1
def solar(value):
2
....[letzter_Wert = letzter Wert von /home/pi/logfile$YEAR.csv]  
3
return str(letzter_Wert)
logfile2017.csv:
1
20171121,11.069
2
20171122,22.09
3
20171123,19.438
4
20171125,1.523

in letzter_Wert sollte dann 1.523 stehen.(oder besser 1523)

Leider bin ich bei meinen Versuchen kein Stück weitergekommen,
meine Versuche mir was zusammenzubastel endeten alle in einem
fehlererzeugenden c, bash, pythom Mix :(

Noch dazu kommt das die Logdatei jedes Jahr einen andern Namen hat.

: Bearbeitet durch User
von Soeren K. (srkeingast)


Lesenswert?

Ungetestet vom Smartphone:
1
import csv
2
with open('datei.csv', 'rb') as csvfile:
3
    reader = csv.reader(csvfile, delimiter=',')
4
    for row in reader:
5
        pass
6
print row[1]

Das ist ineffizient und durchläuft die ganze Datei, aber für dich sicher 
am ehesten nachvollziehbar.

Edit// nun getestet und gibt 2. Spalte zurück

: Bearbeitet durch User
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

1
#!/usr/bin/env python
2
3
4
def solar():
5
    csv_path = 'solar.csv'
6
    csv_file = open(csv_path, 'r')
7
    csv_data = csv_file.read()
8
    csv_file.close()
9
10
    csv_data = csv_data.splitlines()
11
    csv_last_value = csv_data[-1].split(',')[1]
12
    csv_last_value = csv_last_value.replace('.', '')
13
14
    return csv_last_value
15
16
17
def main():
18
    last_value = solar()
19
    print('Last Value is: {}'.format(last_value))
20
21
22
if __name__ == '__main__':
23
    main()
1
Last Value is: 1523

: Bearbeitet durch User
von Chr. M. (snowfly)


Lesenswert?

Erstmal Danke für die Hilfe!

Ich habe zum testen ein Script erstellt,
aber es fängt schon so an:
1
pi@SMApi:~/scripts $ cat ./testlast.py
2
#!/usr/bin/python
3
4
import csv
5
with open('/home/pi/scripts/energy2017.csv', 'rb') as csvfile:
6
    reader = csv.reader(csvfile, delimiter=',')
7
        for row in reader:
8
            pass
9
print row
10
pi@SMApi:~/scripts $ ./testlast.py
11
  File "./testlast.py", line 6
12
    for row in reader:
13
    ^
14
IndentationError: unexpected indent
15
pi@SMApi:~/scripts $

leider habe ich von Python wirklich gar keine Ahnung...

von Soeren K. (srkeingast)


Lesenswert?

Hi, das war mein Fehler, nimm mal das editierte Skript, die Zeile for 
row in Reader und die danach müssen jeweils weiter nach links.

: Bearbeitet durch User
von Chr. M. (snowfly)


Lesenswert?

vielen Dank euch beiden.

Mit dem Script von Kaj solle ich es hinbekommen.

Standalone läuft es jetzt muss ich es nur noch passen
hineinbasteln..

und das mit dem Jahr hinbekommen.

hibt es eine verfügbare Varaiable die das aktuelle
Jahr(4stellig) beinhaltet?

von Chr. M. (snowfly)


Lesenswert?

leider bekomme ich es auch so nicht ans laufen...

Sobald ich meine Änderung einfüge und es vom Hauptscript
angesprochen wird gibt es Fehler.

Das ganze (unter)Script sieht gerade so aus:
1
def kb(value):
2
    csv_path = '/var/www/html/123solar/data/invt1/production/energy2017.csv'
3
    csv_file = open(csv_path, 'r')
4
    csv_data = csv_file.read()
5
    csv_file.close()
6
7
    csv_data = csv_data.splitlines()
8
    csv_last_value = csv_data[-1].split(',')[1]
9
    csv_last_value = csv_last_value.replace('.', '')
10
   return str(csv_last_value)
11
12
13
#def kb(value):
14
#    return str(value / 1024) + " KB"
15
16
17
def mb(value):
18
    return str(value / 1024 / 1024) + " MB"
19
20
21
def gb(value):
22
    return str(value / 1024 / 1024 / 1024) + " GB"
23
24
25
def uptime(boot_time):
26
    import time
27
    upt = time.time() - boot_time
28
29
    retval = ""
30
    days = int(upt / (60 * 60 * 24))
31
32
    if days != 0:
33
        retval += str(days) + " " + ("days" if days > 1 else "day") + ", "
34
35
    minutes = int(upt / 60)
36
    hours = int(minutes / 60)
37
    hours %= 24
38
    minutes %= 60
39
40
    if hours != 0:
41
        retval += str(hours) + ":" + (str(minutes) if minutes >= 10 else "0" + str(minutes))
42
    else:
43
        retval += str(minutes) + " min"
44
45
    return retval
46
47
48
49
50
def register_filters(env):
51
    env.filters['KB'] = kb
52
    env.filters['MB'] = mb
53
    env.filters['GB'] = gb
54
    env.filters['uptime'] = uptime

Die Fehler sehen so aus:
1
ERROR:root:disk_usage/free/|/{{x|GB}}: unindent does not match any outer indentation level (filters.py, line 10)
2
Traceback (most recent call last):
3
  File "./psmqtt.py", line 57, in run_task
4
    payload = get_value(task)
5
  File "./psmqtt.py", line 84, in get_value
6
    value = Formatter.format(_format, value)
7
  File "/home/pi/scripts/psmqtt/format.py", line 15, in format
8
    env = cls.get_environment()
9
  File "/home/pi/scripts/psmqtt/format.py", line 22, in get_environment
10
    import filters
11
  File "/home/pi/scripts/psmqtt/filters.py", line 10
12
    return str(csv_last_value)
13
                             ^
14
IndentationError: unindent does not match any outer indentation level

Habt ihr noch einen Tip was ich übersehe?

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Chr. M. schrieb:
> Habt ihr noch einen Tip was ich übersehe?
Die eine Zeile ist falsch eingerueckt
1
return str(csv_last_value)
Den Cast str() kannst du weglassen. Der Wert ist schon ein String.

von Chr. M. (snowfly)


Lesenswert?

So,
ich habe es hinbekommen...

so läuft es:
1
    retval = ""
2
    csv_path = '/var/www/html/123solar/data/invt1/production/energy2017.csv'
3
    csv_file = open(csv_path, 'r')
4
    csv_data = csv_file.read()
5
    csv_file.close()
6
7
    csv_data = csv_data.splitlines()
8
    csv_last_value = csv_data[-1].split(',')[1]
9
    csv_last_value = csv_last_value.replace('.', '')
10
11
    retval += str(csv_last_value)
12
13
    return retval

wenn in Python wichtig ist wohin die Zeilen eingerückt
sind dann wundert mich heute nichts mehr...

Danke und N8

von (º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· (Gast)


Lesenswert?

Ist dir das nicht peinlich?
Statt des unbekuemmerten Herumexperimentierens empfiehlt sich
mal der Blick ins Buch:

Learning Python von Mark Lutz

Und spaeter dann:

PYTHON IN A NUTSHELL von Alex Martelli

von Dirk B. (dirkb2)


Lesenswert?

Chr. M. schrieb:
> wenn in Python wichtig ist wohin die Zeilen eingerückt
> sind dann wundert mich heute nichts mehr...

In Wikipedia heißt es im letzten Satz im ersten Absatz  über Python:
> So werden beispielsweise Blöcke nicht durch geschweifte Klammern, sondern
> durch Einrückungen strukturiert.

Überraschung!

von Thomas S. (doschi_)


Lesenswert?

Wenn Du nur die letzte zeile benötigst, wäre das
(bash-)Kommando 'tail' auch noch einen Blick wert.
1
tail -n 1 logfile2017.csv
Dann muss das Python-Script nicht die ganze Datei durchlaufen.
Mit
1
tail -n 1 logfile2017.csv | cut -d, -f2
 hast Du dann das 2.Feld

: Bearbeitet durch User
von Chr. M. (snowfly)


Lesenswert?

(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag 
#5224391:
> Ist dir das nicht peinlich?

Abgesehen von dem fremdschämen über deinen Post
ist mir hier nichts peinlich.

> empfiehlt sich mal der Blick ins Buch:

NaKlar, mach ich.
Gleich nachdem ich alle Bücher zu
Linux, php, html, c, c++, WLAN, Bluetooth, Ethernet,
x86, ARM, USB, MQTT, verschiedene Datenbanken und all
ihrer implementierungen und Protokolle auswendig kann,
werde also vorraussichtlich in 2 Wochen damit anfangen ;)

von Chr. M. (snowfly)


Lesenswert?

Thomas S. schrieb:
> Wenn Du nur die letzte zeile benötigst, wäre das
> (bash-)Kommando 'tail' auch noch einen Blick wert.

tail war auch mein erster Gedanke aber es hat einfach nicht
funktioniert (und inzwischen weiß ich auch warum)
danach habe ich nach verscheidenen Beispielen gesucht
und irgendwie hatten alle einen anderen Ansatz wovon
keiner auch nur annähernd funktioniert hat.

Die Fehlermeldungen waren auch immer völlig unpassend
und so dachte ich mir 'frag mal im Forum', was Dank
netter Leute wie Kaj auch funktioniert hat.
(von all den Beispielen die ich gefunden habe
war das auch die beste Lösung)

Meine Absicht war nicht eine Ausbildung in Python
zu machen sondern ein funktionierendes Gerät.
Das ich jetzt auch um die Besonderheiten von Python
weiß ist ein Nebeneffekt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.