diff --git a/.gitignore b/.gitignore index ead8f0e..d1df722 100644 --- a/.gitignore +++ b/.gitignore @@ -569,6 +569,6 @@ FodyWeavers.xsd .idea/ *.sln.iml -dwd-data* -data/influxdb -data/influxdb/data \ No newline at end of file +#Docker Data +Anhang/Docker/data/influxdb/ +Anhang/data/influxdb/data/ diff --git a/Anhang/Docker/data/jupyLab/Grundlagen.ipynb b/Anhang/Docker/data/jupyLab/Grundlagen.ipynb new file mode 100644 index 0000000..9035b6c --- /dev/null +++ b/Anhang/Docker/data/jupyLab/Grundlagen.ipynb @@ -0,0 +1,240 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6801b26f-4bf6-46c0-8584-798ede2d0ff2", + "metadata": {}, + "source": [ + "# InfluxDB Grundlagen" + ] + }, + { + "cell_type": "markdown", + "id": "759f9eb6-5629-4e87-8c6a-043bcafc4f55", + "metadata": {}, + "source": [ + "Bevor mit InfluxDB gearbeitet werden kann muss als erstes die client library importiert werden. " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "43cf5e5c-9542-47ea-9205-89f97a217c51", + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "\n", + "from influxdb_client import InfluxDBClient, Point, WritePrecision\n", + "from influxdb_client.client.write_api import SYNCHRONOUS" + ] + }, + { + "cell_type": "markdown", + "id": "03668637-f4eb-422d-8d36-e59b13e75ad1", + "metadata": {}, + "source": [ + "Im nächsten Schritt müssen die Verbindungsdaten angegeben werden. Ein API Token kann im InfluxDB Webinterface angelegt werden. Der Bucket wird automatisch erstellt. Es kann allerdings auch ein eigener Bucket verwendet werden.\n", + "Als URL muss darauf geachtete werden die URL des Doker Conteiners zu nutzen in dem die Datenbank ausgeführt wird. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d6ae2ed0-3363-420f-81d5-56050591a50e", + "metadata": {}, + "outputs": [], + "source": [ + "token = \"klyDN4DRFvnRrbmNAEvTXdbP7goon9DBfSxN_1X2Us6AFFp6G5T0QNwgf7ucrRExwZomzhPInj68BjPw2gwXOQ==\"\n", + "org = \"test-org\"\n", + "bucket = \"test-bucked\"\n", + "url = \"http://influxdb:8086\"\n" + ] + }, + { + "cell_type": "markdown", + "id": "e4390ee6-e32c-4ef9-9e41-3bb47ee827fb", + "metadata": {}, + "source": [ + "Jetzt wird der InfluxDB Client erstellt." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0a3d1adf-5c17-4aa6-8296-bd6bf0d78dc8", + "metadata": {}, + "outputs": [], + "source": [ + "client = InfluxDBClient(\n", + " url=url, \n", + " token=token,\n", + " org=org\n", + ") " + ] + }, + { + "cell_type": "markdown", + "id": "ee8de7a5-722f-4b03-ab00-8aeea2f1a596", + "metadata": {}, + "source": [ + "## Daten in InfluxDB eintragen" + ] + }, + { + "cell_type": "markdown", + "id": "f6b75431-3767-46c4-85cd-baf0e772a9e3", + "metadata": {}, + "source": [ + "Um Daten zu schreiben wird ein Write Client genutzt. Dieser kann aus dem Client erstellt werden." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9015aa31-9bee-40db-b604-243c8f0b6ee9", + "metadata": {}, + "outputs": [], + "source": [ + "write_api = client.write_api(write_options=SYNCHRONOUS)" + ] + }, + { + "cell_type": "markdown", + "id": "038a43f6-4e70-407f-b7fe-9622178a7dbc", + "metadata": {}, + "source": [ + "Zuguterletzt kann dann ein Datenpunkt mit Demodaten hochgeladen werden." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7a557626-aaba-4ef4-8b4d-5ff2dd2840ef", + "metadata": {}, + "outputs": [], + "source": [ + "p = Point(\"my_measurement\").tag(\"location\", \"Prague\").field(\"temperature\", 25.3)\n", + "write_api.write(bucket=bucket, org=org, record=p)" + ] + }, + { + "cell_type": "markdown", + "id": "920bad93-6b76-4148-8e45-51954d895786", + "metadata": {}, + "source": [ + "# Daten aus InfluxDB abrufen" + ] + }, + { + "cell_type": "markdown", + "id": "94576801-e533-43f7-a12b-af435b0562a1", + "metadata": {}, + "source": [ + "Ähnlich wie zum schreiben von Daten wird für das abrufen von Daten ein extra query Client benötigt." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "59aaa184-b140-432d-8132-cbb179ce4543", + "metadata": {}, + "outputs": [], + "source": [ + "query_api = client.query_api()" + ] + }, + { + "cell_type": "markdown", + "id": "237b7c4c-b92d-4a4b-9864-38c96be54967", + "metadata": {}, + "source": [ + "Um die abzurufenden Daten festzulegen wird ein Flux Querry erstellt" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "cb28ce0d-5d9f-4090-a136-6fa7c8787974", + "metadata": {}, + "outputs": [], + "source": [ + "query = 'from(bucket:\"'+ bucket +'\")\\\n", + "|> range(start: -10m)\\\n", + "|> filter(fn:(r) => r._measurement == \"my_measurement\")\\\n", + "|> filter(fn: (r) => r.location == \"Prague\")\\\n", + "|> filter(fn:(r) => r._field == \"temperature\" )'" + ] + }, + { + "cell_type": "markdown", + "id": "140b5a02-f4d6-4b04-bd36-6ab8102a07fc", + "metadata": {}, + "source": [ + "Dieser query kann dann mit dem query client ausgeführt werden." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "34975883-fa02-469f-8a2a-cc3464ae6c92", + "metadata": {}, + "outputs": [], + "source": [ + "result = query_api.query(org=org, query=query)" + ] + }, + { + "cell_type": "markdown", + "id": "9076f045-e22d-4923-93d0-abcfd1cc5251", + "metadata": {}, + "source": [ + "Mithilfe einer Schleife können die Datenpunkte jetzt durchgegangen werden. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1c689c54-8215-41e3-97ca-6b6eed76d0fc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('temperature', 25.3), ('temperature', 25.3)]\n" + ] + } + ], + "source": [ + "results = []\n", + "for table in result:\n", + " for record in table.records:\n", + " results.append((record.get_field(), record.get_value()))\n", + "\n", + "print(results)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Anhang/Docker/data/jupyLab/InfluxDB.ipynb b/Anhang/Docker/data/jupyLab/InfluxDB.ipynb deleted file mode 100644 index 1ca6d69..0000000 --- a/Anhang/Docker/data/jupyLab/InfluxDB.ipynb +++ /dev/null @@ -1,132 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5b285400-a3a1-410e-9e20-6df4f5e2429e", - "metadata": {}, - "source": [ - "# Influxdb\n" - ] - }, - { - "cell_type": "markdown", - "id": "8101cd24-d68a-422c-a81a-6c7c81fa08c1", - "metadata": {}, - "source": [ - "Influx DB ist eine Zeitserien Datenbank.\n", - "Zum Schreiben und lesen von Daten in der Datenbank gibt es 2 verschiedene Schnitstellen. Eine SQL ähnliche Kommandosprache InfluxQl und eine funktionale Sprache Flux\n", - "\n", - "Der Influxdb containr ist über http://localhost:8086 erreichbar" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c60534da", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "ee8de7a5-722f-4b03-ab00-8aeea2f1a596", - "metadata": {}, - "source": [ - "## Daten in InfluxDB eintragen\n", - "Als erstes den Client initialisieren" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "de26a902-5d7d-4db6-a62d-9a6287c60df4", - "metadata": {}, - "outputs": [], - "source": [ - "from datetime import datetime\n", - "\n", - "from influxdb_client import InfluxDBClient, Point, WritePrecision\n", - "from influxdb_client.client.write_api import SYNCHRONOUS\n", - "\n", - "# You can generate an API token from the \"API Tokens Tab\" in the UI\n", - "token = \"wb4s191jc33JQ4a6wK3ZECwrrG3LuSyQd61akFa_q6ZCEsequUvFhL9Gre6FaZMA2ElCylKz26ByJ6RetkQaGQ==\"\n", - "org = \"test-org\"\n", - "bucket = \"dwd\"\n", - "url = \"http://influxdb:8086\"\n", - "\n", - "with InfluxDBClient(url=\"http://influxdb:8086\", token=token, org=org) as client:\n", - " write_api = client.write_api(write_options=SYNCHRONOUS)\n", - " data = \"mem,host=host1 used_percent=23.43234543\"\n", - " write_api.write(bucket, org, data)\n", - "client.close()\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "28ebb2bd-2efe-49b7-a4e9-2ad8dd48ce79", - "metadata": {}, - "source": [ - "Daten schreiben" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b2a761f7-9541-4935-9ccd-e467214e9ea5", - "metadata": {}, - "outputs": [], - "source": [ - "client = InfluxDBClient(url=url, token=token, org=org)\n", - "\n", - "\n", - "write_api = client.write_api(write_options=SYNCHRONOUS)\n", - "query_api = client.query_api()\n", - "\n", - "a = datetime(2017, 11, 28, 23, 55, 59)\n", - "\n", - "p = Point(\"my_measurement\").tag(\"location\", \"Prague\").field(\"temperature\", 25.3).time(a,WritePrecision.S)\n", - "\n", - "write_api.write(bucket=bucket, record=p)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00dffb4c-2f82-440c-9ed0-cbd441751031", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f513259d-3bfb-46df-9beb-d1c7dcb5a875", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/Anhang/Docker/data/jupyLab/Wetterdaten-Import.ipynb b/Anhang/Docker/data/jupyLab/Wetterdaten-Import.ipynb index e53118c..9384e87 100644 --- a/Anhang/Docker/data/jupyLab/Wetterdaten-Import.ipynb +++ b/Anhang/Docker/data/jupyLab/Wetterdaten-Import.ipynb @@ -404,7 +404,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.10.4" } }, "nbformat": 4, diff --git a/Anhang/Docker/docker-compose.yml b/Anhang/Docker/docker-compose.yml index 5eb6ccf..3f483e2 100644 --- a/Anhang/Docker/docker-compose.yml +++ b/Anhang/Docker/docker-compose.yml @@ -11,8 +11,6 @@ services: JUPYTER_ENABLE_LAB: "yes" JUPYTER_TOKEN: "fhdw" RESTARTABLE: "yes" - depends_on: - - mariadb influxdb: image: influxdb @@ -21,7 +19,7 @@ services: environment: DOCKER_INFLUXDB_INIT_MODE: "setup" DOCKER_INFLUXDB_INIT_USERNAME: "admin" - DOCKER_INFLUXDB_INIT_PASSWORD: "Wetter123!" + DOCKER_INFLUXDB_INIT_PASSWORD: "e1LjSYaFbzbJeIBC" DOCKER_INFLUXDB_INIT_ORG: "test-org" DOCKER_INFLUXDB_INIT_BUCKET: "test-bucked" volumes: diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/00/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/00/0000 deleted file mode 100644 index b4d3ed8..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/00/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/01/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/01/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/01/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/02/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/02/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/02/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/03/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/03/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/03/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/04/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/04/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/04/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/05/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/05/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/05/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/06/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/06/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/06/0000 and /dev/null differ diff --git a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/07/0000 b/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/07/0000 deleted file mode 100644 index a23a49d..0000000 Binary files a/Anhang/data/influxdb/data/engine/data/5184a5854bc602a0/_series/07/0000 and /dev/null differ diff --git a/arbeit/Thesis.pdf b/arbeit/Thesis.pdf index 07dff7e..9ad26d6 100644 Binary files a/arbeit/Thesis.pdf and b/arbeit/Thesis.pdf differ diff --git a/arbeit/chapter/Einleitung.tex b/arbeit/chapter/Einleitung.tex index 82b9734..86c5e0f 100644 --- a/arbeit/chapter/Einleitung.tex +++ b/arbeit/chapter/Einleitung.tex @@ -5,7 +5,7 @@ Das Ziel dieser Arbeit ist es eine Einführung in die Funktion von \gls{TSDB} zu geben. Außerdem soll beispielhaft an InfluxDB gezeigt werden, wie mit einer \gls{TSDB} gearbeitet wird. -Dazu werden die Wetterdaten des \gls{DWD} in InfluxDB importiert und ausgewertet. +Dazu werden die Wetterdaten des \glspl{DWD} in InfluxDB importiert und ausgewertet. \subsection{Aufbau und Vorgehensweise} diff --git a/arbeit/chapter/InfluxDB.tex b/arbeit/chapter/InfluxDB.tex index 43d8c20..db008bc 100644 --- a/arbeit/chapter/InfluxDB.tex +++ b/arbeit/chapter/InfluxDB.tex @@ -8,28 +8,24 @@ eigene Anwendungen ein \gls{HTTP} \gls{API} zur Verfügung, für die es in viele \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 erfolgreich ausgeführt worden ist InfluxDB erfolgreich 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. - - - -% -% Bis hierhin korrigiert! -% - - -%\subsection{{Installation}} - -%\subsection{InfluxDB Webinterface} - -%InfluxDB stellt für die einfache Verwaltung ein Web \gls{UI} zur verfügung. In diesem Interface ist es möglich +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. Bein anlegen kann noch eine +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 Listing~\ref{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 @@ -56,12 +52,15 @@ measurementName,tagKey=tagValue fieldKey="fieldValue" 1465839830100400200 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 +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}} +\subsubsection{Python library} + + %https://docs.influxdata.com/influxdb/cloud/security/tokens/#all-access-token \subsection{{Daten abrufen}} diff --git a/arbeit/config/Abkuerzungen.tex b/arbeit/config/Abkuerzungen.tex index a066186..3014749 100644 --- a/arbeit/config/Abkuerzungen.tex +++ b/arbeit/config/Abkuerzungen.tex @@ -1,5 +1,5 @@ \newacronym{TSDB}{TSDB}{Time Series Database} -\newacronym{DWD}{DWD}{Deutscher Wetterdienst} +\newacronym[\glslongpluralkey={Deutschen Wetterdienstes}]{DWD}{DWD}{Deutscher Wetterdienst} \newacronym{DBMS}{DBMS}{Datenbank Management System} \newacronym{IOT}{IOT}{Internet of Things} \newacronym{RDBMS}{RDBMS}{Relational Database Management System}