from fastapi import APIRouter, Query, HTTPException from models.market import MarketData from gridstatus import ISONE, CAISO, Ercot, MISO, NYISO, PJM from datetime import datetime, timedelta from typing import List, Dict, Type router = APIRouter() MARKET_CLASSES: Dict[str, Type] = { "ISONE": ISONE, # "CAISO": CAISO, # "ERCOT": Ercot, "MISO": MISO, "NYISO": NYISO, # "PJM": PJM, } # In-memory cache _cached_day_ahead: Dict[str, List[MarketData]] = {} _cached_day_ahead_timestamp: Dict[str, datetime] = {} _cached_real_time: Dict[str, List[MarketData]] = {} _cached_real_time_timestamp: Dict[str, datetime] = {} def get_iso_instance(market: str): market = market.upper() if market not in MARKET_CLASSES: raise HTTPException(status_code=400, detail=f"Unsupported market '{market}'. Supported: {list(MARKET_CLASSES.keys())}") return MARKET_CLASSES[market]() @router.get("/day-ahead", response_model=List[MarketData]) def get_day_ahead_data(market: str = Query("ISONE")): now = datetime.utcnow() market = market.upper() if (market not in _cached_day_ahead_timestamp or now - _cached_day_ahead_timestamp[market] > timedelta(hours=1)): iso = get_iso_instance(market) df = iso.get_lmp(date=datetime.now().date(), market="DAY_AHEAD_HOURLY", locations="ALL") grouped = df.groupby("Interval Start")[["LMP", "Energy", "Congestion", "Loss"]].mean().reset_index() _cached_day_ahead[market] = [ MarketData( timestamp=row["Interval Start"], lmp=row["LMP"], energy=row["Energy"], congestion=row["Congestion"], loss=row["Loss"], ) for _, row in grouped.iterrows() ] _cached_day_ahead_timestamp[market] = now return _cached_day_ahead[market] @router.get("/real-time", response_model=List[MarketData]) def get_real_time_data(market: str = Query("ISONE")): now = datetime.utcnow() market = market.upper() if (market not in _cached_real_time_timestamp or now - _cached_real_time_timestamp[market] > timedelta(minutes=5)): iso = get_iso_instance(market) df = iso.get_lmp(date="today", market="REAL_TIME_5_MIN", locations="ALL") grouped = df.groupby("Interval Start")[["LMP", "Energy", "Congestion", "Loss"]].mean().reset_index() _cached_real_time[market] = [ MarketData( timestamp=row["Interval Start"], lmp=row["LMP"], energy=row["Energy"], congestion=row["Congestion"], loss=row["Loss"], ) for _, row in grouped.iterrows() ] _cached_real_time_timestamp[market] = now return _cached_real_time[market]