From fa745c47d1fc08e149fb827b022dd19bb527092b Mon Sep 17 00:00:00 2001 From: Navan Chauhan Date: Sun, 27 Apr 2025 12:01:12 -0600 Subject: initial commit --- server/Makefile | 12 +++++------ server/api/market.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++-- server/main.py | 9 +++++++++ server/models/market.py | 8 ++++++-- server/settings.json | 2 +- 5 files changed, 73 insertions(+), 11 deletions(-) (limited to 'server') diff --git a/server/Makefile b/server/Makefile index 6709e13..6b9a67c 100644 --- a/server/Makefile +++ b/server/Makefile @@ -1,11 +1,11 @@ .PHONY: run setup -env/bin/activate: - python3 -m venv env - env/bin/pip install --upgrade pip - env/bin/pip install -r requirements.txt +.venv/bin/activate: + python3 -m venv .venv + .venv/bin/pip install --upgrade pip + .venv/bin/pip install -r requirements.txt -setup: env/bin/activate +setup: .venv/bin/activate run: setup - env/bin/uvicorn main:app --reload + .venv/bin/uvicorn main:app --reload diff --git a/server/api/market.py b/server/api/market.py index 5b95ca3..5102f03 100644 --- a/server/api/market.py +++ b/server/api/market.py @@ -1,12 +1,61 @@ from fastapi import APIRouter from models.market import MarketData +from gridstatus import ISONE +from datetime import datetime, timedelta +from typing import List router = APIRouter() +# Keeping the scope of this api to just one market right now +iso = ISONE() + +# In-memory cache +_cached_day_ahead: List[MarketData] = [] +_cache_timestamp: datetime | None = None +_cached_real_time: List[MarketData] = [] +_cache_real_time_timestamp: datetime | None = None + +# TODO: Error Handling @router.get("/day-ahead", response_model=list[MarketData]) def get_day_ahead_data(): - return [] + global _cached_day_ahead, _cache_timestamp + + now = datetime.utcnow() + if _cache_timestamp is None or now - _cache_timestamp > timedelta(hours=1): + 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 = [ + MarketData( + timestamp=row["Interval Start"], + lmp=row["LMP"], + energy=row["Energy"], + congestion=row["Congestion"], + loss=row["Loss"], + ) + for _, row in grouped.iterrows() + ] + _cache_timestamp = now + + return _cached_day_ahead @router.get("/real-time", response_model=list[MarketData]) def get_real_time_data(): - return [] + global _cached_real_time, _cache_real_time_timestamp + + now = datetime.utcnow() + if _cache_real_time_timestamp is None or now - _cache_real_time_timestamp > timedelta(minutes=5): + 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 = [ + MarketData( + timestamp=row["Interval Start"], + lmp=row["LMP"], + energy=row["Energy"], + congestion=row["Congestion"], + loss=row["Loss"], + ) + for _, row in grouped.iterrows() + ] + _cache_real_time_timestamp = now + + return _cached_real_time diff --git a/server/main.py b/server/main.py index df4cd55..09881a2 100644 --- a/server/main.py +++ b/server/main.py @@ -1,4 +1,5 @@ from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware from api import market, bids, pnl app = FastAPI(title="Virtual Energy Trading API") @@ -6,3 +7,11 @@ app = FastAPI(title="Virtual Energy Trading API") app.include_router(market.router, prefix="/market") app.include_router(bids.router, prefix="/bids") app.include_router(pnl.router, prefix="/trader") + +app.add_middleware( + CORSMiddleware, + allow_origins=["http://localhost:3000"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) diff --git a/server/models/market.py b/server/models/market.py index f402ab7..072e40f 100644 --- a/server/models/market.py +++ b/server/models/market.py @@ -1,5 +1,9 @@ +from datetime import datetime from pydantic import BaseModel class MarketData(BaseModel): - timestamp: str - price: float + timestamp: datetime + lmp: float + energy: float + congestion: float + loss: float diff --git a/server/settings.json b/server/settings.json index cf90886..38b6195 100644 --- a/server/settings.json +++ b/server/settings.json @@ -3,7 +3,7 @@ "pyright": { "settings": { "python": { - "pythonPath": "./env/bin/python" + "pythonPath": "./.venv/bin/python" } } } -- cgit v1.2.3