Hallo zusammen,
ich habe mir eine Wetterstation mit einem Rasperry Pi gebaut und speichere die gemessenden Daten alle 10 Minuten (py wird über crontab gestartet) in eine csv Datei ab. Das ganze läuft nun seit ca. einem Jahre sehr zuverlässig.
Die jetzige Datei ist nach einem Jahr ist sehr groß geworden.
Nun kam mir die Idee, dass ich ja monatlich eine Datei mit neuem Namen (z.B wetterdaten_01_2018) benutzen könnten.
Da ich dazu noch kein Tutorial gefunden habe, hier nun die Frage ob dies schon jemand realisiert hat und mir den Code zu Verfügung stellen könnte?
Gruß
Franzel
Datei die ich speichere monatlich umbenennen
Mir fallen da zwei Lösungen ein:
Variante 1: Du erledigst das in deinem Python Skript. Den aktuellen Monat an den Dateinamen anzuhängen ist trivial. Python bringt Datumsoperationen in der Standard Bibliothek mit.
Variante 2: Du erledigst das mit den Mitteln deines Betriebssystems. Unter Linux gibt es dafür z.B. logrotate, das oft schon installiert ist oder leicht nachinstalliert werden kann. Du schreibst dann eine entsprechende Config-Datei, die in /etc/logrotate.d (oder vergleichbar) landet. Der Vorteil hierbei ist, dass du noch diverse weitere Dinge einstellen kannst (max. Dateigröße, Kompression, hooks, ...), die du in deinem Skript, wenn du sie brauchst, selbst programmieren müsstest. Ein bisschen Arbeit ist das aber schon, du zum Beispiel dafür sorgen solltest, dass der Cronjob für dein Skript und die Logratation sich nicht in die Quere kommen, dass eventuelle Spaltennamen auch in die neue Datei geschrieben werden usw. Der Vorteil von Variante 1 ist, dass du eine nahtlose Integration mit deinem Skript hast, was die letztgenannten Punkte einfacher machen kann.
Variante 1: Du erledigst das in deinem Python Skript. Den aktuellen Monat an den Dateinamen anzuhängen ist trivial. Python bringt Datumsoperationen in der Standard Bibliothek mit.
Variante 2: Du erledigst das mit den Mitteln deines Betriebssystems. Unter Linux gibt es dafür z.B. logrotate, das oft schon installiert ist oder leicht nachinstalliert werden kann. Du schreibst dann eine entsprechende Config-Datei, die in /etc/logrotate.d (oder vergleichbar) landet. Der Vorteil hierbei ist, dass du noch diverse weitere Dinge einstellen kannst (max. Dateigröße, Kompression, hooks, ...), die du in deinem Skript, wenn du sie brauchst, selbst programmieren müsstest. Ein bisschen Arbeit ist das aber schon, du zum Beispiel dafür sorgen solltest, dass der Cronjob für dein Skript und die Logratation sich nicht in die Quere kommen, dass eventuelle Spaltennamen auch in die neue Datei geschrieben werden usw. Der Vorteil von Variante 1 ist, dass du eine nahtlose Integration mit deinem Skript hast, was die letztgenannten Punkte einfacher machen kann.
-
- User
- Beiträge: 13
- Registriert: Freitag 12. August 2016, 15:46
Hallo nochmal,
erstmal geht es wie von euch gut geantwortet um den Weg zum Ziel. Ich bin noch Pythonanfänger und habe gelernt man kann sich bei der Programmierung auch ein Loch in das Knie bohren und eine Stacheldraht durchziehen.
Ich würde es gerne mit dem bereits von mir erstellten Pythonprgramm erledigen.
Das Datum und die Uhrzeit habe ich bereits aufgeteilt in Tage, Monat, Jahr usw in Variablen gelegt und schreibe diese auch in die csv- Datei.
Somit wäre das Jahr und der Monat vorhanden.
Was ich gerne möchte, ist jeweils eine neue Datei am Anfang des Monats automatisch erstellen, und diese dann den ganzen Monat mit den Daten füllen. Im nächsten Monat das ganze vor vorne nur mit einem neuen Dateinamen, der den Monat als Zahl und die Jahreszahl enthält.
Bisher beschreibe ich die Datei mit folgendem Code
Gruß
Thomas
erstmal geht es wie von euch gut geantwortet um den Weg zum Ziel. Ich bin noch Pythonanfänger und habe gelernt man kann sich bei der Programmierung auch ein Loch in das Knie bohren und eine Stacheldraht durchziehen.
Ich würde es gerne mit dem bereits von mir erstellten Pythonprgramm erledigen.
Das Datum und die Uhrzeit habe ich bereits aufgeteilt in Tage, Monat, Jahr usw in Variablen gelegt und schreibe diese auch in die csv- Datei.
Somit wäre das Jahr und der Monat vorhanden.
Was ich gerne möchte, ist jeweils eine neue Datei am Anfang des Monats automatisch erstellen, und diese dann den ganzen Monat mit den Daten füllen. Im nächsten Monat das ganze vor vorne nur mit einem neuen Dateinamen, der den Monat als Zahl und die Jahreszahl enthält.
Bisher beschreibe ich die Datei mit folgendem Code
Code: Alles auswählen
#Ausgabe in Datei schreiben
try:
d = open("/home/shares/pi/wetterhaus_2018_python3_test.csv","a")
except:
print("Dateizugriff auf lokale Datei /home/shares/pi nicht erfolgreich")
sys.exit(0)
d.write (time.strftime("%d/%m/%Y") + ";" + time.strftime("%H:%M:%S") + ";" + str(Luftfeuchte).replace(".",",")
+ ";" + str(Temperatur).replace(".",",") + ";" + str(Temperatur2).replace(".",",")
+ ";" + str(Druck).replace(".",",") + ";" + str(Hoehe).replace(".",",") + ";" + str(ad1).replace(".",",")
+ ";" + str(ad2).replace(".",",") + ";" + str(ad3).replace(".",",") + ";" + str(ad4).replace(".",",")
+ ";" + str(ad5).replace(".",",") + ";" + str(ad6).replace(".",",") + ";" + str(ad7).replace(".",",")
+ ";" + str(ad8).replace(".",",") + ";" + str(ad9).replace(".",",") + ";" + str(ad10).replace(".",",")
+ ";" + str(ad11).replace(".",",") + ";" + str(ad12).replace(".",",") + ";" + str(Lichtlux1).replace(".",",")
+ ";" + str(Lichtlux2).replace(".",",") + "\n")
d.close()
Gruß
Thomas
Du baust doch schon strings zusammen. Auf etwas grausliche Weise mit + statt format zu benuzten, aber sei’s drum. Was hindert dich denn daran den Dateinamen genauso zu bauen?
zb als Start, zusammen mit os.path.join für den vollen Pfad.
Code: Alles auswählen
time.strftime(“%Y-%m.csv”)
@Franzel007: Wenn Du Dir, wie von __deets__ gezeigt, die Dateinamen selbst erstellst, dann kannst Du vor dem öffnen der Datei prüfen, ob es die Dateie schon gibt. Falls ja, dann füge weitere Daten an, andernfalls erstelle eine neue Datei. Das ist beides sogar recht einfach und Du bist fast am Ziel.
Programmieranfänger neigen allerdings manchmal dazu, Lösungen als einfacher zu betrachten, die ausschließlich auf ihrem aktuellen Kenntnisstand operieren. Dabei sind gerade diese Lösungen öfters mal die wesentlich komplizierteren. Beispielsweise könntest du für das Schreiben der CSV-Datei auf das entsprechende Modul zurückgreifen, statt selbst CSV zu erzeugen.Ich bin noch Pythonanfänger und habe gelernt man kann sich bei der Programmierung auch ein Loch in das Knie bohren und eine Stacheldraht durchziehen.
Hier jedenfalls mal ein Beispiel, wie man es meiner Meinung nach lösen könnte:
Code: Alles auswählen
#!/usr/bin/env python3
import pathlib
import csv
from datetime import datetime
from random import randint
TEMPLATE = '/tmp/mylog_{year}-{month}.csv'
def main():
now = datetime.now()
path = pathlib.Path(TEMPLATE.format(year=now.year, month=now.month))
fieldnames = ('timestamp', 'temperature', 'humidity')
if not path.exists():
with path.open('w') as fh:
writer = csv.writer(fh)
writer.writerow(fieldnames)
with path.open('a') as fh:
writer = csv.writer(fh)
data = [datetime.now().timestamp(), randint(-10, 50), randint(1, 100)]
writer.writerow(data)
if __name__ == '__main__':
main()
Zuletzt geändert von nezzcarth am Sonntag 10. Dezember 2017, 13:54, insgesamt 1-mal geändert.
-
- User
- Beiträge: 13
- Registriert: Freitag 12. August 2016, 15:46
Hallo und nochmals danke,
ich habe mir eure Tips angeschaut und mich für diesen (ich weiß Anfänger- Python) Weg entschieden.
Gruß
Franzel
ich habe mir eure Tips angeschaut und mich für diesen (ich weiß Anfänger- Python) Weg entschieden.
Code: Alles auswählen
#!/usr/bin/python3
#-*- coding: iso-8859-1 -*-
#Test Filename mit Datum erstellen in Python3
#Module laden
import sys
import time
#Datum und Uhrzeit
lt = time.localtime()
jahr, monat, tag = lt[0:3]
stunde, minute, sekunde = lt[3:6]
#Ausgabe Datum und Zeit
print ("Datum :{0:02d}/{1:02d}/{2:04d}".format(tag, monat, jahr))
print ("Uhrzeit :{0:02d}:{1:02d}:{2:02d}".format(stunde, minute, sekunde))
#Filename definieren
filename = (str(jahr) + str("_") + str(monat) + str("_") + str("wetterhauesle"))
print ("Filename heisst: ", filename)
#Ausgabe in Datei schreiben
try:
d = open("/home/shares/pi/"+filename,"a")
except:
print("Dateizugriff auf lokale Datei /home/shares/pi nicht erfolgreich")
sys.exit(0)
d.write ("Hallo Test")
d.close()
Franzel
@Franzel007: warum verwendest Du .format bei print, stückelst aber dann den Dateinamen mit str und + zusammen? Du weißt doch wie es besser geht. »str« auf einen literalen String anzuwenden, ist doppelt komisch. Niemals nackte excepts benutzen, denn Du fängst viel mehr Fehler ab, als Du denkst. Hier machst Du nicht einmal was sinnvolles mit dem Fehler. Pfade setzt man mit os.path.join zusammen und Dateien öffnet man mit dem with-Statement:
Code: Alles auswählen
import os
from datetime import datetime
#Datum und Uhrzeit
now = datetime.now()
#Ausgabe Datum und Zeit
print("Datum :{:d.m.Y}".format(now))
print("Uhrzeit :{:H:M:S}".format(now))
filename = "{:Y_m}_wetterhauesle".format(now)
print("Filename heisst: ", filename)
with open(os.path.join("/home/shares/pi", filename), "a") as d:
d.write("Hallo Test")
@Sirius3: Daran ist nichts falsch in dem Sinne, dass es mit den heute am meisten verbreiteten Betriebssystemen funktioniert, aber der slash ist ein Betriebssystem abhängiger Separator, so dass
konsequent wäre.
Code: Alles auswählen
os.path.join('/home', 'share', 'pi', filename)
@kbr: was ist mit `/home`? Solche Strings gehören nicht in den Code, sondern als Konstanten an den Anfang, so dass sie je nach System schnell geändert werden können:
Code: Alles auswählen
import os
from datetime import datetime
HOME_PATH = "/home/shares/pi"
#Datum und Uhrzeit
now = datetime.now()
#Ausgabe Datum und Zeit
print("Datum :{:d.m.Y}".format(now))
print("Uhrzeit :{:H:M:S}".format(now))
filename = "{:Y_m}_wetterhauesle".format(now)
print("Filename heisst: ", filename)
with open(os.path.join(HOME_PATH, filename), "a") as d:
d.write("Hallo Test")
@kbr: es geht darum, dass man absolute Pfade nicht systemübergreifend festlegen kann, will man also solch ein Programm möglichst einfach anpassbar machen, verstreut man am besten nicht alle Änderungen über den gesamten Code, sondern sammelt sie am Anfang.
@Sirius3: Mir ging es darum, dass der Vorteil der Nutzung von os.path.join, nämlich die automatische Nutzung os-spezifischer Separatoren, verlorengeht, sobald auch nur einmal davon abgewichen wird, so wie Du es getan hast.
Deine Anmerkungen sind zwar korrekt, aber ich habe den Eindruck, dass Du Dich auf den führenden Slash bei '/home' kaprizieren möchtest. Ja, den hätte ich weglassen können, das lässt sich anders angehen.
Deine Anmerkungen sind zwar korrekt, aber ich habe den Eindruck, dass Du Dich auf den führenden Slash bei '/home' kaprizieren möchtest. Ja, den hätte ich weglassen können, das lässt sich anders angehen.
@kbr:
Der Pfad für benutzerspezifische Dateien ist unter Windows ein ganz anderer als unter Linux-Systemen. Trotzdem ist es vorteilhaft, os.path.join() einzusetzen, wenn vorher ein bestimmter Pfad festgelegt wurde und man da die gewünschte Datei ablegt (/home/whatever/ <-> C:\Whatever\).
IMHO verstehst du hier den Sinn von os.path.join() falsch. Es geht ja nicht darum, jeden erdenklichen Pfad quasi nachträglich in eine "join()-Version" umschreiben zu müssen. Man will einfach an Stellen, wo tatsächlich noch etwas zusammengesetzt werden muss, eine plattformübergreifende Lösung haben.
Und das von dir bemängelte os.path.join("/home/shares/pi", filename) mag erstmal unnötig erscheinen. Im tatsächlichen Code jedoch schreibt man das vielleicht jetzt oder später als Konstante (wie ja schon gesagt wurde). Und dann ist der Weg über join() durchaus sinnvoll. Ob man es daher in weiser Voraussicht gleich so schreibt, ist Geschmackssache. Falsch ist es jedoch nicht.
Der Pfad für benutzerspezifische Dateien ist unter Windows ein ganz anderer als unter Linux-Systemen. Trotzdem ist es vorteilhaft, os.path.join() einzusetzen, wenn vorher ein bestimmter Pfad festgelegt wurde und man da die gewünschte Datei ablegt (/home/whatever/ <-> C:\Whatever\).
IMHO verstehst du hier den Sinn von os.path.join() falsch. Es geht ja nicht darum, jeden erdenklichen Pfad quasi nachträglich in eine "join()-Version" umschreiben zu müssen. Man will einfach an Stellen, wo tatsächlich noch etwas zusammengesetzt werden muss, eine plattformübergreifende Lösung haben.
Und das von dir bemängelte os.path.join("/home/shares/pi", filename) mag erstmal unnötig erscheinen. Im tatsächlichen Code jedoch schreibt man das vielleicht jetzt oder später als Konstante (wie ja schon gesagt wurde). Und dann ist der Weg über join() durchaus sinnvoll. Ob man es daher in weiser Voraussicht gleich so schreibt, ist Geschmackssache. Falsch ist es jedoch nicht.
So verstehe ich es auch. Nur was zuvor zusammengesetzt wurde, sollte dann auch plattformübergreifend funktionieren, sonst ergibt sich kein Nutzen. Falls ich da etwas falsch sehe, korrigiere mich bitte.snafu hat geschrieben:Man will einfach an Stellen, wo tatsächlich noch etwas zusammengesetzt werden muss, eine plattformübergreifende Lösung haben.