Files
boc/life-weather/storage/observation_store.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

124 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""
ObservationStore - Sparar och hämtar observationer
"""
import sqlite3
import json
from datetime import datetime
from pathlib import Path
DB_PATH = "/home/bernt/.openclaw/workspace/rivp-pilot-1/rivp.db"
RAW_DIR = Path("/home/bernt/.openclaw/workspace/life-weather/raw")
RAW_DIR.mkdir(exist_ok=True)
class ObservationStore:
def __init__(self, db_path=DB_PATH):
self.db_path = db_path
self._init_db()
def _init_db(self):
"""Initiera databasen"""
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
# Huvudtabell för väderobservationer
c.execute('''
CREATE TABLE IF NOT EXISTS weather_observations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
road_id INTEGER,
station_id TEXT,
observation_type TEXT,
value REAL,
unit TEXT,
timestamp TEXT,
raw_data TEXT,
source TEXT,
created_at TEXT
)
''')
# Index för snabbare sökning
c.execute('''
CREATE INDEX IF NOT EXISTS idx_weather_road
ON weather_observations(road_id, timestamp)
''')
conn.commit()
conn.close()
def save_raw_data(self, weather_data, filename=None):
"""Spara rådata oförändrad"""
if filename is None:
filename = f"weather_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
filepath = RAW_DIR / filename
with open(filepath, 'w') as f:
json.dump(weather_data, f, indent=2)
return filepath
def save_observation(self, road_id, observation_type, value, unit, timestamp, raw_data, source="smhi"):
"""Spara normaliserad observation"""
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
# Idempotent - kolla om observation redan finns
c.execute('''
SELECT id FROM weather_observations
WHERE road_id = ? AND observation_type = ? AND timestamp = ?
''', (road_id, observation_type, timestamp))
if c.fetchone():
conn.close()
return None # Redan sparad
c.execute('''
INSERT INTO weather_observations
(road_id, station_id, observation_type, value, unit, timestamp, raw_data, source, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
road_id,
"97530", # Uppsala station
observation_type,
value,
unit,
timestamp,
json.dumps(raw_data),
source,
datetime.now().isoformat()
))
obs_id = c.lastrowid
conn.commit()
conn.close()
return obs_id
def get_latest_for_road(self, road_id, observation_type=None):
"""Hämta senaste observation för väg"""
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
if observation_type:
c.execute('''
SELECT * FROM weather_observations
WHERE road_id = ? AND observation_type = ?
ORDER BY timestamp DESC LIMIT 1
''', (road_id, observation_type))
else:
c.execute('''
SELECT * FROM weather_observations
WHERE road_id = ?
ORDER BY timestamp DESC LIMIT 1
''', (road_id,))
row = c.fetchone()
conn.close()
return row
if __name__ == "__main__":
store = ObservationStore()
print("ObservationStore initierad")
print(f"Rådata sparas i: {RAW_DIR}")