Files
boc/life-agents/real_data_pipeline_v2.py
T

231 lines
7.4 KiB
Python
Raw Normal View History

#!/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)