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
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
"""
|
||||
RIVP Pilot 1 - Real Infrastructure Monitoring
|
||||
Reads from SQLite database with real road network and generated observations
|
||||
"""
|
||||
from fastapi import APIRouter
|
||||
import sqlite3
|
||||
import os
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
|
||||
router = APIRouter(prefix="/rivp-pilot1", tags=["rivp_pilot1"])
|
||||
|
||||
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
|
||||
|
||||
@router.get("/public/roads")
|
||||
async def get_roads(county: Optional[str] = None, road_type: Optional[str] = None):
|
||||
"""Get all roads with optional filtering"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
query = "SELECT * FROM roads WHERE 1=1"
|
||||
params = []
|
||||
|
||||
if county:
|
||||
query += " AND county = ?"
|
||||
params.append(county)
|
||||
if road_type:
|
||||
query += " AND type = ?"
|
||||
params.append(road_type)
|
||||
|
||||
query += " ORDER BY county, name"
|
||||
|
||||
c.execute(query, params)
|
||||
roads = [dict(row) for row in c.fetchall()]
|
||||
|
||||
# Get observation count for each road
|
||||
for road in roads:
|
||||
c.execute("SELECT COUNT(*) FROM observations WHERE road_id = ?", (road['id'],))
|
||||
road['observation_count'] = c.fetchone()[0]
|
||||
|
||||
conn.close()
|
||||
return {
|
||||
"total": len(roads),
|
||||
"counties": list(set(r['county'] for r in roads)),
|
||||
"roads": roads
|
||||
}
|
||||
|
||||
@router.get("/public/observations")
|
||||
async def get_observations(road_id: Optional[int] = None,
|
||||
observation_type: Optional[str] = None,
|
||||
severity: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
verified_only: bool = False):
|
||||
"""Get observations with filtering"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
query = """
|
||||
SELECT o.*, r.name as road_name, r.county
|
||||
FROM observations o
|
||||
JOIN roads r ON o.road_id = r.id
|
||||
WHERE 1=1
|
||||
"""
|
||||
params = []
|
||||
|
||||
if road_id:
|
||||
query += " AND o.road_id = ?"
|
||||
params.append(road_id)
|
||||
if observation_type:
|
||||
query += " AND o.observation_type = ?"
|
||||
params.append(observation_type)
|
||||
if severity:
|
||||
query += " AND o.severity = ?"
|
||||
params.append(severity)
|
||||
if source:
|
||||
query += " AND o.source = ?"
|
||||
params.append(source)
|
||||
if verified_only:
|
||||
query += " AND o.verified = 1"
|
||||
|
||||
query += " ORDER BY o.detected_date DESC"
|
||||
|
||||
c.execute(query, params)
|
||||
observations = [dict(row) for row in c.fetchall()]
|
||||
|
||||
conn.close()
|
||||
return {
|
||||
"total": len(observations),
|
||||
"observations": observations
|
||||
}
|
||||
|
||||
@router.get("/public/dashboard")
|
||||
async def get_dashboard():
|
||||
"""Get dashboard statistics"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
# Total roads
|
||||
c.execute("SELECT COUNT(*) FROM roads")
|
||||
total_roads = c.fetchone()[0]
|
||||
|
||||
# Total observations
|
||||
c.execute("SELECT COUNT(*) FROM observations")
|
||||
total_observations = c.fetchone()[0]
|
||||
|
||||
# By type
|
||||
c.execute("SELECT type, COUNT(*) FROM roads GROUP BY type")
|
||||
roads_by_type = {row[0]: row[1] for row in c.fetchall()}
|
||||
|
||||
# By county
|
||||
c.execute("SELECT county, COUNT(*) FROM roads GROUP BY county ORDER BY COUNT(*) DESC")
|
||||
roads_by_county = [{"county": row[0], "count": row[1]} for row in c.fetchall()]
|
||||
|
||||
# Observations by type
|
||||
c.execute("SELECT observation_type, COUNT(*) FROM observations GROUP BY observation_type")
|
||||
obs_by_type = {row[0]: row[1] for row in c.fetchall()}
|
||||
|
||||
# Observations by source
|
||||
c.execute("SELECT source, COUNT(*) FROM observations GROUP BY source")
|
||||
obs_by_source = {row[0]: row[1] for row in c.fetchall()}
|
||||
|
||||
# Observations by severity
|
||||
c.execute("SELECT severity, COUNT(*) FROM observations GROUP BY severity")
|
||||
obs_by_severity = {row[0]: row[1] for row in c.fetchall()}
|
||||
|
||||
# Verified vs unverified
|
||||
c.execute("SELECT verified, COUNT(*) FROM observations GROUP BY verified")
|
||||
verification = {row[0]: row[1] for row in c.fetchall()}
|
||||
|
||||
# Average confidence
|
||||
c.execute("SELECT AVG(confidence) FROM observations")
|
||||
avg_confidence = c.fetchone()[0]
|
||||
|
||||
# Recent observations (last 30 days)
|
||||
c.execute("""
|
||||
SELECT COUNT(*) FROM observations
|
||||
WHERE detected_date >= date('now', '-30 days')
|
||||
""")
|
||||
recent_obs = c.fetchone()[0]
|
||||
|
||||
conn.close()
|
||||
|
||||
return {
|
||||
"roads": {
|
||||
"total": total_roads,
|
||||
"by_type": roads_by_type,
|
||||
"by_county": roads_by_county[:10]
|
||||
},
|
||||
"observations": {
|
||||
"total": total_observations,
|
||||
"by_type": obs_by_type,
|
||||
"by_source": obs_by_source,
|
||||
"by_severity": obs_by_severity,
|
||||
"verification": verification,
|
||||
"average_confidence": round(avg_confidence, 2),
|
||||
"last_30_days": recent_obs
|
||||
}
|
||||
}
|
||||
|
||||
@router.get("/public/map-data")
|
||||
async def get_map_data(county: Optional[str] = None):
|
||||
"""Get observation data for map visualization"""
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
query = """
|
||||
SELECT o.id, o.latitude, o.longitude, o.observation_type,
|
||||
o.confidence, o.severity, o.detected_date, o.verified,
|
||||
r.name as road_name, r.county
|
||||
FROM observations o
|
||||
JOIN roads r ON o.road_id = r.id
|
||||
WHERE 1=1
|
||||
"""
|
||||
params = []
|
||||
|
||||
if county:
|
||||
query += " AND r.county = ?"
|
||||
params.append(county)
|
||||
|
||||
c.execute(query, params)
|
||||
points = [dict(row) for row in c.fetchall()]
|
||||
|
||||
conn.close()
|
||||
return {
|
||||
"total": len(points),
|
||||
"points": points
|
||||
}
|
||||
Reference in New Issue
Block a user