Seite 1 von 3
Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 4. Mai 2016, 15:46
von chrisxx8
Hallo zusammen,
Das hier ist mein ersten Programm. Teilweise zusammen kopiert und selbst geschrieben.
Ich möchte im unteren Teil des Programms eine CSV Datei schreiben. Was Ohne While schleife auch funktioniert.
Ich möchte aber nun jede Minute diese CSV Datei schreiben. Ich weiß aber noch nicht wie ich das machen soll?
Vieleicht mittels:
-Unterprogramm
-While schleife mit Timer
Wenn ich eine While schleife einbaue welche die bedingung True hat schreibt er mir meine CSV datei voll, aber er bearbeitet ja nur die Schleife und nicht mehr den Rest des Programms. Jetzt wäre die Idee die While schleife oder das Unterprogramm alles 60s aufzurufen. Das er für einen Zyklus die CSV schreibt.
Code: Alles auswählen
import Tkinter
from Tkinter import *
from Tkinter import *
import smbus
import ttk
import csv
import time
import threading
bus = smbus.SMBus(1)
mainWin = Tk()
mainWin.title('Analoge Eingabe')
bus = smbus.SMBus(1)
def wert(label,kanal,pb): #Variablen für Label,Kanal,Progressbar
def read():
var = bus.read_i2c_block_data(0x08,kanal,11) #Werte von Board in 11 stelliges Array schreiben
val = var[2]*256+var[1] #Berechnung der korrekten Zahlenwerte aus dem Array
label.config(text=str(val)) #Umwandeln der Integer Zahl in eine String Ziffer + Ausgabe in Label
label.after(20, read) #read() wird nach 20 ms erneut ausgeführt
pb.config(value=val) #Value der Progressbar wird angepasst
return val
return read()
#Label für Kanalbestimmung (unwichtig)
bai1 = ttk.Label(mainWin, width=9, text='Kanal 1: ')
bai1.grid(row=1,column=1)
bai2 = ttk.Label(mainWin, width=9, text='Kanal 2: ')
bai2.grid(row=2,column=1)
bai3 = ttk.Label(mainWin, width=9, text='Kanal 3: ')
bai3.grid(row=3,column=1)
bai4 = ttk.Label(mainWin, width=9, text='Kanal 4: ')
bai4.grid(row=4,column=1)
bai5 = ttk.Label(mainWin, width=9, text='Kanal 5: ')
bai5.grid(row=5,column=1)
#Label für Digitale Darstellung
labelai1 = ttk.Label(mainWin, width=5)
labelai1.grid(row=1,column=2)
labelai2 = ttk.Label(mainWin, width=5)
labelai2.grid(row=2,column=2)
labelai3 = ttk.Label(mainWin, width=5)
labelai3.grid(row=3,column=2)
labelai4 = ttk.Label(mainWin, width=5)
labelai4.grid(row=4,column=2)
labelai5 = ttk.Label(mainWin, width=5)
labelai5.grid(row=5,column=2)
#Progressbar für Analoge Darstellung
pb1 = ttk.Progressbar(mainWin, orient='horizontal', maximum=990, length=100, mode='determinate')
pb1.grid(row=1,column=3)
pb2 = ttk.Progressbar(mainWin, orient='horizontal', maximum=990, length=100, mode='determinate')
pb2.grid(row=2,column=3)
pb3 = ttk.Progressbar(mainWin, orient='horizontal', maximum=990, length=100, mode='determinate')
pb3.grid(row=3,column=3)
pb4 = ttk.Progressbar(mainWin, orient='horizontal', maximum=990, length=100, mode='determinate')
pb4.grid(row=4,column=3)
pb5 = ttk.Progressbar(mainWin, orient='horizontal', maximum=990, length=100, mode='determinate')
pb5.grid(row=5,column=3)
#Die wert-Funktion wird mit den 3 Parametern bestückt
kw1 = wert(labelai1,0x00,pb1)
kw2 = wert(labelai2,0x01,pb2)
kw3 = wert(labelai3,0x02,pb3)
kw4 = wert(labelai4,0x03,pb4)
kw5 = wert(labelai5,0x04,pb5)
print ("kw1:",kw1)
print ("kw2:",kw2)
print ("kw3:",kw3)
print ("kw4:",kw4)
print ("kw5:",kw5)
gps=0
while time.time(5.0):
csvOut=open("/home/pi/Ana_Value.csv", "a")
spamWriter = csv.writer(csvOut, delimiter=';', quotechar='|')
spamWriter.writerow( ['Wert1:', kw1, 'Wert2:', kw2, 'Wert3:', kw3, 'Wert4:', kw4, 'Wert5:', kw5, 'GPS:', gps, ] )
csvOut.close()
mainWin.mainloop()
Noch ne Frage die mich interesiert, (ich komme aus der Siemens SPS Welt) hier wird Das Programm Zyklisch abgearbeitet. Wieso wird die CSV bei Python nicht in jeden Zyklus beschrieben wenn das Programm alleine mit diesem
Code: Alles auswählen
csvOut=open("/home/pi/Ana_Value.csv", "a")
spamWriter = csv.writer(csvOut, delimiter=';', quotechar='|')
spamWriter.writerow( ['Wert1:', kw1, 'Wert2:', kw2, 'Wert3:', kw3, 'Wert4:', kw4, 'Wert5:', kw5, 'GPS:', gps, ] )
csvOut.close()
Code läuft?
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 4. Mai 2016, 15:59
von Sirius3
@chrisxx8: Du benutzt doch schon after, um periodisch eine Methode aufzurufen. Warum nicht auch zum Schreiben.
Einrückungen sollten einheitlich 4 Leerzeichen pro Ebene sein. Sternchenimporte vermeiden, weil man nicht kontrollieren kann, was da alles in den Namensraum geladen wird. Auf Modulebene gehören nur Definitionen und Konstanten, der Rest sollte in eine Funktion, die üblicherweise main genannt wird. Wenn man anfängt, Variablennamen durchzunummerieren will man wahrscheinlich Listen benutzen.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 4. Mai 2016, 16:17
von BlackJack
@chrisxx8: Bis wie weit hast Du das Programm denn laufen lassen (können)? Weil:
Code: Alles auswählen
In [7]: import time
In [8]: time.time(5.0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-fb31c0dd8285> in <module>()
----> 1 time.time(5.0)
TypeError: time() takes no arguments (1 given)
Und sollte in Deinem *tatsächlichen* Programm `time.sleep()` an der Stelle stehen: Das hat `None` als Rückgabewert und `None` ist als Bedingung ”falsch” womit die ``while``-Schleife nicht ausgeführt wird.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 4. Mai 2016, 23:03
von BlackJack
@chrisxx8: Nicht nur der `time.time()`-Aufruf führt zu einem Programmabbruch sondern das läuft so gar nicht erst weil im Quelltext Umlaute stehen, aber kein Kodierungskommentar angegeben wird.
`Tkinter` und `threading` werden importiert aber dann gar nicht verwendet und der Sternchen-Import aus dem `Tkinter`-Modul steht doppelt da.
Ebenfalls doppelt ist das erstellen eines `SMBus`-Exemplars.
`wert()` ist kein guter Funktionsname. Namen sollen dem Leser verraten was der Wert dahinter im Programm bedeutet. Bei Funktionen und Methoden sind Namen daher in der Regel Tätigkeiten die beschreiben was die Funktion tut.
Zeilen sollten nicht länger als 80 Zeichen sein und ausgerichtete Kommentare am Zeilenende sind unpraktisch. Zum einen kommt man damit schnell über die 80 Zeichen-Grenze und dann muss man immer wenn man etwas an einer kommentierten Zeile ändert, den Kommentar neu ausrichten. Kommentare sollten ausserdem nicht noch mal das beschreiben was man am Quelltext sowieso schon ablesen kann. Wenn ein Kommentar keinen Mehrwert über den Code bietet, braucht man ihn nicht. Er ist dann sogar eine Fehlerquelle weil man immer aufpassen muss auch den Kommentar zu ändern wenn man den Code ändert. Macht man da einen Fehler, dann widersprechen sich im schlimmsten Fall Kommentar und Code und dann verwirrt der Kommentar statt aufzuklären. Faustregel: Kommentare beschreiben nicht *was* der Code macht, sondern warum er das macht was er macht. Sofern das nicht offensichtlich ist.
Nach Kommas und um binäre Operatoren werden üblicherweise Leerzeichen gesetzt. Das erhöht die Lesbarkeit.
Namen sollten nicht aus kryptischen Abkürzungen bestehen. Wenn man `progressbar` meint, sollte man nicht `pb` schreiben. Ausnahme sind Namen die nur auf einen Ausdruck beschränkt sind (anonyme Funktionen, Generatorausdrücke, …).
Werte, ausser Konstanten, die von einer Funktion oder Methode verwendet werden, sollten als Argumente übergeben werden und nicht irgendwie ”magisch” aus der Umgebung kommen. Die `wert()`-Funktion bräuchte also noch ein Argument über das der Bus in die Funktion kommt.
Der Rückgabewert bei `read()` macht keinen wirklichen Sinn, weil nur der allererste tatsächlich beim Aufrufer landet. Alle weiteren Aufrufe werden von der GUI-Hauptschleife erledigt (wenn der Code bis dahin kommen würde) und diese Schleife kann mit Rückgabewerten an der Stelle nichts anfangen. Und tut das auch nicht. Die werden einfach ignoriert.
Die `read()`-Funktion so zu verschachteln macht nicht wirklich Sinn. Zusätzliche Argumente kann man bei `after()` angeben, so dass man dieses Closure nicht benötigt.
Spalten und Zeilennummern bei `grid()` fangen bei 0 an und nicht bei 1. Bei 0 anzufangen zu zählen ist üblich bei Computern.
Das Auslesen und die Anzeige könnten dann beispielsweise so aussehen (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
import Tkinter as tk
import ttk
import smbus
def read_channel(bus, channel, label, progressbar):
byte_values = bus.read_i2c_block_data(0x08, channel, 11)
value = byte_values[2] * 256 + byte_values[1]
label.config(text=str(value))
progressbar.config(value=value)
label.after(20, read_channel, bus, channel, label, progressbar)
def main():
root = tk.Tk()
root.title('Analoge Eingabe')
bus = smbus.SMBus(1)
for i in xrange(5):
ttk.Label(
root, width=9, text='Kanal {0}: '.format(i + 1)
).grid(row=i, column=0)
value_label = ttk.Label(root, width=5)
value_label.grid(row=i, column=1)
progressbar = ttk.Progressbar(
root,
orient='horizontal',
maximum=990,
length=100,
mode='determinate',
)
progressbar.grid(row=i, column=2)
read_channel(bus, i, value_label, progressbar)
root.mainloop()
Allerdings ist es schwer hier jetzt das schreiben in eine CSV-Datei einzubauen. Ich würde mal behaupten das ist ohne objektorientierte Programmierung nicht sauber ohne Verrenkungen oder „unpythonisch“ zu werden möglich.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 08:09
von chrisxx8
@Sirius3
Ja die after funktion könnte man natürlich auch zum schreiben nehmen..
habe das jetzt mal so geschrieben
[Codebox=python file=Unbenannt.py]
Code: Alles auswählen
def schreibe_csv():
def wirte():
csvOut=open("/home/pi/Ana_Value.csv", "a")
spamWriter = csv.writer(csvOut, delimiter=';', quotechar='|')
spamWriter.writerow( ['Wert1:', kw1, 'Wert2:', kw2, 'Wert3:', kw3, 'Wert4:', kw4, 'Wert5:', kw5, 'GPS:', gps, ] )
csvOut.close()
lable.after(100, wirte)
[/Codebox]
Das komplette Programm wie oben gepostet läuft zwar und funktioniert auch super, aber die csv wird so nicht mehr geschrieben.
woran könnte das denn liegen?
@BlackJack
Das Programm läuft aber sehr gut, die Werte kommen über den Bus an und werden auch angezeigt(wenn ich den zweiten csv Teil benutze den ich oben gepostet habe) nur die CSV datei wird nur einmalig geschrieben. Ich möchte aber das sie in einem Minuten Takt z.b geschrieben wird.
Auf jeden Fall cool von dir das du dir so eine mühe machst, werde mir es zu Herzen nehmen und Teile anpassen.
Aber zu sagen CSV schreiben geht nicht mehr ist natürlich misst.
Wie das so bei Programmierern ist... es muss gehen^^
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 09:06
von Sirius3
@chrisxx8: wenn etwas nicht tut, dann kann das Programm wohl nicht so super sein. Tk bietet Variablen um Werte an mehreren Stellen benutzen zu können, ohne sich merken zu müssen, wo genau. Bei Dir ändern sich ja die Werte kw1, ... nach dem ersten Auslesen nie wieder. Auch sehe ich nicht, wo Du wirte überhaupt einmal aufrufst.
Code: Alles auswählen
import Tkinter as tk
import ttk
import csv
import smbus
def update_values(mainwin, bus, variables):
for kanal, variable in enumerate(variables):
# Werte von Board in 11 stelliges Array schreiben
var = bus.read_i2c_block_data(0x08, kanal, 11)
variable.set(var[2]*256 + var[1])
mainwin.after(20, update_value, mainwin, bus, variables)
def save_values(mainwin, variables):
with open("/home/pi/Ana_Value.csv", "a") as csv_out:
writer = csv.writer(csv_out, delimiter=';', quotechar='|')
row = []
for idx, var in enumerate(variables, 1):
row.append('Wert%d:' % idx)
row.append(var.get())
writer.writerow(row)
mainwin.after(10000, write, mainwin, variables)
def main():
bus = smbus.SMBus(1)
mainwin = tk.Tk()
mainwin.title('Analoge Eingabe')
werte = []
for kanal in range(5):
wert = tk.IntVar()
werte.append(wert)
ttk.Label(mainwin, width=9, text='Kanal %d: ' % (kanal+1)).grid(row=kanal, column=0)
# Label für Digitale Darstellung
ttk.Label(mainwin, width=5, textvariable=wert).grid(row=kanal, column=1)
# Progressbar für Analoge Darstellung
ttk.Progressbar(mainwin, orient='horizontal',
maximum=990, length=100, mode='determinate',
variable=wert).grid(row=kanal,column=2)
update_values(mainwin, bus, werte)
save_values(mainwin, werte)
mainwin.mainloop()
if __name__ == '__main__':
main()
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 10:04
von chrisxx8
Ja stimmt eigentlich, die Werte aendern sich nicht mehr...
Also bei deinem Code bekomme ich jetyt folgende Fehler Meldungen:
Traceback (most recent call last):
File "/home/pi/pyforum.py", line 43, in <module>
main()
File "/home/pi/pyforum.py", line 38, in main
update_values(mainwin, bus, werte)
File "/home/pi/pyforum.py", line 11, in update_values
mainwin.after(20, update_value, mainwin, bus, variables)
NameError: global name 'update_value' is not defined
>>>
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 11:01
von BlackJack
@chrisxx8: Na dann überleg mal was da eigentlich stehen sollte. Das ist ja ein recht offensichtlicher Fehler mit einer recht offensichtlichen Lösung.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 11:32
von chrisxx8
ja das weiß ich nicht.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 12:48
von Sirius3
@chrisxx8: Du weißt nicht, was ein NameError bedeutet?
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 12:50
von BlackJack
@chrisxx8: Das müsstest Du aber wissen, es sei denn Du weisst auch schon nicht was Du in deinem eigenen ersten Beitrag in dem Code gemacht hast.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 12:56
von chrisxx8
Nein ich weiß nicht was ich im ersten code gemacht habe.. alles gebastellt und zusammen kopiert..
sitze das erste mal vor Python..
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Freitag 6. Mai 2016, 18:10
von BlackJack
@chrisxx8: Dann fang jetzt halt an zu lernen und zu verstehen was Du da machst. Sonst wird das mit dem Programmieren nichts, wenn Du Dir alles von anderen schreiben lässt.

Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Dienstag 10. Mai 2016, 08:52
von chrisxx8
Ja Ich bleibe dran:)
Habe noch einiges an erweiterungen eingebaut.
Unteranderem arbeite ich jetyt mit einem GPS Module.
Bekomme in unregelmaesigen Zeitabstaenden einen Key Fehler.
Hat das was mit meinen Bibliotheken zu tun? Ich mache wieder * Importe da es mit nur Import GPS nicht funktinoniert.
Hier die Fehlermeldung:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/home/pi/Christian.py", line 112, in run
GPSValues = self.GetGPSValues(gpsd)
File "/home/pi/Christian.py", line 52, in GetGPSValues
GPSValues_[0] = gps['time']
File "/usr/lib/python2.7/dist-packages/gps/client.py", line 203, in __getitem__
return self.__dict__[key]
KeyError: 'time'
Code: Alles auswählen
#! /usr/bin/python
import threading
import csv
import time
import smbus
from gps import *
from datetime import datetime
import datetime
import os
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.session = gps(mode=WATCH_ENABLE)
self.current_value = None
def get_current_value(self):
return self.current_value
def run(self):
try:
while True:
self.current_value = self.session.next()
time.sleep(0.2) # tune this, you might not get values that quickly
except StopIteration:
pass
class Loger(threading.Thread):
#Ergebnis = {}
ActValues = ""
ActValueLock = threading.Lock()
LogDelay = 10
def __init__(self, LogDelay):
threading.Thread.__init__(self)
self.LogDelay = LogDelay
Loger.ActValueLock.acquire()
Loger.ActValues = "LEER"
Loger.ActValueLock.release()
@staticmethod
def GetGPSValues(gpsd_):
GPSValues_ = ["", "", ""]
gps = gpsd_.get_current_value()
if gps != None:
GPSValues_[0] = gps['time']
GPSValues_[1] = gps['lat']
GPSValues_[2] = gps['lon']
return GPSValues_
@staticmethod
def GetDigitalValues(i2c_, adresse_):
DigitalValues_ = [False, True, False, False, False, False, False, False]
#print DigitalValues_
return DigitalValues_
@staticmethod
def GetAnalogValues(i2c_, adresse_, MinOut, MaxOut):
AnalogValues_ = [0.0, 0.0, 0.0, 0.0, 0.0]
for i in range(5):
var = i2c_.read_i2c_block_data(adresse_, i, 11)
AnalogValues_[i] = var[2] << 8
AnalogValues_[i] = AnalogValues_[i] | var[1]
AnalogValues_[i] = ((MaxOut[i] - MinOut[i]) / 1024) * AnalogValues_[i]
return AnalogValues_
@staticmethod
def SaveValues(GPSValues_, DigitalValues_, AnalogValues_, Path):
csvFile = open(Path, "a")
writer = csv.writer(csvFile, delimiter=';', quotechar='|')
if os.path.getsize(Path) == 0:
row = []
row = ["utc", "latitude", "longitude"]
for i in range(len(DigitalValues_)):
row.append("D%04d_%04d" % (0x38, i))
for i in range(len(AnalogValues_)):
row.append("A%04d_%04d" % (0x08, i))
writer.writerow(row)
row = []
row.append(GPSValues_[0])
row.append(GPSValues_[1])
row.append(GPSValues_[2])
for i in range(len(DigitalValues_)):
row.append('%s' % DigitalValues_[i])
for i in range(len(AnalogValues_)):
row.append('%f' % AnalogValues_[i])
writer.writerow(row)
csvFile.close()
print row
def run(self):
gpsd = GpsPoller()
gpsd.start()
GPSValues = []
i2c = smbus.SMBus(1)
DigitalValues = []
AnalogValues = []
ScaleOutMin = [0.0, 0.0, 0.0, 0.0, 0.0]
ScaleOutMax = [10.0, 10.0, 10.0, 10.0, 10.0]
while True:
t0 = datetime.datetime.now()
GPSValues = self.GetGPSValues(gpsd)
DigitalValues = self.GetDigitalValues(i2c, 0x38)
AnalogValues = self.GetAnalogValues(i2c, 0x08, ScaleOutMin, ScaleOutMax)
self.SaveValues(GPSValues, DigitalValues, AnalogValues, r"/home/pi/Ana_Value.csv")
dt = datetime.datetime.now() - t0
print self.LogDelay - dt.total_seconds()
time.sleep(self.LogDelay - dt.total_seconds())
gpsd.join()
thread = Loger(long(5))
thread.start()
thread.join()
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Dienstag 10. Mai 2016, 09:15
von Sirius3
@chrisxx8: Dass etwas mit *-Import funktioniert aber mit `import gps` nicht, kann nur daran liegen, dass Du den entsprechenden Namen nicht richtig referenzierst: `gps.xyz`. So einen NameError zu beheben, dürfte trivial sein.
So wie Du Dir das vorstellst funktioniert nebenläufige Programmierung nicht. Objekte dürfen nicht gleichzeitig in unterschiedlichen Threads verwendet werden. In Deinem Fall heißt das, dass Du eine Kopie der Daten anfertigen solltest. Diese selbstgeschriebene for-Schleife per while sieht auch komisch aus.
Deine Loger-Klasse ist eigentlich keine Klasse, da Du nur mit globalen Variablen und statischen Klassen herumhantierst. Du solltest Dir klar darüber sein, wann eine Endlosschleife fertig ist. Du hältst Dich nicht an die Namenskonvention und hängst zusätzlich noch lustige Unterstriche an Variablennamen dran. Beides macht Deinen Code sehr schwer lesbar. Was erwartest Du für Effekte, dass die 5 ein long ist?
`datetime` aus datetime zu importieren um danach diesen Namen wieder mit dem Modul datetime zu überschreiben, ist ziemlich unsinnig. Diese ActValue-Zeugs ist sicher nur aus Deinem Unwissen, wie man mit Threads arbeitet übriggeblieben. (PS: Locks sollte man *immer* mit with benutzen). Statt Listen mit Dummy-Werten zu belegen und danach mit richtigen Werten zu füllen, ist umständlich; warum nicht gleich die Liste mit richtigen Werten erzeugen?
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Dienstag 10. Mai 2016, 09:17
von chrisxx8
Vermutlich habe ich den Fehler selber schon gefunden.. aber so 100% verstehen tue ich das noch nicht.
Ich habe im Code den Time.sleep entfernt, bisher läuft es ohne abstürze..
Code: Alles auswählen
[code]def run(self):
try:
while True:
self.current_value = self.session.next()
time.sleep(0.2) # tune this, you might not get values that quickly
except StopIteration:
pass
[/code]
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Dienstag 10. Mai 2016, 09:27
von chrisxx8
@ Sirius3
Danke für dein Beitrag, ich werde mir diese stellen mal genauer anschauen und hoffentlich abändern können.
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Dienstag 10. Mai 2016, 09:51
von Sirius3
@chrisxx8: komme ich ungefähr da raus (ungetestet):
Code: Alles auswählen
#!/usr/bin/python
import os
import time
import copy
import csv
import threading
import smbus
import gps
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.current_value = {}
def get_gps_values(self):
gps = self.current_value
return gps.get('time', ''), gps.get('lat', ''), gps.get('lon', '')
def run(self):
session = gps(mode=WATCH_ENABLE)
for value in session:
self.current_value = copy.copy(session)
time.sleep(0.2) # tune this, you might not get values that quickly
def get_digital_values(i2c, adresse):
return [False, True, False, False, False, False, False, False]
def get_analog_values(i2c, adresse, output_scaling):
result = []
for idx, (min, max) in enumerate(output_scaling):
var = i2c.read_i2c_block_data(adresse, idx, 11)
value = var[2] * 256 + var[1]
result.append(value / 1024.0 * (max - min) + min)
return result
def save_values(gps_values, digital_values, analog_values, filename):
with open(filename, "a") as csv_file:
writer = csv.writer(csv_file, delimiter=';', quotechar='|')
if csv_file.tell() == 0:
row = ["utc", "latitude", "longitude"]
for i in range(len(digital_values)):
row.append("D%04d_%04d" % (0x38, i))
for i in range(len(analog_values)):
row.append("A%04d_%04d" % (0x08, i))
writer.writerow(row)
row = []
row.extend(gps_values)
row.extend(digital_values)
row.extend(analog_values)
writer.writerow(row)
def do_logging(delay):
gpsd = GpsPoller()
gpsd.start()
i2c = smbus.SMBus(1)
output_scaling = [(0, 10.0)] * 5
while True:
start = time.time()
gps_values = gpsd.get_gps_values()
digital_values = get_digital_values(i2c, 0x38)
analog_values = get_analog_values(i2c, 0x08, output_scaling)
save_values(gps_values, digital_values, analog_values, "/home/pi/Ana_Value.csv")
time.sleep(start + delay - time.time())
do_logging(5)
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 11. Mai 2016, 10:26
von chrisxx8
Hey vielen dank für deine Mühe:)
habe das programm jetzt fürs erste soweit lauffähig bekommen, aber tunen werde ich weiter hin.
Also die CSV Datei hat nun GPS Werte Analogwerte sowie Binärwerte mit drin. Jetzt möchte ich die Datei nun auf einen FTP Server schicken (dieser ist schon soweit eingerichtet). Ich arbeite hierfür mit der ftplib.
Das Programm steht auch schon.
Es passiert allerdings garnichts wenn ich es starte.
Was mir aber schon aufgefallen ist, wenn ich diese ("ftp.******.de") Daten falsch angebe, kommt wenigstens eine Fehlermeldung
"gaierror:[Errno -2] Name or service not known"
Wo kann ich nun anpacken? Das Programm sollte eig ok sein?
Code: Alles auswählen
#! /usr/bin/python
import ftplib
meinftp = ftplib.FTP("ftp.******.de") #Bei der Erzeugung einer FTP-Instanz kann
#auch Nutzername und Passwort mit übergeben
#werden.
meinftp.login("*****","******")
if login == '230 Login successful.':
print "login ok"
ftp.cdw('debian')
ftp.retrlines('LIST')
else:
print "login not ok"
directory = '/homes/****' #ftp-Hauptverzeichnis
meinftp.cwd(directory) #Wir nutzen das Hauptverzeichnis des ftp-Servers.
directory_local='/home/pi/' #lokales Upload-Verzeichnis
print "ftp: So sieht der Inhalt von ",directory, " vor dem Upload aus:"
print
meinftp.retrlines('LIST')
filename = 'Ana_Value.csv'
print
print 'Ort und Name der lokalen Datei: ' + directory_local + filename
print
file = open(directory_local+filename, 'rb') #Lesemodus binär.
print 'Upload: ftp-Server: ' + directory +filename
#'STOR ' das geeignete ftp_Kommando
meinftp.storbinary('Stor '+filename, file) #Es wird die Datei mit
# dem Namen test.txt aus dem Hauptverzeichnis des Servers in die lokale
# Datei mit dem Namen test2.txt im Verzeichnis E:/ geschrieben.
print "ftp: So sieht der Inhalt von ",directory, " nach dem Upload aus:"
print
meinftp.retrlines('LIST')
print
print 'Die lokale Datei ' + directory_local+filename +' wird geschlossen.'
file.close()
print meinftp.quit() #"höfliches" Trennen meinerseits der ftp-Verbindung
print
print 'Die FTP-Verbindung wurde von mir getrennt.'
Re: Mit Timer (Intervall) eine csv datei schreiben/erweitern
Verfasst: Mittwoch 11. Mai 2016, 10:31
von BlackJack
@chrisxx8: Lies doch einfach mal die Fehlermeldung durch die vom Compiler kommt wenn Du versuchst das zu starten.
