\section{{InfluxDB}}

InfluxDB ist eine in Go geschriebene open source \gls{TSDB}, die darauf ausgelegt ist, mit einer großen Menge an Time Series Data zu arbeiten.\footnote{\cite[vgl.][]{dbranking}}
Im weiterem verlauf dieses Kapitels wird am Beispiel von Wetterdaten gezeigt, wie mit InfluxDB gearbeitet wird. InfluxDB stellt für die Integration in 
eigene Anwendungen ein \gls{HTTP} \gls{API} zur Verfügung, für die es in vielen Programmiersprachen Client Librarys gibt. Außerdem wird ein Webinterface und ein \gls{CLI} bereitgestellt.
\footnote{\cite[vgl.][]{InfluxAPI}}


\subsection{{InfluxDB Installation}}

Bevor InfluxDB genutzt werden kann muss es als erstes installiert werden. Am einfachsten ist dies über Docker möglich. Dazu ist es notwendig das Docker und Docker Compose auf dem System installiert sind. 
Mit Docker Desktop lassen sich die  beide Tools am einfachsten installieren. Im Anhang dieser Arbeit befindet sich im Ordner Docker eine Docker Compose Datei mit dem Namen docker-compose.yml. 
Zum Starten der benötigten Container ist es am einfachsten mit einem Terminal (Powershell, xterm usw.) in den Docker Ordner zu wechseln und den Befehl docker compose up -d auszuführen. 
Jetzt beginnt docker damit die notwendigen Images herunterzuladen und zu bauen. Wenn der Befehl ohne Fehler ausgeführt worden ist InfluxDB installiert worden und kann 
über die URL:\ \url{http://localhost:8086} aufgerufen werden. Die Login Daten sind als Umgebungsvariable in Docker Compose definiert und lauten: admin e1LjSYaFbzbJeIBC. 

Außerdem wurde mit diesem Befehl auch ein Jupyter Notebook in einem Docker Container gestartet. Auf diesen Container kann über die URL:\ \url{http://localhost:8888/} 
zugegriffen werden. Das Passwort lautet fhdw. Im Ordner DWD befinden sich die Notebooks mit dem in dieser Arbeit beschrieben Code.

\subsection{{Daten einfügen}}

In InfluxDB werden Daten immer in Buckets gespeichert. Um Daten hochzuladen, muss zunächst ein Bucket angelegt werden. Dazu gibt es zwei 
Möglichkeiten. Die Einfachste ist es, über das Web \gls{UI} von InfluxDB einen neuen Bucket anzulegen. Dazu muss nach dem Login der Navigationspunkt Data 
und der Reiter Buckets ausgewählt werden. Hier kann dann mit dem Button Create Bucket ein neuer Bucket angelegt werden. Bei dem Anlegen kann noch eine 
Lebensdauer für die Daten ausgewählt werden, nach welcher die jeweiligen Datenpunkte gelöscht werden.\footnote{vgl. \cref{fig:dashboard}, \cref{fig:load-data-source}, \cref{fig:load-data-bucket}, \cref{fig:load-data-add-bucket}}

\subsubsection{Line Protokoll}

Daten werden immer nach dem InfluxDB Line Protokoll formatiert an die Datenbank gesendet. Das Protokoll ist wie in \cref{list:lineproto}
dargestellt aufgebaut. Im ersten Teil des Line Protokolls wird der Name der Messreihe angegeben. Das kann zum Beispiel der Name des Sensors sein oder
der Ort an dem der Messwert genommen wurde. Wichtig ist, dass Groß und Kleinschreibung beachtet werden muss und Unterstriche nicht
genutzt werden dürfen. Sonderzeichen müssen mit einem \textbackslash \  %Bachslash mit Leerzeichen
maskiert werden. Nach dem Namen kommen getrennt durch ein Komma die Tags der Messung. 
Tags werden indexiert und dazu genutzt, um Messwerte zu durchsuchen. Tags werden als Key Value Paar angegeben. Hier sollen Metadaten wie 
zum Beispiel der Standort des Sensors oder der Name des Servers eingetragen werden, zu dem die Datenpunkt/e gehören. Die eigentlichen Werte sind mit einem 
Leerzeichen von den Tags abgegrenzt und bestehen aus durch Kommas getrennten Key Value Feldern. Der letzte Wert einer Zeile ist der Unix Timestamp in Millisekunden. 
In einer Datei oder Anfrage kann es mehrere Zeilen mit Daten geben.\footnote{\cite[vgl.][]{InfluxDBLineProtolkoll}}
%Quelle https://docs.influxdata.com/influxdb/v2.2/reference/syntax/line-protocol/
%Quelle https://docs.influxdata.com/influxdb/v2.2/reference/syntax/line-protocol/#naming-restrictions

\begin{figure}[bht]
\begin{lstlisting}[caption=InfluxDB Line Protokoll {Quelle: \cite[][]{InfluxDBLineProtolkoll}}, label=list:lineproto],
measurementName,tagKey=tagValue fieldKey="fieldValue" 1465839830100400200
--------------- --------------- --------------------- -------------------
       |               |                  |                    |
  Measurement       Tag set           Field set            Timestamp
\end{lstlisting}
\end{figure}
%Quelle https://docs.influxdata.com/influxdb/v2.2/reference/syntax/line-protocol/
%Quelle https://docs.influxdata.com/influxdb/v2.2/reference/syntax/line-protocol/#naming-restrictions

Die im Line Protokoll formatierten Daten können jetzt entweder mithilfe eines Rest Requests oder des InfluxDB \gls{CLI} in die Datenbank übertragen werden.
Um diese Anfragen zu autorisieren muss ein \gls{API} Token mitgesendet werden.\footnote{\cite[vgl.][]{InfluxDBWriteAPI}}
Um einen Token zu bekommen, kann dieser entweder über das Webinterface, die \gls{CLI} oder über die \gls{API} angelegt werden. Der einfachste Weg ist es, 
den Token über das Webinterface anzulegen. Dazu wird wie beim Anlegen eines Buckets zunächst der Menüpunkt Data ausgewählt und anschließend der Reiter API 
Tokens. Mit einem Klick auf Generate API Token kann dann ein API Token erstellt werden.\footnote{vgl. \cref{fig:dashboard}, \cref{fig:load-data-source}, \cref{fig:load-data-api-token}, \cref{fig:load-data-add-token}}
Dabei kann zwischen einem All-Access token und einem Read/Write token ausgewählt werden. Mit dem All Access Token kann auf alles zugegriffen werden. 
Mit einem Read/Write Token kann wie in \cref{fig:load-data-add-token} zu sehen, ausgewählt werden, auf welchen Bucket geschrieben oder gelesen werden kann.\footnote{\cite[vgl.][]{InfluxDBToken}} 

\subsection{{Daten abrufen}}



%InfluxDB QUerrys Flux

\subsection{Python library}

Um nicht selbst eigene API Anfragen über die Rest API schreiben zu müssen gibt es für Python und andere Sprachen fertige 
Bibliotheken.\footnote{\cite[vgl.][]{InfluxAPIClientLibs}} Bevor mit der Client Library gearbeitet werden kann muss diese als erste 
Installiert und importiert werden. Am besten wird zur Installation der Python Paketmanager pip genutzt. Mit dem Befehl pip install influxdb-client
werden alle benötigten Packte installiert. 

In \cref{list:influxPythonWrite} kann an einem Beispiel gesehen werden wie Daten mithilfe von Python in die Datenbank geschrieben
werden. Ein ähnliches Beispiel findet sich ausführbar und detailliert beschreiben im Jupyter Notebook. In der ersten beiden
Zeile des Codes wird der InfluxDB Client importiert. Danach werden in Zeile vier bis sieben die benötigten Daten bucket, 
Organisation, Token und URL in Variablen geschrieben. Was in die Variablen eingetragen werden muss wird im 
Kapitel Daten einfügen %eventuell Link einfügen?
beschreiben. 

In Zeile neun bis 13 wird der Client mit den hinterlegen Variablen initialisiert. Danach folgt in Zeile 15 die 
Initialisierung des write clients. Als nächstes muss ein Datenbank erstellt werden der in die Datenbank geschrieben werden kann. 
Dazu wird in Zeile 17 bis 19 der Datenpunkt erstellt. An diesen Datenpunkt kann eine beliebige Menge an Tags und Datenfeldern
über die Methoden tag und field angehängt werden. Hier im Beispiel wird der Datenpunkt my\_measurement mit dem Tag location angelegt,
welcher den Wert Paderborn hat, und dem Datenpunkt temperature mit dem Wert 25,3 angelegt. In der letzten Zeile wird dann 
der write client dazu genutzt um diesen Datenbank an die Datenbank zu senden. 

\subsection{{Daten verarbeiten und visualisieren}}

%InfluxDB Tasks 
% InfluxDB Graphen

\subsection{{weitere InfluxDB-Funktionen}}

% Monitoring und Alamierung mit InfluxDB
% InfluxDB Notebooks


\subsection{{Wetterdaten}} 

\subsubsection{{Wetterdaten Aufbau}}

Die Wetterdaten des DWD können über den CDC OpenData Bereich heruntergeladen werden. Hier werden die Wetterdaten über FTP und HTTPS zum Download 
angeboten. Unter der URL \url{https://www.dwd.de/DE/leistungen/cdc/cdc_ueberblick-klimadaten.html} wird eine gute Übersicht über die zum
Download angeboten Daten geboten. Die Werte für die aktuelle Lufttemperatur können über 
\url{https://opendata.dwd.de/climate_environment/CDC/observations_germany/climate/10_minutes/air_temperature/now/}
abgerufen werden. Historische Daten können über 
\url{https://opendata.dwd.de/climate_environment/CDC/observations_germany/climate/10_minutes/air_temperature/now/} 
abgerufen werden. 

Aktuell werden auf der Webseite, für die aktuelle Lufttemperatur, ca 480 Dateien zum Download angeboten. Die meisten dieser Dateien entsprechen jeweils 
einer Messstation und je nach Tageszeit kann deswegen die Menge der Zeilen in der Datei variieren, weil immer um 00:00 eine neue Datei angefangen wird.
In den Zip-Dateien finden sich außerdem Metadaten über die Messtationen. Die eigentlichen Daten sind als \gls{CSV} formatiert und sehen aus wie in Listing~\ref{list:wetter_csv} gekürzt dargestellt
In der \gls{CSV} Datei gibt es 9 Felder. Der Inhalt der Felder wird in \cref{tab:csv-explenation} beschreiben.

%Eventuell kürzen wenn zu viele Seiten
\begin{figure}[bht]
    \begin{lstlisting}[caption=Wetterdaten CSV {Quelle: DWD Wetterdaten CSV Download}, label=list:wetter_csv]
    STATIONS_ID;MESS_DATUM;  QN;PP_10;TT_10;TM5_10;RF_10;TD_10;eor
    73;202205120000;    2;   -999;  12.9;  11.2;  84.2;  10.3;eor
    73;202205120010;    2;   -999;  12.7;  11.2;  84.9;  10.2;eor
    73;202205120020;    2;   -999;  12.9;  11.4;  83.0;  10.1;eor
    73;202205120030;    2;   -999;  12.4;  10.7;  86.9;  10.3;eor
    73;202205120040;    2;   -999;  12.4;  10.5;  86.2;  10.2;eor
    73;202205120050;    2;   -999;  12.3;  10.3;  85.5;   9.9;eor
    73;202205120100;    2;   -999;  12.1;  10.1;  88.1;  10.2;eor
    73;202205120110;    2;   -999;  11.7;   9.9;  90.1;  10.1;eor
    73;202205120120;    2;   -999;  11.7;  10.0;  89.0;  10.0;eor
    \end{lstlisting}
\end{figure}

\begin{table}[hbt]
\centering
\begin{minipage}[t]{1\textwidth} % Breite, z.B. 1\textwidth		
\caption{Bedeutung der CSV Felder} % Überschrift
\begin{tabularx}{\columnwidth}{rXrr}
\toprule
Feld Name & Bedeutung \\
\midrule
STATION\_ID & Gibt an von welcher Station die Werte stammen  \\ \hline
MESS\_DATUM & Gibt an wann gemessen wurde im Format \%Y\%m\%d\%H\%M. Also Jahr Monat Tag Stunde Minute als eine zusammengeschriebene Zahl. \\ \hline
QN &  Gibt die Qualität der Messwerte an. Hier gibt es die Werte 1 bis 3
    \begin{compactenum}
        \item nur formale Kontrolle bei Dekodierung und Import
        \item Kontrolle mit individuell festgelegten Kriterien
        \item ROUTINE automatische Kontrolle und Korrektur mit Software (QUALIMET)
    \end{compactenum} \\ \hline
PP\_10 & Luftdruck auf Stationshöhe \\ \hline
TT\_10 & Lufttemperatur auf 2m Höhe \\ \hline
TM5\_10 & Lufttemperatur auf 5cm Höhe \\ \hline
TD\_10 & relative Luftfeuchtigkeit auf 2m Höhe \\ \hline
eor & END OF RECORD" Bedeutet die Zeile ist zu Ende. \\
\bottomrule
\end{tabularx}
\source{Eigene Darstellung \url{https://opendata.dwd.de/climate_environment/CDC/observations_germany/climate/10_minutes/air_temperature/now/BESCHREIBUNG_obsgermany_climate_10min_tu_now_de.pdf}} % Quelle
\label{tab:csv-explenation}
\end{minipage}
\end{table}

In der Datei zehn\_now\_tu\_Beschreibung\_Stationen.txt werden die Wetterstationen beschrieben. Diese Datei ist nicht als \gls{CSV} Datei formatiert sondern als Tabelle und erhält
Daten über die Wetterstationen. Die Daten der Stationen in der heruntergeladenen Textdatei stimmen mit den Daten der Hauptamtliches Messnetz Karte überein. 
Allerdings enthält die Textdatei nicht alle Stationen sondern nur Station für die auch Messwerte im Datensatz hinterlegt sind. Die Bedeutung der einzelnen
Spalten der Tabelle sind in der \cref{tab:file-stations} beschreiben.

\begin{table}[hbt]
    \centering
    \begin{minipage}[t]{1\textwidth} % Breite, z.B. 1\textwidth		
    \caption{Bedeutung Stationstabellen Felder} % Überschrift
    \begin{tabularx}{\columnwidth}{rXrr}
    \toprule
    Feld Name & Bedeutung \\
    \midrule
    STATION\_ID & Gibt an von welcher Station die Werte stammen  \\ \hline
    von\_datum  & Datum seit dem die Station aktiv ist. \\ \hline
    bis\_datum  & Hohe der Station. \\ \hline
    Stationshoehe  & Hohe über dem Normalnullpunkt \\ \hline
    geoBreite  & Breitengrad der Station. \\ \hline
    geoLaenge \_10 & Längengrad der Stations. \\ \hline
    Stationsname   & Name der Station. \\ \hline
    Bundesland & Bundesland in dem die Station steht. \\
    \bottomrule
    \end{tabularx}
    \source{Vergleich der Werte mit der Hauptamtliches Messnetz Karte \url{https://opendata.dwd.de/climate_environment/CDC/observations_germany/climate/10_minutes/air_temperature/now/zehn_now_tu_Beschreibung_Stationen.txt}} % Quelle
    \label{tab:file-stations}
    \end{minipage}
\end{table}


%\pagebreak %Damit die Tabelle nicht auf der falschen Seite ist.
\subsubsection{{Wetterdaten abrufen}}

Um die Daten auswerten zu können müssen diese als erstes heruntergeladen und entpackt werden. Dazu wird mithilfe von BeautifulSoup aus der \gls{HTML} Seite 
des \gls{DWD} für jede Datei eine URL ausgelesen. Die so gewonnen URLs können dann mithilfe einer Schleife heruntergeladen werden.
Um den Messwerten eine Station zuzuordnen zu können wird als erstes die Datei mit den Station verarbeitet. Für jede Station wird Objekt erstellt und in ein
dictionary gespeichert. Dadurch kann in im dictionary einfach über die STATIONS\_ID die passende Station gefunden werden. Weil diese Datei allerdings nicht 
CSV formatiert ist musst die Datei auf eine andere Art ausgewertete werden. Um die einzelnen Felder aus einer Zeile zu bekommen wird immer so lange 
gelesen bis wieder ein bestimmte Anzahl von Leerzeichen hintereinander erkannt worden ist. Die Zeichen zwischen den Leerzeichen sind dann ein ausgelesenes Feld. 
Nachdem die Stationsdaten ausgewertet worden sind, werden die CSV Datein in einer Schleife entpackt und mithilfe der Bibliothek Pandas in ein Dataframe 
umgewandelt. Das so erzeugte Dataframe wir im letzten Schritt mit den Daten der Stations zusammengeführt und als Datenpunkt in InfluxDB geschrieben.
Weitere Erklärungen und der Code selbst kann im angehängten Jupyter notebook eingesehen und ausgeführt werden. 

\subsubsection{{Wetterdaten Verarbeiten}}