From 4f89db49b6d7cbff24348b20a7215ddc8bf55956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20X=2E=20F=C3=BCrst?= Date: Tue, 19 May 2026 14:09:59 +0200 Subject: [PATCH] V 1.5.9 feat: Spalte 'source' (loop/archive/wview) in weather_data Co-Authored-By: Claude Sonnet 4.6 --- collector/main.py | 21 ++++++++++++--- frontend/package.json | 2 +- migrate_sqlite_to_postgres.py | 49 ++++++++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/collector/main.py b/collector/main.py index 7ebadeb..fb22e80 100644 --- a/collector/main.py +++ b/collector/main.py @@ -164,6 +164,9 @@ class WeatherDataInput(BaseModel): # Vorhersage forecast: Optional[int] = None + # Datenquelle + source: Optional[str] = None + # ---- Validatoren ----------------------------------------------------- @field_validator("tempOut", "temperature", "tempIn") @@ -229,6 +232,13 @@ class WeatherDataInput(BaseModel): raise ValueError("rain value out of plausible range") return v + @field_validator("source") + @classmethod + def _source_valid(cls, v: Optional[str]) -> Optional[str]: + if v is not None and v not in ("loop", "archive"): + raise ValueError("source must be 'loop' or 'archive'") + return v + # ---- Konvertierungen ------------------------------------------------- def get_datetime_string(self) -> str: @@ -330,6 +340,9 @@ def setup_database() -> None: cursor.execute( "ALTER TABLE weather_data ADD COLUMN IF NOT EXISTS bar_trend INTEGER" ) + cursor.execute( + "ALTER TABLE weather_data ADD COLUMN IF NOT EXISTS source VARCHAR" + ) cursor.execute( "CREATE INDEX IF NOT EXISTS idx_weather_datetime_desc " "ON weather_data (datetime DESC)" @@ -500,6 +513,7 @@ def _store_weather(data: WeatherDataInput) -> dict: data.rain, data.get_rain_rate(), data.forecast, + data.source, ) with pool.connection() as conn: @@ -509,8 +523,8 @@ def _store_weather(data: WeatherDataInput) -> dict: INSERT INTO weather_data (datetime, temperature, temp_in, humidity, humidity_in, pressure, bar_trend, wind_speed, wind_gust, wind_dir, - rain, rain_rate, forecast) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + rain, rain_rate, forecast, source) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON CONFLICT (datetime) DO UPDATE SET temperature = EXCLUDED.temperature, temp_in = EXCLUDED.temp_in, @@ -523,7 +537,8 @@ def _store_weather(data: WeatherDataInput) -> dict: wind_dir = EXCLUDED.wind_dir, rain = EXCLUDED.rain, rain_rate = EXCLUDED.rain_rate, - forecast = EXCLUDED.forecast + forecast = EXCLUDED.forecast, + source = EXCLUDED.source """, values, ) diff --git a/frontend/package.json b/frontend/package.json index 599934f..941bef8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "wetterstation-frontend", "private": true, - "version": "1.5.8", + "version": "1.5.9", "type": "module", "scripts": { "dev": "vite", diff --git a/migrate_sqlite_to_postgres.py b/migrate_sqlite_to_postgres.py index fe803dc..88a6823 100755 --- a/migrate_sqlite_to_postgres.py +++ b/migrate_sqlite_to_postgres.py @@ -19,7 +19,7 @@ load_dotenv(dotenv_path=env_path) # Konfiguration SQLITE_DB = "data/wview-archive.sdb" START_DATE = datetime(2025, 1, 1, 0, 0, 0, tzinfo=timezone.utc) -END_DATE = datetime(2026, 2, 8, 0, 0, 0, tzinfo=timezone.utc) +END_DATE = datetime(2026, 3, 23, 0, 0, 0, tzinfo=timezone.utc) # PostgreSQL-Konfiguration DB_HOST = os.getenv('DB_HOST', 'localhost') @@ -96,6 +96,41 @@ def main(): sqlite_conn.close() sys.exit(1) + # Tabelle anlegen falls nicht vorhanden + try: + pg_cursor.execute(""" + CREATE TABLE IF NOT EXISTS weather_data ( + id SERIAL PRIMARY KEY, + datetime TIMESTAMPTZ NOT NULL, + temperature FLOAT, + humidity INTEGER, + pressure FLOAT, + wind_speed FLOAT, + wind_gust FLOAT, + wind_dir FLOAT, + rain FLOAT, + rain_rate FLOAT, + temp_in FLOAT, + humidity_in INTEGER, + forecast INTEGER, + bar_trend INTEGER, + source VARCHAR, + received_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(datetime) + ) + """) + pg_cursor.execute( + "CREATE INDEX IF NOT EXISTS idx_weather_datetime_desc " + "ON weather_data (datetime DESC)" + ) + pg_conn.commit() + print("✓ Tabelle weather_data bereit") + except Exception as e: + print(f"✗ Fehler beim Anlegen der Tabelle: {e}") + sqlite_conn.close() + pg_conn.close() + sys.exit(1) + # Tabelle leeren falls gewünscht if TRUNCATE_TABLE: print("\nLeere PostgreSQL-Tabelle weather_data...") @@ -163,13 +198,13 @@ def main(): # In PostgreSQL einfügen pg_cursor.execute(""" - INSERT INTO weather_data - (datetime, temperature, humidity, pressure, - wind_speed, wind_gust, wind_dir, rain, rain_rate) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) + INSERT INTO weather_data + (datetime, temperature, humidity, pressure, + wind_speed, wind_gust, wind_dir, rain, rain_rate, source) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON CONFLICT (datetime) DO NOTHING - """, (dt, temp_c, humidity, pressure_hpa, - wind_speed_kmh, wind_gust_kmh, windDir, rain_mm, rain_rate_mm)) + """, (dt, temp_c, humidity, pressure_hpa, + wind_speed_kmh, wind_gust_kmh, windDir, rain_mm, rain_rate_mm, 'wview')) if pg_cursor.rowcount > 0: inserted += 1