Compare commits

..

1 Commits

Author SHA1 Message Date
admin 38a43407b3 Merge branch 'main' into all_in_one
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 11:47:00 +02:00
2 changed files with 22 additions and 18 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[project] [project]
name = "weather2oag" name = "weather2oag"
version = "1.1.1" version = "1.1.0"
description = "Monatlicher Wetterbericht der Sternwarte Welzheim" description = "Monatlicher Wetterbericht der Sternwarte Welzheim"
requires-python = ">=3.12" requires-python = ">=3.12"
+21 -17
View File
@@ -4,7 +4,7 @@
import os import os
import smtplib import smtplib
import tempfile import tempfile
from collections import defaultdict
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from email.mime.image import MIMEImage from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
@@ -48,8 +48,8 @@ plt.rcParams.update({
def last_month_range() -> tuple[datetime, datetime, str]: def last_month_range() -> tuple[datetime, datetime, str]:
today = datetime.now(timezone.utc) today = datetime.now(timezone.utc)
first_of_this = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0) first_of_this = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
start = (first_of_this - timedelta(days=1)).replace(day=1, hour=0, minute=0, second=0, microsecond=0) end = first_of_this - timedelta(seconds=1)
end = first_of_this + timedelta(days=1) # inkl. 1. Folgemonat start = end.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
label = f"{MONTHS_DE[start.month - 1]} {start.year}" label = f"{MONTHS_DE[start.month - 1]} {start.year}"
return start, end, label return start, end, label
@@ -85,19 +85,23 @@ def _data_temp_hourly(start: datetime, end: datetime):
def _data_rain_daily(start: datetime, end: datetime): def _data_rain_daily(start: datetime, end: datetime):
today = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0) data = fetch("/weather/range", {
days = min((today - start).days + 2, 365) "start": start.isoformat(), "end": end.isoformat(), "limit": 50000,
data = fetch("/weather/rain-daily", {"days": days}) })
pairs = [] by_day: dict[str, list[float]] = defaultdict(list)
for d in data: for d in data:
day_dt = parse_dt(d["date"]).replace(hour=0, minute=0, second=0, microsecond=0) if d.get("rain") is not None:
if start <= day_dt < end: by_day[parse_dt(d["datetime"]).strftime("%Y-%m-%d")].append(d["rain"])
pairs.append((day_dt, round(d["total_rain"], 1)))
pairs.sort() dates, rain = [], []
if not pairs: for day_key in sorted(by_day):
return [], [] vals = by_day[day_key]
dates, rain = zip(*pairs) daily = max(vals) - min(vals)
return list(dates), list(rain) if daily < 0:
daily = max(vals)
dates.append(datetime.fromisoformat(day_key).replace(tzinfo=timezone.utc))
rain.append(round(daily, 1))
return dates, rain
def create_combined_chart(start: datetime, end: datetime, label: str) -> bytes: def create_combined_chart(start: datetime, end: datetime, label: str) -> bytes:
@@ -117,7 +121,7 @@ def create_combined_chart(start: datetime, end: datetime, label: str) -> bytes:
ax.fill_between(dates_mm, t_min, t_max, alpha=0.12, color="#888888") ax.fill_between(dates_mm, t_min, t_max, alpha=0.12, color="#888888")
ax.set_title("Temperaturverlauf (Tages-Min / Tages-Max)", fontweight="bold", pad=10) ax.set_title("Temperaturverlauf (Tages-Min / Tages-Max)", fontweight="bold", pad=10)
ax.set_ylabel("Temperatur (°C)") ax.set_ylabel("Temperatur (°C)")
ax.set_xlim(start - timedelta(hours=12), end + timedelta(hours=12)) ax.set_xlim(start, end)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d.%m.")) ax.xaxis.set_major_formatter(mdates.DateFormatter("%d.%m."))
ax.xaxis.set_major_locator(mdates.DayLocator(interval=3)) ax.xaxis.set_major_locator(mdates.DayLocator(interval=3))
plt.setp(ax.get_xticklabels(), rotation=0, ha="center") plt.setp(ax.get_xticklabels(), rotation=0, ha="center")
@@ -128,7 +132,7 @@ def create_combined_chart(start: datetime, end: datetime, label: str) -> bytes:
ax.plot(dates_h, temps, color="#2a7be0", linewidth=1.5, label="Stundenmittel") ax.plot(dates_h, temps, color="#2a7be0", linewidth=1.5, label="Stundenmittel")
ax.set_title("Temperaturverlauf (Stundenmittel)", fontweight="bold", pad=10) ax.set_title("Temperaturverlauf (Stundenmittel)", fontweight="bold", pad=10)
ax.set_ylabel("Temperatur (°C)") ax.set_ylabel("Temperatur (°C)")
ax.set_xlim(start - timedelta(hours=12), end + timedelta(hours=12)) ax.set_xlim(start, end)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d.%m.")) ax.xaxis.set_major_formatter(mdates.DateFormatter("%d.%m."))
ax.xaxis.set_major_locator(mdates.DayLocator(interval=3)) ax.xaxis.set_major_locator(mdates.DayLocator(interval=3))
plt.setp(ax.get_xticklabels(), rotation=0, ha="center") plt.setp(ax.get_xticklabels(), rotation=0, ha="center")