diff --git a/code/ausgabe.txt b/code/ausgabe.txt new file mode 100644 index 0000000..3586d60 --- /dev/null +++ b/code/ausgabe.txt @@ -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 + diff --git a/code/auswertung.py b/code/auswertung.py new file mode 100755 index 0000000..2d6a4c3 --- /dev/null +++ b/code/auswertung.py @@ -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) diff --git a/figures/Urkunde.png b/figures/Urkunde.png new file mode 100644 index 0000000..52978de Binary files /dev/null and b/figures/Urkunde.png differ diff --git a/figures/logo.png b/figures/logo.png new file mode 100644 index 0000000..bc69f39 Binary files /dev/null and b/figures/logo.png differ diff --git a/hardware.tex b/hardware.tex index 5b60d5d..0c1635c 100644 --- a/hardware.tex +++ b/hardware.tex @@ -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} \ No newline at end of file diff --git a/main.pdf b/main.pdf index a180ea8..cb54863 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.tex b/main.tex index 1b908c0..19515f4 100644 --- a/main.tex +++ b/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 diff --git a/praesentationen.tex b/praesentationen.tex index adbdcbc..ef3b300 100644 --- a/praesentationen.tex +++ b/praesentationen.tex @@ -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} diff --git a/references-biblatex.bib b/references-biblatex.bib index f20d563..de99649 100644 --- a/references-biblatex.bib +++ b/references-biblatex.bib @@ -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}, diff --git a/software.tex b/software.tex index a177b5c..9393d5b 100644 --- a/software.tex +++ b/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} \ No newline at end of file diff --git a/template/preamble.tex b/template/preamble.tex index ea2d3dd..8e6c1f8 100644 --- a/template/preamble.tex +++ b/template/preamble.tex @@ -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