Compare commits

...

4 Commits

Author SHA1 Message Date
admin f4fa3df73a Version 1.1.1: Regen via /weather/rain-daily, days relativ zu heute
- Regenberechnung nutzt neuen API-Endpunkt statt kumulativem Rohzähler
- days-Parameter relativ zu heute: funktioniert korrekt auch bei
  Aufruf mitten im Monat (z.B. 5.6. → zeigt trotzdem Mai komplett)
- Erster Tag des Folgemonats weiterhin im Chart sichtbar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:54:24 +02:00
admin db8feb317e Erster Tag des Folgemonats wird im Chart mit angezeigt
Ermöglicht korrekte Regenberechnung für den letzten Monatstag:
der Abschlusswert des kumulativen Zählers liegt oft erst im
Mitternachtswert des 1. Folgemonats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:30:13 +02:00
admin 91f4a7e4d2 Fix: Regen letzter Monatstag fehlt (kumulativer Zähler)
Query um +1 Tag erweitert, damit der erste Wert des Folgetags als
Abschlusswert für den letzten Tag verfügbar ist. Ohne diesen Wert
liefert max-min = 0 wenn der Zähler nur einmal pro Tag aktualisiert wird.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:22:00 +02:00
admin 37127fada3 Fix: 31. des Monats fehlt – API-End auf Monatsersten (exklusiv) gesetzt
end = first_of_this (Juni 1 00:00) statt May 31 23:59:59, damit APIs
mit exklusivem End-Parameter alle Tage des letzten Monats liefern.
Zusätzlich ±12h Padding auf xlim der Linien-Charts (wie Balkendiagramm).

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