diverses in Software
This commit is contained in:
parent
407b4e5fa2
commit
20f3feb4fe
11 changed files with 269 additions and 19 deletions
62
code/ausgabe.txt
Normal file
62
code/ausgabe.txt
Normal file
|
@ -0,0 +1,62 @@
|
|||
in Spalte 5 Zeile 6828 ist ein Ausreisser (7.5)
|
||||
in Spalte 5 Zeile 43508 ist ein Ausreisser (25.5)
|
||||
in Spalte 5 Zeile 43515 ist ein Ausreisser (25.5)
|
||||
in Spalte 5 Zeile 43629 ist ein Ausreisser (25.5)
|
||||
in Spalte 5 Zeile 43636 ist ein Ausreisser (25.5)
|
||||
in Spalte 6 Zeile 6828 ist ein Ausreisser (5.0)
|
||||
in Spalte 6 Zeile 30728 ist ein Ausreisser (87.2)
|
||||
in Spalte 10 Zeile 885 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 891 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 919 ist ein Ausreisser (2000.0)
|
||||
in Spalte 10 Zeile 2399 ist ein Ausreisser (5900.0)
|
||||
in Spalte 10 Zeile 2402 ist ein Ausreisser (5968.0)
|
||||
in Spalte 10 Zeile 2407 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 2408 ist ein Ausreisser (5952.0)
|
||||
in Spalte 10 Zeile 2416 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 3321 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 5917 ist ein Ausreisser (0.0)
|
||||
in Spalte 10 Zeile 27470 ist ein Ausreisser (5191.0)
|
||||
in Spalte 10 Zeile 27873 ist ein Ausreisser (5780.0)
|
||||
in Spalte 10 Zeile 31148 ist ein Ausreisser (3487.0)
|
||||
in Spalte 10 Zeile 40646 ist ein Ausreisser (5961.0)
|
||||
Bitte Datum im Format 'DD.MM.YY HH:MM:SS' eingeben
|
||||
Es sollte zwischen 22.02.14 10:24:30 und 13.03.14 14:54:50 liegen
|
||||
von: 22.02.14 10:30:00
|
||||
bis: 30.02.14 00:00:00
|
||||
Bitte Datum im Format 'DD.MM.YY HH:MM:SS' eingeben
|
||||
bis: 13.03.14 14:00:00
|
||||
Der Messwert geht von Zeile 14 bis Zeile 50353 und über folgenden Zeitraum: 19 days, 3:30:00
|
||||
------Mittelwerte------
|
||||
Innentemperatur: 24.40
|
||||
Gerätetemperatur 1: 26.34
|
||||
Außentemperatur: 9.38
|
||||
Gerätetemperatur 2: 26.34
|
||||
Temperatur (Luft): 11.18
|
||||
Luftfeuchtigkeit: 50.90
|
||||
Luftdruck : 989.33
|
||||
Temperatur (Druck): 11.31
|
||||
Prozessor : 51.92
|
||||
Qualität : 2154.99
|
||||
------Minimum-Maximum------
|
||||
Innentemperatur: 17.187 26.437
|
||||
Gerätetemperatur 1: 19.687 30.5
|
||||
Außentemperatur: 0.687 32.687
|
||||
Gerätetemperatur 2: 19.687 30.5
|
||||
Temperatur (Luft): 1.1 25.5
|
||||
Luftfeuchtigkeit: 0.0 89.5
|
||||
Luftdruck : 966.99 1005.38
|
||||
Temperatur (Druck): 1.2 24.4
|
||||
Prozessor : 32.0 57.8
|
||||
Qualität : 0.0 6001.0
|
||||
------Standardabweichung------
|
||||
Innentemperatur: 0.90
|
||||
Gerätetemperatur 1: 0.94
|
||||
Außentemperatur: 6.33
|
||||
Gerätetemperatur 2: 0.94
|
||||
Temperatur (Luft): 6.55
|
||||
Luftfeuchtigkeit: 19.34
|
||||
Luftdruck : 11.31
|
||||
Temperatur (Druck): 6.48
|
||||
Prozessor : 1.58
|
||||
Qualität : 1245.77
|
||||
|
151
code/auswertung.py
Executable file
151
code/auswertung.py
Executable file
|
@ -0,0 +1,151 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import csv
|
||||
import math
|
||||
from datetime import datetime # aus dem Modul datetime Datentyp datetime (Datum und Zeit) importieren
|
||||
bis_roh = "2014/02/01 22:1:00"
|
||||
|
||||
namen = ["Innentemperatur", "Gerätetemperatur 1", "Außentemperatur", "Gerätetemperatur 2", "Temperatur (Luft)", "Luftfeuchtigkeit", "Luftdruck\t", "Temperatur (Druck)", "Prozessor\t", "Qualität\t"]
|
||||
format = "%Y/%m/%d %H:%M:%S"
|
||||
eingabeformat = "%d.%m.%y %H:%M:%S"
|
||||
von_roh = "2014/02/01 18:12:42"
|
||||
|
||||
|
||||
def offnen(datei):
|
||||
with open(datei) as filein:
|
||||
reader = csv.reader(filein, quoting = csv.QUOTE_NONNUMERIC)
|
||||
global liste # Liste außerhalb von Funtion nutzen
|
||||
liste = list(zip(*reader)) # = [temp1,temp2,temp3,temp4,luft_temp,luft_feucht,druck,temp_druck,rasp]
|
||||
|
||||
def ausreisser(spalte):
|
||||
zeilenanzahl = len(spalte) - 1
|
||||
i = 0
|
||||
|
||||
while i < zeilenanzahl:
|
||||
if (spalte[i] != "") and (spalte[i + 1] != "") and (spalte[i - 1] != ""):
|
||||
diff1 = spalte[i] - spalte[i + 1]
|
||||
diff2 = spalte[i] - spalte[i - 1]
|
||||
if ((diff1 < -schwankung) or (diff1 > schwankung)) and ((diff2 < -schwankung) or (diff2 > schwankung)):
|
||||
print("in Spalte " + str(liste.index(spalte) + 1) + " Zeile " + str(i + 1) + " ist ein Ausreisser (" + str(spalte[i]) + ")")
|
||||
ausreisserliste.append((liste.index(spalte), i))
|
||||
# else:
|
||||
# print("Passt:" + str(i),str(diff1),str(diff2))
|
||||
i += 1
|
||||
|
||||
def mittelwert(spalte):
|
||||
summe = 0
|
||||
anzahl = 0 # Anzahl der Messwerte
|
||||
for wert in spalte:
|
||||
if wert != "":
|
||||
summe = summe + wert # zur bisherigen Summe addieren
|
||||
anzahl += 1
|
||||
mittelwert = summe / anzahl
|
||||
return mittelwert
|
||||
|
||||
def minmax(spalte):
|
||||
mini = spalte[0] # Minimum auf ersten Wert setzen
|
||||
maxi = spalte[0]
|
||||
for wert in spalte:
|
||||
if wert != "":
|
||||
if wert < mini:
|
||||
mini = wert
|
||||
if wert > maxi:
|
||||
maxi = wert
|
||||
return (mini, maxi)
|
||||
|
||||
def standardabweichung(spalte, mw):
|
||||
n = 0
|
||||
summe = 0
|
||||
for wert in spalte:
|
||||
if wert != "":
|
||||
term = wert - mw
|
||||
summe = summe + (term * term)
|
||||
n += 1
|
||||
stab = math.sqrt(summe / n)
|
||||
return stab
|
||||
|
||||
def datum_offnen():
|
||||
datei = open("datum.csv", "r")
|
||||
global inhalt
|
||||
inhalt = datei.readlines()
|
||||
datei.close()
|
||||
def datumsauswahl(von, bis):
|
||||
|
||||
start_gefunden = False
|
||||
stop_gefunden = False
|
||||
for datum in inhalt:
|
||||
datum_py = datetime.strptime(datum.rstrip(), format)
|
||||
if (datum_py > von) and (start_gefunden == False):
|
||||
start = inhalt.index(datum)
|
||||
start_gefunden = True
|
||||
if (start_gefunden == True) and (datum_py > bis) and (stop_gefunden == False):
|
||||
stop = inhalt.index(datum) - 1
|
||||
stop_gefunden = True
|
||||
break
|
||||
if(stop_gefunden != True) or (start_gefunden != True):
|
||||
print("Entweder ist der Endzeitpunkt vor dem Startzeitpunkt oder die beiden liegen zu nahe an den Grenzwerten.")
|
||||
exit(1)
|
||||
print("Der Messwert geht von Zeile " + str(start) + " bis Zeile " + str(stop) + " und über folgenden Zeitraum: " + str(bis - von))
|
||||
return start, stop
|
||||
|
||||
def datumsfrage(frage):
|
||||
while True:
|
||||
eingabe_roh = input(frage)
|
||||
try:
|
||||
eingabe = datetime.strptime(eingabe_roh, eingabeformat)
|
||||
except ValueError:
|
||||
print("Bitte Datum im Format 'DD.MM.YY HH:MM:SS' eingeben")
|
||||
else:
|
||||
return eingabe
|
||||
|
||||
offnen("vorbereitet.csv")
|
||||
datum_offnen()
|
||||
spalten_nummer = 0
|
||||
ausreisserliste = []
|
||||
for spalte in liste:
|
||||
if (spalten_nummer == 9):
|
||||
schwankung = 1000
|
||||
else:
|
||||
schwankung = 10
|
||||
ausreisser(spalte)
|
||||
spalten_nummer += 1
|
||||
print("Bitte Datum im Format 'DD.MM.YY HH:MM:SS' eingeben")
|
||||
print("Es sollte zwischen " + datetime.strptime(inhalt[1].rstrip(), format).strftime(eingabeformat) + " und " + datetime.strptime(inhalt[-1].rstrip(), format).strftime(eingabeformat) + " liegen")
|
||||
von = datumsfrage("von: ")
|
||||
bis = datumsfrage("bis: ")
|
||||
startstop = datumsauswahl(von, bis)
|
||||
von = startstop[0]
|
||||
bis = startstop[1]
|
||||
liste_auswahl = []
|
||||
for spalte in liste:
|
||||
spalte_neu = spalte[von:bis]
|
||||
liste_auswahl.append(spalte_neu)
|
||||
liste = liste_auswahl
|
||||
print("------Mittelwerte------")
|
||||
mittelwerte = [] # leere Liste erstellen
|
||||
for spalte in liste:
|
||||
mw = mittelwert(spalte) # jeden MW ausrechnen ...
|
||||
mittelwerte.append(mw) # ... und an die Liste anhängen
|
||||
mittelausgabe = zip(namen, mittelwerte) # in Tupel umwandeln [(Innentemperatur, 25), (Außentemperatur,8)]
|
||||
for name, mittelwert in mittelausgabe:
|
||||
print(name + ":\t%0.2f" % mittelwert) # jedes Tupel ausgeben
|
||||
|
||||
print("------Minimum-Maximum------")
|
||||
minima = []
|
||||
maxima = []
|
||||
for spalte in liste:
|
||||
minumax = minmax(spalte)
|
||||
mini = minumax[0]
|
||||
maxi = minumax[1]
|
||||
minima.append(mini)
|
||||
maxima.append(maxi)
|
||||
minmaxausgabe = zip(namen, minima, maxima)
|
||||
for name, minimum, maximum in minmaxausgabe:
|
||||
print(name + ":\t" + str(minimum) + "\t" + str(maximum))
|
||||
print("------Standardabweichung------")
|
||||
standardabweichungen = []
|
||||
for spalte in liste:
|
||||
abweichung = standardabweichung(spalte, mittelwerte[liste.index(spalte)]) # Mittelwert über Stelle in Liste herausfinden
|
||||
standardabweichungen.append(abweichung)
|
||||
stabausgabe = zip(namen, standardabweichungen)
|
||||
for name, abweichung in stabausgabe:
|
||||
print(name + ":\t%0.2f" % abweichung)
|
BIN
figures/Urkunde.png
Normal file
BIN
figures/Urkunde.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
BIN
figures/logo.png
Normal file
BIN
figures/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -125,3 +125,4 @@ Da jedoch fix angelötete Kabel unflexibel sind, bin ich auf ein Display von \em
|
|||
|
||||
\section{Anschluss}
|
||||
\label{sec:Anschluss}
|
||||
\todo[inline]{Kapitel über Gehäuse, Platinen, Zusammenbau}
|
BIN
main.pdf
BIN
main.pdf
Binary file not shown.
10
main.tex
10
main.tex
|
@ -23,12 +23,6 @@
|
|||
%% and right pages (twoside) or you create a document which is printed
|
||||
%% on right pages only (oneside).
|
||||
|
||||
\newcommand{\mydraft}{false}
|
||||
%% "true" or "false"
|
||||
%% Use draft mode? If true, included graphics are replaced by empty
|
||||
%% rectangles (of same size) and overfull boxes (in margin space) are
|
||||
%% marked with black box (-> easy to spot!)
|
||||
|
||||
\newcommand{\myparskip}{half}
|
||||
%% e.g., "no", "full", "half", ...
|
||||
%% How to separate paragraphs: indention ("no") or spacing ("half",
|
||||
|
@ -243,6 +237,10 @@
|
|||
\hyphenpenalty=3000 % weniger Wort-Trennungen
|
||||
\tolerance=1000
|
||||
|
||||
\clubpenalty=1000
|
||||
\widowpenalty=1000
|
||||
\displaywidowpenalty=1000
|
||||
|
||||
|
||||
%% ========================================================================
|
||||
%%%% MISC self-defined commands and settings
|
||||
|
|
|
@ -11,4 +11,4 @@ Ein Monat später erfuhr ich, dass ich im Finale bin\footnote{\href{http://blog.
|
|||
Anschließend schrieb ich im Sommer einen Artikel für das OCG Journal.\footnote{\href{http://www.ocg.at/sites/ocg.at/files/medien/pdfs/OCG-Journal1403.pdf}{OCG Journal 3/2014: Seite 33 (www.ocg.at/sites/ocg.at/files/medien/pdfs/OCG-Journal1403.pdf)}}
|
||||
|
||||
Am 6. Oktober 2014 durfte ich mein Projekt der Arbeitsgruppe \textit{Bildung, Wissenschaft und Forschung} am \textsf{3. IKT-Konvent} präsentieren.\footnote{\href{http://www.internetoffensive.at/3-ikt-konvent}{www.internetoffensive.at/3-ikt-konvent}}
|
||||
\includepdf[pages={1},draft]{figures/Urkunde.pdf}
|
||||
\includepdf[pages={1}]{figures/Urkunde.png}
|
||||
|
|
|
@ -235,6 +235,17 @@
|
|||
Timestamp = {2014.12.14}
|
||||
}
|
||||
|
||||
@Online{wiki:wunderground,
|
||||
Title = {Weather Underground (weather service) --- Wikipedia{,} The Free Encyclopedia},
|
||||
Author = {Wikipedia},
|
||||
Date = {2014-12-12},
|
||||
Url = {http://en.wikipedia.org/w/index.php?title=Weather_Underground_(weather_service)&oldid=637705817},
|
||||
Urldate = {2015-01-03},
|
||||
|
||||
Owner = {lukas},
|
||||
Timestamp = {2014.12.14}
|
||||
}
|
||||
|
||||
@Online{wiki:bus,
|
||||
Title = {Bus--- Wikipedia{,} Die freie Enzyklopädie},
|
||||
Author = {Wikipedia},
|
||||
|
|
48
software.tex
48
software.tex
|
@ -101,10 +101,10 @@ Einer der wichtigsten Teile des Projektes ist die grafische Auswertung. Diese ka
|
|||
|
||||
Auf der Webseite des Raspberry Pi können die aktuellen Messwerte angezeigt und grafisch eranschaulicht werden. Hierzu wird alle 5 Sekunden mithilfe von \gls{Javascript} die Datei \emph{text\_ws.txt} nachgeladen und ausgewertet. Zusätzlich zur Anzeige der Zahlenwerte werden die Messungen mithilfe von Balken und Farbverläufen angezeigt. Für ältere Browser gibt es auch eine einfache tabellarische Ansicht\footnote{\href{http://winkler.kremszeile.at/aktuell_einfach.html}{winkler.kremszeile.at/aktuell\_einfach.html}}
|
||||
|
||||
\subsubsection{Wetterrater}
|
||||
\subsubsection{Wetter-Rater}
|
||||
\label{subsubsec:Wetterrater}
|
||||
|
||||
Um die Daten auch anders zu nutzen habe ich einen \emph{Wetterrater} programmiert. Dieser versucht auf Basis von einfachen Berechnungen und Schätzungen das aktuelle Wetter zu \enquote{erraten}. So wird zum Beispiel die aktuelle Außentemperatur mit der nach Jahreszeit und Tageszeit zu erwartenden Temperatur verglichen, um Rückschlüsse auf den Bewölkungsgrad zu ziehen oder aufgrund der Luftfeuchtigkeit ermittelt, ob es Niederschlag gibt.
|
||||
Um die Daten auch anders zu nutzen habe ich einen \emph{Wetter-Rater} programmiert. Dieser versucht auf Basis von einfachen Berechnungen und Schätzungen das aktuelle Wetter zu \enquote{erraten}. So wird zum Beispiel die aktuelle Außentemperatur mit der nach Jahreszeit und Tageszeit zu erwartenden Temperatur verglichen, um Rückschlüsse auf den Bewölkungsgrad zu ziehen oder aufgrund der Luftfeuchtigkeit ermittelt, ob es Niederschlag gibt.
|
||||
|
||||
Hierzu wird zum Beispiel die Temperaturschwankung über einen Tag als Cosinusfunktion mit einer Schwankung von \SI{5}{\degreeCelsius} angenommen.
|
||||
$$ \textit{Temperaturerwartung} = -5 \cdot \cos\left(\frac{\text{Stunde}\cdot 2 \cdot \pi }{24}\right) + \textit{Mittlere Temperatur des Tages}; $$
|
||||
|
@ -128,7 +128,7 @@ $$ \textit{Temperaturerwartung} = -5 \cdot \cos\left(\frac{\text{Stunde}\cdot 2
|
|||
\end{figure}
|
||||
|
||||
|
||||
Der Wetterrater gibt drei Werte aus:
|
||||
Der Wetter-Rater gibt drei Werte aus:
|
||||
\begin{itemize}
|
||||
\item Tag oder Nacht
|
||||
\item Niederschlag (keiner/Gewitter/Schnee/Regen/Schneeregen)
|
||||
|
@ -181,16 +181,44 @@ Nun werden für jede Spalte bzw. für jeden Sensor der Mittelwert, das Minimum,
|
|||
|
||||
\code{ausgabe.txt}{}{29}{59}
|
||||
|
||||
|
||||
\section{diverses}
|
||||
\label{sec:diverses}
|
||||
|
||||
\subsection{autostart}
|
||||
\label{subsec:autostart}
|
||||
|
||||
\subsection{mitternacht.sh}
|
||||
\label{subsec:mitternacht.sh}
|
||||
\todo{eventuell entfernen}
|
||||
Abgesehen von den großen Teilen gibt es auch einige kleinere Aspekte, von denen ich nun einige vorstellen möchte:
|
||||
|
||||
\subsection{Weather Underground}
|
||||
\label{subsec:wunderground}
|
||||
|
||||
\emph{Weather Underground} ist ein Online-Wetterdienst mit Firmensitz in San Francisco.\footcite{wiki:wunderground} Dieser bietet auch die Möglichkeit eine eigene Wetterstation zu betreiben und die Daten auf ihrer Webseite anzuzeigen.\footnote{\href{http://www.wunderground.com/personal-weather-station/dashboard?ID=INIEDERS353}{www.wunderground.com/personal-weather-station/dashboard?ID=INIEDERS353}}
|
||||
Leider werden die Wetterdaten nur in imperialen Einheiten (also \si{\degree F} und \si{\mmHg}\footnote{Millimeter-Quecksilbersäule oder Torr}) akzeptiert. Daher werden die Messwerte vorher von einem \gls{Python}-Programm umgerechnet und anschließend hochgeladen.
|
||||
|
||||
\subsection{Autostart}
|
||||
\label{subsec:Autostart}
|
||||
|
||||
Damit die Umweltdatenmessung einfacher zu handhaben ist, gibt es ein einfaches Start-/Stop-Skript. So werden die Aufzeichnung und das Display automatisch beim Hochfahren gestartet und vor dem Herunterfahren ordnungsgemäß beendet.
|
||||
|
||||
\subsection{mitternacht.sh}
|
||||
\label{subsec:mitternacht.sh}
|
||||
|
||||
Da der Raspberry Pi in der Schule hängt und nicht von außerhalb erreicht werden kann, ist es schwierig Softwareänderungen anzuwenden. Daher habe ich das kleine Skript \emph{mitternacht.sh} geschrieben. Dieses startet täglich um 0:00 Uhr und lädt die neuerste Version von \gls{Github} und installiert diese. Zusätzlich werden auch das Betriebssystem und alle installierten Programme aktualisiert. Anschließend werde ich per Push-Benachrichtigung über etwaige Probleme benachrichtigt und der Raspberry Pi startet neu.
|
||||
|
||||
\subsection{sonstiges}
|
||||
\label{subsec:sonstiges}
|
||||
|
||||
\begin{itemize}
|
||||
\item ein Logo (siehe Abbildung \ref{fig:logo})
|
||||
\item Erstellung von statischen Diagrammen mit Gnuplot
|
||||
\begin{itemize}
|
||||
\item Jedoch bei zu vielen Daten unübersichtlich und langsam
|
||||
\end{itemize}
|
||||
\item Windows Vista/7 Gadget
|
||||
\item E-Mail und Push-Benachrichtigungen
|
||||
\item regelmäßiger Upload der Daten auf \href{http://winkler.kremszeile.at}{winkler.kremszeile.at}
|
||||
\end{itemize}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{figures/logo.png}
|
||||
\caption{Logo (eigenes Werk)}
|
||||
\label{fig:logo}
|
||||
\end{figure}
|
|
@ -371,8 +371,7 @@ appendixprefix=true, %% adds appendix prefix; only for book-classes with \backma
|
|||
bibliography=totoc, %% adds the bibliography to table of contents (without number)
|
||||
listof=totoc,
|
||||
index=totoc,
|
||||
draft=\mydraft, %% if true: included graphics are omitted and black boxes
|
||||
%% mark overfull boxes in margin space
|
||||
%draft,
|
||||
BCOR=\myBCOR, %% binding correction (depends on how you bind
|
||||
%% the resulting printout.
|
||||
\mylaterality %% oneside: document is not printed on left and right sides, only right side
|
||||
|
|
Reference in a new issue