V 1.5.9 feat: Spalte 'source' (loop/archive/wview) in weather_data
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-3
@@ -164,6 +164,9 @@ class WeatherDataInput(BaseModel):
|
|||||||
# Vorhersage
|
# Vorhersage
|
||||||
forecast: Optional[int] = None
|
forecast: Optional[int] = None
|
||||||
|
|
||||||
|
# Datenquelle
|
||||||
|
source: Optional[str] = None
|
||||||
|
|
||||||
# ---- Validatoren -----------------------------------------------------
|
# ---- Validatoren -----------------------------------------------------
|
||||||
|
|
||||||
@field_validator("tempOut", "temperature", "tempIn")
|
@field_validator("tempOut", "temperature", "tempIn")
|
||||||
@@ -229,6 +232,13 @@ class WeatherDataInput(BaseModel):
|
|||||||
raise ValueError("rain value out of plausible range")
|
raise ValueError("rain value out of plausible range")
|
||||||
return v
|
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 -------------------------------------------------
|
# ---- Konvertierungen -------------------------------------------------
|
||||||
|
|
||||||
def get_datetime_string(self) -> str:
|
def get_datetime_string(self) -> str:
|
||||||
@@ -330,6 +340,9 @@ def setup_database() -> None:
|
|||||||
cursor.execute(
|
cursor.execute(
|
||||||
"ALTER TABLE weather_data ADD COLUMN IF NOT EXISTS bar_trend INTEGER"
|
"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(
|
cursor.execute(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_weather_datetime_desc "
|
"CREATE INDEX IF NOT EXISTS idx_weather_datetime_desc "
|
||||||
"ON weather_data (datetime DESC)"
|
"ON weather_data (datetime DESC)"
|
||||||
@@ -500,6 +513,7 @@ def _store_weather(data: WeatherDataInput) -> dict:
|
|||||||
data.rain,
|
data.rain,
|
||||||
data.get_rain_rate(),
|
data.get_rain_rate(),
|
||||||
data.forecast,
|
data.forecast,
|
||||||
|
data.source,
|
||||||
)
|
)
|
||||||
|
|
||||||
with pool.connection() as conn:
|
with pool.connection() as conn:
|
||||||
@@ -509,8 +523,8 @@ def _store_weather(data: WeatherDataInput) -> dict:
|
|||||||
INSERT INTO weather_data
|
INSERT INTO weather_data
|
||||||
(datetime, temperature, temp_in, humidity, humidity_in,
|
(datetime, temperature, temp_in, humidity, humidity_in,
|
||||||
pressure, bar_trend, wind_speed, wind_gust, wind_dir,
|
pressure, bar_trend, wind_speed, wind_gust, wind_dir,
|
||||||
rain, rain_rate, forecast)
|
rain, rain_rate, forecast, source)
|
||||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
ON CONFLICT (datetime) DO UPDATE SET
|
ON CONFLICT (datetime) DO UPDATE SET
|
||||||
temperature = EXCLUDED.temperature,
|
temperature = EXCLUDED.temperature,
|
||||||
temp_in = EXCLUDED.temp_in,
|
temp_in = EXCLUDED.temp_in,
|
||||||
@@ -523,7 +537,8 @@ def _store_weather(data: WeatherDataInput) -> dict:
|
|||||||
wind_dir = EXCLUDED.wind_dir,
|
wind_dir = EXCLUDED.wind_dir,
|
||||||
rain = EXCLUDED.rain,
|
rain = EXCLUDED.rain,
|
||||||
rain_rate = EXCLUDED.rain_rate,
|
rain_rate = EXCLUDED.rain_rate,
|
||||||
forecast = EXCLUDED.forecast
|
forecast = EXCLUDED.forecast,
|
||||||
|
source = EXCLUDED.source
|
||||||
""",
|
""",
|
||||||
values,
|
values,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "wetterstation-frontend",
|
"name": "wetterstation-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.5.8",
|
"version": "1.5.9",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ load_dotenv(dotenv_path=env_path)
|
|||||||
# Konfiguration
|
# Konfiguration
|
||||||
SQLITE_DB = "data/wview-archive.sdb"
|
SQLITE_DB = "data/wview-archive.sdb"
|
||||||
START_DATE = datetime(2025, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
|
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
|
# PostgreSQL-Konfiguration
|
||||||
DB_HOST = os.getenv('DB_HOST', 'localhost')
|
DB_HOST = os.getenv('DB_HOST', 'localhost')
|
||||||
@@ -96,6 +96,41 @@ def main():
|
|||||||
sqlite_conn.close()
|
sqlite_conn.close()
|
||||||
sys.exit(1)
|
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
|
# Tabelle leeren falls gewünscht
|
||||||
if TRUNCATE_TABLE:
|
if TRUNCATE_TABLE:
|
||||||
print("\nLeere PostgreSQL-Tabelle weather_data...")
|
print("\nLeere PostgreSQL-Tabelle weather_data...")
|
||||||
@@ -165,11 +200,11 @@ def main():
|
|||||||
pg_cursor.execute("""
|
pg_cursor.execute("""
|
||||||
INSERT INTO weather_data
|
INSERT INTO weather_data
|
||||||
(datetime, temperature, humidity, pressure,
|
(datetime, temperature, humidity, pressure,
|
||||||
wind_speed, wind_gust, wind_dir, rain, rain_rate)
|
wind_speed, wind_gust, wind_dir, rain, rain_rate, source)
|
||||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
ON CONFLICT (datetime) DO NOTHING
|
ON CONFLICT (datetime) DO NOTHING
|
||||||
""", (dt, temp_c, humidity, pressure_hpa,
|
""", (dt, temp_c, humidity, pressure_hpa,
|
||||||
wind_speed_kmh, wind_gust_kmh, windDir, rain_mm, rain_rate_mm))
|
wind_speed_kmh, wind_gust_kmh, windDir, rain_mm, rain_rate_mm, 'wview'))
|
||||||
|
|
||||||
if pg_cursor.rowcount > 0:
|
if pg_cursor.rowcount > 0:
|
||||||
inserted += 1
|
inserted += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user