Grüße euch,
ich schraube gerade an einem Script, welches mir von einer Regenmengenmessung (ESP + Wippe + Tasmota) die Zählungen in Regenmengen umrechnet, dann in die ein oder andere CSV schreibt.
Sowie die Werte aus der CSV plottet und als Bild abspeichert.
Die Werte sollen von heute und gestern dynamisch auf einer Webseite angezeigt werden. Genauso die daraus geplotteten Bilder.
Die Werte werden mir angezeigt, leider aber nicht das Bild.
Hat jemand Erfahrung mit Flask und könnte mir erklären wie man sowas macht?
Python
import csv
import json
import paho.mqtt.client as mqtt
import pandas as pd
import schedule
import matplotlib.pyplot as plt
from datetime import datetime, timedelta, date
from flask import Flask, render_template
from functools import partial
from loguru import logger
from pathlib import Path
from time import sleep
from threading import Thread
def get_yesterday_date():
yesterday = date.today() - timedelta(days=1)
return yesterday.strftime("%d-%m-%Y")
PATHS_WITH_DATES = {
"today":
Path(f"/home/pi/Wetterstation/Regenmenge_csv/taegliche_messungen/{datetime.now().strftime('%d-%m-%Y')}"),
"yesterday":
Path(f"/home/pi/Wetterstation/Regenmenge_csv/taegliche_messungen/{get_yesterday_date()}"),
"monthly":
Path(f"/home/pi/Wetterstation/Regenmenge_csv/montaliche_zusammenfassung/{datetime.now().strftime('%m-%Y')}"),
}
HOST = "192.168.178.51"
#flask
app = Flask(__name__)
FLASK_PORT = 5001
DEBUG = False
#mqtt
MQTT_PORT = 1883
KEEPALIVE = 60
TOPIC = "tele/Wetterstation/SENSOR"
CMND_TOPIC = "cmnd/Wetterstation/Counter"
CMND = 0
"""
Berechnung Faktor für Regenmenge:
0,00165 Liter (tick pro Zaehlung)/ 0,055 m² (Flaeche Regenmesser) * 10 = Faktor in l/m²
"""
FAKTOR = 0.3
@logger.catch
@app.route("/")
def index():
with (open(PATHS_WITH_DATES["yesterday"].with_suffix(".csv")) as yesterday_csv,
open(PATHS_WITH_DATES["today"].with_suffix(".csv")) as today_csv,
open (PATHS_WITH_DATES["yesterday"].with_suffix(".jpg")) as yesterday_img):
return render_template("index.html", today_csv=today_csv,
yesterday_csv=yesterday_csv, yesterday_img=yesterday_img)
@logger.catch
@app.route("/Monatsansicht")
def monthly_site():
pass
@logger.catch
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client.subscribe(TOPIC)
@logger.catch
def payload_to_json(client, userdata, msg):
change_dictionary(json.loads(msg.payload.decode("utf-8")))
@logger.catch
def change_dictionary(json_dic):
measure_values = {"Time": datetime.now().strftime("%d-%m-%Y %H:%M")}
for key, value in json_dic["COUNTER"].items():
measure_values[key] = value
calculate_amount_of_rain(measure_values)
@logger.catch
def calculate_amount_of_rain(dic):
dic["Regenmenge"] = round(dic["C1"] * FAKTOR, 1)
dataframe = [dic]
write_to_csv(dataframe, PATHS_WITH_DATES["today"])
@logger.catch
def get_last_row_csv():
read = pd.read_csv(PATHS_WITH_DATES["yesterday"].with_suffix(".csv"))
last_row = read.tail(1)
write_to_csv(last_row, PATHS_WITH_DATES["monthly"])
@logger.catch
def check_file_exists():
for path_date in PATHS_WITH_DATES.values():
in not path_date.with_suffix(".csv").exists():
create_csv_file(path_date)
@logger.catch
def write_to_csv(dic, path_date):
check_file_exists()
writer = pd.DataFrame(dic)
writer.to_csv(path_date.with_suffix(".csv"), mode="a", index=False, header=False)
plot_csv(path_date)
@logger.catch
def plot_csv(path_date):
data = pd.read_csv(path_date.with_suffix(".csv"), sep=",")
data.plot(x="Zeit", y="Regenmenge")
plt.savefig(path_date.with_suffix(".jpg"))
plt.close()
@logger.catch
def create_csv_file(path_date):
with open(path_date.with_suffix(".csv"), "w") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(["Zeit", "Zähler", "Regenmenge"])
@logger.catch
def reset_counter(client):
client.publish(CMND_TOPIC, CMND)
@logger.catch
def schedule_thread():
while True:
schedule.run_pending()
sleep(1)
@logger.catch
def main():
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = payload_to_json
client.connect(host=HOST, port=MQTT_PORT, keepalive=KEEPALIVE)
client.loop_start()
schedule.every().day.at("00:01").do(get_last_row_csv)
schedule.every().day.at("00:00").do(partial(reset_counter, client))
thread = Thread(target=schedule_thread, daemon=True)
thread.start()
app.run(host=HOST, port=FLASK_PORT, debug=DEBUG)
if __name__ == "__main__":
main()
Alles anzeigen
HTML
<!doctype html>
<html>
<head>
<link rel="stylesheet" href='/static/style.css' />
<h1>Regenmengen</h1>
</head>
<body>
<main>
<figure>
<img src="{{yesterday_img}}" alt="plot_yesterday" width="150" height="100">
</figure>
<table id="Gestern">
<caption>Gestern</caption>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
{% for row in yesterday_csv %}
<tr>
{% for col in row.split(",") %}
<td>{{ col }}<td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<table id="Heute">
<caption>Heute</caption>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
{% for row in today_csv %}
<tr>
{% for col in row.split(",") %}
<td>{{ col }}<td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</main>
</body>
</html>
Alles anzeigen
CSS
body{
font-family: Arial, Helvetica, sans-serif;
}
img {
width: 100%;
max-width: 500px;
height: auto;
}
@media (min-width: 25em) {
img {
width: 50%;
float: right;
margin: 0 0 1em 1em;
}
}
@media (min-width: 50em) {
img {
width: 25%;
}
}
table {
float: left;
border-collapse: separate;
border-spacing: .2em;
margin-left: 2em;
box-shadow: 0 0 .1em #666;
position: relative;
z-index: 1;
}
tbody{
text-align: center;
}
caption {
color: white;
background: hsl(13, 96%, 39%);
font-size: 1.5em;
box-shadow: .1em .1em .1em 0 hsl(0, 0, 50%);
padding: .2em .2em .2em 2em;
width: 10em;
margin-left: -.6em;
position: relative;
}
caption::before {
content: "";
position: absolute;
display: block;
height: 0;
width: 0;
top: 1em;
left: -.6em;
border-style: solid;
border-width: .6em;
border-color: transparent hsl(13, 96%, 35%) transparent transparent;
z-index: -1;
}
tbody tr:hover, tfoot tr:hover {
background-color:#fffbf0;
}
tbody td:hover, tfoot td:hover {
background-color: #fce4a2;
}
Alles anzeigen