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. :-)