148 lines
4.4 KiB
Python
148 lines
4.4 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
LIFE Real Data Pipeline
|
||
|
|
Hämtar RIKTIG data från ö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"""
|
||
|
|
# Uppsala Flygplats
|
||
|
|
station_id = "97530"
|
||
|
|
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()
|
||
|
|
|
||
|
|
# Extrahera senaste värdet
|
||
|
|
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 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_osm_roads():
|
||
|
|
"""Hämta vägdata från OpenStreetMap (öppet API)"""
|
||
|
|
# Overpass API query för vägar i Uppsala
|
||
|
|
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 save_weather_observation(weather_data):
|
||
|
|
"""Spara väderobservation i databasen"""
|
||
|
|
conn = get_db()
|
||
|
|
c = conn.cursor()
|
||
|
|
|
||
|
|
# Hitta vägar i Uppsala
|
||
|
|
c.execute("SELECT id FROM roads WHERE county = 'Uppsala' LIMIT 5")
|
||
|
|
roads = c.fetchall()
|
||
|
|
|
||
|
|
for road in roads:
|
||
|
|
c.execute('''
|
||
|
|
INSERT INTO observations
|
||
|
|
(road_id, observation_type, latitude, longitude, confidence, severity, detected_date, source)
|
||
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||
|
|
''', (
|
||
|
|
road[0],
|
||
|
|
f"weather_temp_{weather_data['temperature']}c",
|
||
|
|
59.85, 17.65,
|
||
|
|
0.95,
|
||
|
|
"high" if weather_data['temperature'] < 0 else "low",
|
||
|
|
datetime.now().strftime('%Y-%m-%d'),
|
||
|
|
'smhi_real'
|
||
|
|
))
|
||
|
|
|
||
|
|
conn.commit()
|
||
|
|
conn.close()
|
||
|
|
return len(roads)
|
||
|
|
|
||
|
|
def run_real_pipeline():
|
||
|
|
"""Kör pipeline med RIKTIG data"""
|
||
|
|
print(f"[{datetime.now().isoformat()}] Fetching REAL data...")
|
||
|
|
|
||
|
|
# 1. Hämta riktig temperatur
|
||
|
|
temp = fetch_smhi_temperature()
|
||
|
|
if temp:
|
||
|
|
print(f" SMHI Temp: {temp['temperature']}°C at {temp['station']}")
|
||
|
|
saved = save_weather_observation(temp)
|
||
|
|
print(f" Saved to {saved} roads")
|
||
|
|
|
||
|
|
# 2. Hämta riktig nederbörd
|
||
|
|
precip = fetch_smhi_precipitation()
|
||
|
|
if precip:
|
||
|
|
print(f" SMHI Precip: {precip['precipitation_mm']}mm")
|
||
|
|
|
||
|
|
# 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")
|
||
|
|
print("="*60)
|
||
|
|
run_real_pipeline()
|
||
|
|
print("="*60)
|