#!/usr/bin/env python3 """ LIFE Real Data Pipeline v2 Hämtar RIKTIG data från flera öppna källor """ import requests import sqlite3 import json from datetime import datetime DB_PATH = "/home/bernt/.openclaw/workspace/rivp-pilot-1/rivp.db" def get_db(): conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row return conn def fetch_smhi_temperature(): """Hämta RIKTIG temperaturdata från SMHI""" station_id = "97530" # Uppsala Flygplats url = f"https://opendata-download-metobs.smhi.se/api/version/latest/parameter/1/station/{station_id}/period/latest-hour/data.json" try: response = requests.get(url, timeout=30) if response.status_code == 200: data = response.json() values = data.get("value", []) if values: latest = values[-1] return { "station": data["station"]["name"], "temperature": float(latest["value"]), "timestamp": latest["date"], "unit": "celsius" } except Exception as e: print(f"SMHI temp error: {e}") return None def fetch_smhi_precipitation(): """Hämta RIKTIG nederbördsdata från SMHI""" station_id = "97530" url = f"https://opendata-download-metobs.smhi.se/api/version/latest/parameter/7/station/{station_id}/period/latest-day/data.json" try: response = requests.get(url, timeout=30) if response.status_code == 200: data = response.json() values = data.get("value", []) if values: total = sum(float(v["value"]) for v in values if float(v["value"]) >= 0) return { "station": data["station"]["name"], "precipitation_mm": total, "measurements": len(values) } except Exception as e: print(f"SMHI precip error: {e}") return None def fetch_smhi_wind(): """Hämta RIKTIG vinddata från SMHI""" station_id = "97530" url = f"https://opendata-download-metobs.smhi.se/api/version/latest/parameter/4/station/{station_id}/period/latest-hour/data.json" try: response = requests.get(url, timeout=30) if response.status_code == 200: data = response.json() values = data.get("value", []) if values: latest = values[-1] return { "station": data["station"]["name"], "wind_speed": float(latest["value"]), "unit": "m/s" } except Exception as e: print(f"SMHI wind error: {e}") return None def fetch_osm_roads(): """Hämta vägdata från OpenStreetMap""" query = """ [out:json]; area["name"="Uppsala"]->.searchArea; way["highway"~"motorway|trunk|primary|secondary"](area.searchArea); out body; """ try: response = requests.post( "https://overpass-api.de/api/interpreter", data={"data": query}, timeout=30 ) if response.status_code == 200: data = response.json() ways = [e for e in data.get("elements", []) if e.get("type") == "way"] return ways except Exception as e: print(f"OSM error: {e}") return [] def fetch_wikidata_sweden(): """Hämta data om Sverige från Wikidata""" query = """ SELECT ?item ?itemLabel WHERE { ?item wdt:P31 wd:Q34442. ?item wdt:P17 wd:Q34. SERVICE wikibase:label { bd:serviceParam wikibase:language "sv,en". } } LIMIT 10 """ try: response = requests.get( "https://query.wikidata.org/sparql", params={"query": query, "format": "json"}, headers={"Accept": "application/sparql-results+json"}, timeout=30 ) if response.status_code == 200: return response.json() except Exception as e: print(f"Wikidata error: {e}") return None def save_weather_observations(temp_data, precip_data, wind_data): """Spara väderobservationer i databasen""" conn = get_db() c = conn.cursor() # Hitta vägar i Uppsala c.execute("SELECT id FROM roads WHERE county = 'Uppsala' LIMIT 10") roads = c.fetchall() count = 0 for road in roads: # Temperatur if temp_data: severity = "high" if temp_data['temperature'] < 0 else "medium" if temp_data['temperature'] > 25 else "low" c.execute(''' INSERT INTO observations (road_id, observation_type, latitude, longitude, confidence, severity, detected_date, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', ( road[0], f"temperature_{temp_data['temperature']}c", 59.85, 17.65, 0.95, severity, datetime.now().strftime('%Y-%m-%d'), 'smhi_real' )) count += 1 # Nederbörd if precip_data and precip_data['precipitation_mm'] > 0: severity = "high" if precip_data['precipitation_mm'] > 10 else "medium" if precip_data['precipitation_mm'] > 2 else "low" c.execute(''' INSERT INTO observations (road_id, observation_type, latitude, longitude, confidence, severity, detected_date, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', ( road[0], f"precipitation_{precip_data['precipitation_mm']}mm", 59.85, 17.65, 0.9, severity, datetime.now().strftime('%Y-%m-%d'), 'smhi_real' )) count += 1 # Vind if wind_data: severity = "high" if wind_data['wind_speed'] > 15 else "medium" if wind_data['wind_speed'] > 10 else "low" c.execute(''' INSERT INTO observations (road_id, observation_type, latitude, longitude, confidence, severity, detected_date, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', ( road[0], f"wind_{wind_data['wind_speed']}ms", 59.85, 17.65, 0.9, severity, datetime.now().strftime('%Y-%m-%d'), 'smhi_real' )) count += 1 conn.commit() conn.close() return count def run_real_pipeline(): """Kör pipeline med RIKTIG data""" print(f"[{datetime.now().isoformat()}] Fetching REAL data...") # 1. Hämta riktig väderdata temp = fetch_smhi_temperature() precip = fetch_smhi_precipitation() wind = fetch_smhi_wind() if temp: print(f" SMHI Temp: {temp['temperature']}°C at {temp['station']}") if precip: print(f" SMHI Precip: {precip['precipitation_mm']}mm") if wind: print(f" SMHI Wind: {wind['wind_speed']} m/s") # 2. Spara i databasen saved = save_weather_observations(temp, precip, wind) print(f" Saved {saved} observations") # 3. Hämta vägar från OSM roads = fetch_osm_roads() if roads: print(f" OSM Roads: {len(roads)} found") print(f"[{datetime.now().isoformat()}] Real data pipeline complete") if __name__ == "__main__": print("="*60) print("LIFE REAL DATA PIPELINE v2") print("="*60) run_real_pipeline() print("="*60)