""" 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 }