{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "26d70186",
   "metadata": {},
   "source": [
    "# Aqua Cycle – Proof of Concept\n",
    "\n",
    "Dieses Jupyter-Notebook dient als separate technische Abgabe zum Kapitel 5 der Abschlussarbeit. Es zeigt vereinfacht, wie Aqua Cycle Sensordaten, Wetterdaten und Stammdaten kombiniert, um eine Bewässerungsempfehlung sowie Kennzahlen zur Regenwassernutzung zu berechnen.\n",
    "\n",
    "Der Proof of Concept ist keine vollständige produktive Softwarelösung. Er zeigt die zentrale Entscheidungslogik des geplanten Backend-Systems."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfbbc81e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Aqua Cycle – Proof of Concept\n",
    "\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc36a400",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 1. Grundannahmen und Konfiguration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0967ebc6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "CONFIG = {\n",
    "    \"stadion_name\": \"Pilotanlage Aqua Cycle\",\n",
    "    \"rasenflaeche_m2\": 7140,          # Standard-Fussballfeld ca. 105 x 68 m\n",
    "    \"dachflaeche_m2\": 5000,           # Beispielhafte nutzbare Dachfläche\n",
    "    \"tank_kapazitaet_l\": 350_000,      # Referenzwert ähnlich Praxisbeispiel TSG Hoffenheim\n",
    "    \"abflussbeiwert\": 0.80,            # Anteil des Niederschlags, der gesammelt werden kann\n",
    "    \"wasserbedarf_mm\": 4.0,            # 4 Liter pro m² entsprechen 4 mm Bewässerung\n",
    "    \"min_bodenfeuchtigkeit_pct\": 35,   # Unter diesem Wert wird Bewässerung geprüft\n",
    "    \"min_tankstand_pct\": 30,           # Mindestfüllstand für automatische Bewässerung\n",
    "    \"regenwahrscheinlichkeit_grenze\": 60,\n",
    "    \"regenmenge_grenze_mm\": 3.0,\n",
    "    \"wasserpreis_chf_pro_m3\": 2.50\n",
    "}\n",
    "\n",
    "print(\"Konfiguration geladen:\")\n",
    "CONFIG"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "61283b47",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 2. Beispielhafte Sensor- und Wetterdaten erzeugen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8713f78",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "np.random.seed(42)\n",
    "\n",
    "dates = pd.date_range(start=\"2026-06-01\", periods=14, freq=\"D\")\n",
    "\n",
    "data = pd.DataFrame({\n",
    "    \"datum\": dates,\n",
    "    \"tankstand_pct\": np.random.randint(25, 90, size=len(dates)),\n",
    "    \"bodenfeuchtigkeit_pct\": np.random.randint(20, 65, size=len(dates)),\n",
    "    \"regenwahrscheinlichkeit_pct\": np.random.randint(10, 90, size=len(dates)),\n",
    "    \"erwarteter_regen_mm\": np.round(np.random.uniform(0, 12, size=len(dates)), 1),\n",
    "    \"temperatur_c\": np.round(np.random.uniform(18, 33, size=len(dates)), 1)\n",
    "})\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a5c65cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 3. Berechnungsfunktionen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2929a65f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "def berechne_wasserbedarf_l(rasenflaeche_m2: float, wasserbedarf_mm: float) -> float:\n",
    "    \"\"\"Berechnet den Wasserbedarf in Litern. 1 mm Niederschlag entspricht 1 Liter pro m².\"\"\"\n",
    "    return rasenflaeche_m2 * wasserbedarf_mm\n",
    "\n",
    "\n",
    "def berechne_sammelbares_regenwasser_l(dachflaeche_m2: float, regen_mm: float, abflussbeiwert: float) -> float:\n",
    "    \"\"\"Berechnet, wie viel Regenwasser theoretisch über die Dachfläche gesammelt werden kann.\"\"\"\n",
    "    return dachflaeche_m2 * regen_mm * abflussbeiwert\n",
    "\n",
    "\n",
    "def berechne_tankinhalt_l(tankstand_pct: float, tank_kapazitaet_l: float) -> float:\n",
    "    \"\"\"Berechnet den aktuellen Tankinhalt in Litern.\"\"\"\n",
    "    return tank_kapazitaet_l * (tankstand_pct / 100)\n",
    "\n",
    "\n",
    "def entscheide_bewaesserung(row: pd.Series, config: dict) -> str:\n",
    "    \"\"\"Leitet aus Sensor- und Wetterdaten eine Bewässerungsempfehlung ab.\"\"\"\n",
    "    boden_trocken = row[\"bodenfeuchtigkeit_pct\"] < config[\"min_bodenfeuchtigkeit_pct\"]\n",
    "    tank_genug = row[\"tankstand_pct\"] >= config[\"min_tankstand_pct\"]\n",
    "    regen_erwartet = (\n",
    "        row[\"regenwahrscheinlichkeit_pct\"] >= config[\"regenwahrscheinlichkeit_grenze\"]\n",
    "        or row[\"erwarteter_regen_mm\"] >= config[\"regenmenge_grenze_mm\"]\n",
    "    )\n",
    "\n",
    "    if not boden_trocken:\n",
    "        return \"Keine Bewässerung nötig: Bodenfeuchtigkeit ausreichend.\"\n",
    "    if regen_erwartet:\n",
    "        return \"Bewässerung pausieren: Regen wird erwartet.\"\n",
    "    if not tank_genug:\n",
    "        return \"Bewässerung nicht empfohlen: Tankfüllstand zu tief.\"\n",
    "    return \"Bewässerung empfohlen: Bedingungen sind geeignet.\"\n",
    "\n",
    "\n",
    "def berechne_kennzahlen(row: pd.Series, config: dict) -> pd.Series:\n",
    "    \"\"\"Berechnet Wasserbedarf, Tankinhalt, Regenwassermenge und Einsparungen.\"\"\"\n",
    "    wasserbedarf_l = berechne_wasserbedarf_l(\n",
    "        config[\"rasenflaeche_m2\"],\n",
    "        config[\"wasserbedarf_mm\"]\n",
    "    )\n",
    "    tankinhalt_l = berechne_tankinhalt_l(\n",
    "        row[\"tankstand_pct\"],\n",
    "        config[\"tank_kapazitaet_l\"]\n",
    "    )\n",
    "    sammelbares_regenwasser_l = berechne_sammelbares_regenwasser_l(\n",
    "        config[\"dachflaeche_m2\"],\n",
    "        row[\"erwarteter_regen_mm\"],\n",
    "        config[\"abflussbeiwert\"]\n",
    "    )\n",
    "\n",
    "    empfehlung = entscheide_bewaesserung(row, config)\n",
    "    bewaesserung_empfohlen = empfehlung.startswith(\"Bewässerung empfohlen\")\n",
    "\n",
    "    regenwasser_genutzt_l = min(wasserbedarf_l, tankinhalt_l) if bewaesserung_empfohlen else 0\n",
    "    trinkwasser_einsparung_m3 = regenwasser_genutzt_l / 1000\n",
    "    kosteneinsparung_chf = trinkwasser_einsparung_m3 * config[\"wasserpreis_chf_pro_m3\"]\n",
    "\n",
    "    return pd.Series({\n",
    "        \"wasserbedarf_l\": wasserbedarf_l,\n",
    "        \"tankinhalt_l\": tankinhalt_l,\n",
    "        \"sammelbares_regenwasser_l\": sammelbares_regenwasser_l,\n",
    "        \"bewässerungsempfehlung\": empfehlung,\n",
    "        \"regenwasser_genutzt_l\": regenwasser_genutzt_l,\n",
    "        \"trinkwasser_einsparung_m3\": trinkwasser_einsparung_m3,\n",
    "        \"kosteneinsparung_chf\": kosteneinsparung_chf\n",
    "    })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7239172",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 4. Proof-of-Concept ausführen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ce0ff3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "resultate = pd.concat([data, data.apply(lambda row: berechne_kennzahlen(row, CONFIG), axis=1)], axis=1)\n",
    "resultate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "40cb9f7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 5. Zusammenfassung der Ergebnisse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eaec2b42",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "zusammenfassung = {\n",
    "    \"Anzahl Tage\": len(resultate),\n",
    "    \"Bewässerung empfohlen an Tagen\": int(resultate[\"bewässerungsempfehlung\"].str.startswith(\"Bewässerung empfohlen\").sum()),\n",
    "    \"Total genutztes Regenwasser in Liter\": round(resultate[\"regenwasser_genutzt_l\"].sum(), 2),\n",
    "    \"Total Trinkwassereinsparung in m³\": round(resultate[\"trinkwasser_einsparung_m3\"].sum(), 2),\n",
    "    \"Geschätzte Kosteneinsparung in CHF\": round(resultate[\"kosteneinsparung_chf\"].sum(), 2),\n",
    "    \"Durchschnittlicher Tankstand in %\": round(resultate[\"tankstand_pct\"].mean(), 2),\n",
    "    \"Durchschnittliche Bodenfeuchtigkeit in %\": round(resultate[\"bodenfeuchtigkeit_pct\"].mean(), 2)\n",
    "}\n",
    "\n",
    "pd.DataFrame([zusammenfassung])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2117c2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 6. Visualisierung: Tankstand und Bodenfeuchtigkeit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f126334",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(resultate[\"datum\"], resultate[\"tankstand_pct\"], marker=\"o\", label=\"Tankstand (%)\")\n",
    "plt.plot(resultate[\"datum\"], resultate[\"bodenfeuchtigkeit_pct\"], marker=\"o\", label=\"Bodenfeuchtigkeit (%)\")\n",
    "plt.axhline(CONFIG[\"min_tankstand_pct\"], linestyle=\"--\", label=\"Mindest-Tankstand\")\n",
    "plt.axhline(CONFIG[\"min_bodenfeuchtigkeit_pct\"], linestyle=\"--\", label=\"Mindest-Bodenfeuchtigkeit\")\n",
    "plt.title(\"Aqua Cycle PoC: Sensorwerte über Zeit\")\n",
    "plt.xlabel(\"Datum\")\n",
    "plt.ylabel(\"Prozent\")\n",
    "plt.xticks(rotation=45)\n",
    "plt.legend()\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "91914b36",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 7. Visualisierung: Trinkwassereinsparung"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93ce803e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.bar(resultate[\"datum\"], resultate[\"trinkwasser_einsparung_m3\"])\n",
    "plt.title(\"Aqua Cycle PoC: Trinkwassereinsparung pro Tag\")\n",
    "plt.xlabel(\"Datum\")\n",
    "plt.ylabel(\"Einsparung in m³\")\n",
    "plt.xticks(rotation=45)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "171ceaa1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 8. Beispielhafte Ausgabe für die App"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b935c8f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "app_output = resultate[[\n",
    "    \"datum\",\n",
    "    \"tankstand_pct\",\n",
    "    \"bodenfeuchtigkeit_pct\",\n",
    "    \"regenwahrscheinlichkeit_pct\",\n",
    "    \"erwarteter_regen_mm\",\n",
    "    \"bewässerungsempfehlung\",\n",
    "    \"trinkwasser_einsparung_m3\",\n",
    "    \"kosteneinsparung_chf\"\n",
    "]].copy()\n",
    "\n",
    "app_output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45c3ba2e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "# 9. Optional: Ergebnisse als CSV exportieren"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a49c0c23",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ------------------------------------------------------------\n",
    "\n",
    "resultate.to_csv(\"aqua_cycle_poc_resultate.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "print(\"CSV-Datei wurde erstellt: aqua_cycle_poc_resultate.csv\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.x"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
