## Data Collection
Keine Batterie hält ewig - nun möchten wir wissen, wie lange unsere Batterie Strom liefert, und wieviel Energie wir praktisch nutzen konnten, bis sie leer ist. Aus der Physik wissen wir, dass $Spannung\cdot{}Strom$ die Leistung unserer Batterie (bzw. die Leistungsaufnahme der Leuchte) ergibt. Wenn wir die Leistung über die ganze Lebensdauer unseres Systems aufzeichnen, wissen wir, wieviel Arbeit die Batterie insgesamt geleistet hat.
### Ziel
Schreibe Python-Code wie folgt. Falls die nötigen Python-Kenntnisse noch nicht vorhanden sind, folgst du den untenstehenden Tutorials.
* Datei `batterie.csv` im Schreibmodus öffnen.
* Eine Schleife ausführen, die alle zehn Sekunden die Strom- und Spannungswerte ausliest.
* Für jede Lesung wird eine Zeile (en. _record_) in die Datei geschrieben im folgenden Format:
`, , `
* also zum Beispiel (für eine Messung von $U = 1.37V$ und $I = 300mA$):
`2024-06-13 14:08:37.375, 1.37, 0.3`
++++Lösung|
from datetime import datetime
import time
from gdx import gdx
gdx = gdx.gdx()
gdx.open(connection='usb')
gdx.select_sensors()
gdx.start()
interval = 10 # Miss alle 10s
with open('batterie.csv', 'w') as outfile:
# Kopfzeile der Tabelle schreiben
outfile.write('Zeitstempel,Spannung,Strom\n')
while True:
timestamp = datetime.now()
measurements = gdx.read() # Liste von Messwerten
if measurements == None:
break
voltage = measurements[0]
current = measurements[1]
# Wir messen, bis die Spannung unter 0.05V fällt
if voltage < 0.05:
break
line = f'{timestamp},{voltage},{current}\n'
outfile.write(line)
time.sleep(interval)
gdx.stop()
gdx.close()
++++
### Tutorials
#### Python: Sensoren auslesen
**Einmalig** muss in Python die `godirect` Bibliothek installiert werden ([Anleitung](https://vernierst.github.io/godirect-examples/python/#install-the-vernier-godirect-module)). Führe auf der Kommandozeile bzw. im Terminal folgenden Befehl aus:
pip3 install godirect
Anschliessend hat Python Zugriff auf die verwendeted _godirect_ Sensoren. Der folgende Code liest 5 Messwerte vom via USB angeschlossenen Sensor und gibt sie auf der Konsole aus:
from gdx import gdx
gdx = gdx.gdx()
gdx.open(connection='usb')
gdx.select_sensors()
gdx.start()
for i in range(5):
measurements = gdx.read()
if measurements == None:
break
print(measurements)
gdx.stop()
gdx.close()
##### Aufgabe
Schliesse deinen Spannungs-Sensor an und führe obigen Code aus. Die gemessene Spannung sollte nahe bei null sein.
#### Python: Datei Ein- und Ausgabe
Wie lesen wir Daten in einer Text-Datei?
# Opens a file for writing (and closes it again after the 'with').
with open('dateiname.csv', 'w') as outfile:
for i in range(10):
line = 'Zeile ' + str(i) + '\n'
outfile.write(line)
Beachte:
* Wenn Dateien gelesen oder geschrieben werden, müssen sie beim Betriebssystem reserviert werden. Mit `with` wird sichergestellt, dass die Datei nicht offen bleibt sondern nach dem Lesevorgang wieder geschlossen wird.
* Die Datei (hier 'dateiname.csv') muss sich im gleichen Ordner befinden wie die Python-Datei.
* `'w'` bedeutet *write*, also, dass die Textdatei nicht nur gelesen sondern auch beschrieben wird.
* `str()` verwandelt die Zahl in einen Text.
* `'\n'` ist der ASCII-Code für einen Zeilenumbruch.
##### Aufgabe
Beschreibe eine Datei mit einigen Zeilen. Es ist ungünstig, mehr als einige zehntausend Zeilen zu schreiben...
#### Python: Schlafen
Wir wollen nur alle zehn Sekunden einen neuen Record schreiben, aber der Computer ist viel schneller. Zwischen den Messungen schlafen wir also:
import time
duration = 3
print(f'Hello, I will sleep for {duration} seconds!')
time.sleep(duration)
print('Yawn, just woke up!')
##### Aufgabe
Führe den obigen Code aus. Ändere ihn so ab, dass der Schlaf nur noch $2.5s$ dauert!
#### Python: Zeitstempel formatieren
Zeitstempel können aus der `datetime` Bibliothek geholt werden:
from datetime import datetime
print(datetime.now())
Mit Python f-Strings können mehrere Argumente praktisch in einen String gepackt werden:
from datetime import datetime
timestamp = datetime.now()
planet = 'Alderaan'
magnitude = 'great'
print(f'At {timestamp}, there was a {magnitude} disturbance in the Force on planet {planet}!')
##### Aufgabe
Ändere den Code so ab, dass eine _small_ disturbance auf dem Planet _Coruscant_ rapportiert wird.
(Du weisst nicht, was mit _Alderaan_ oder _Coruscant_ oder der [[https://starwars.fandom.com/wiki/Disturbance_in_the_Force|Disturbance in the Force]] gemeint ist? -> [[wpde>Star Wars]] schauen bis zur nächsten Lektion!)
#### CSV-Format
Unsere Log-Datei ist im [[wpde>CSV_(Dateiformat)|Comma-Separated-Values]] Format gespeichert: Die Daten sind ganz ähnlich gespeichert wie in einer Tabelle und können auch mit Excel und Sheets geöffnet werden. Jede Zeile entspricht einer Zeile der Tabelle; die Spalten sind meist mit Kommas voneinander getrennt. Manchmal werden aber auch Semikolons oder ein Tabulator (`\t`) als Trennzeichen verwendet.
Oft werden in der ersten Zeile die Namen der abgespeicherten Werte festgelegt:
Zeitstempel,Spannung,Strom
2024-06-13 14:08:37.375, 1.37, 0.301
2024-06-13 14:08:47.105, 1.35, 0.295
...
##### Aufgabe
Schreibe Code, der drei Zeilen ähnlich wie oben in eine CSV-Datei schreibt. Verwende f-Strings um die drei Werte auszugeben.