120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
"""
|
|
통계 조회 API
|
|
- 일별/월별/연도별 발전량 통계
|
|
"""
|
|
|
|
from fastapi import APIRouter, HTTPException, Depends, Query
|
|
from supabase import Client
|
|
from typing import List, Literal
|
|
from datetime import datetime, timedelta
|
|
|
|
from app.core.database import get_db
|
|
|
|
router = APIRouter(
|
|
prefix="/plants",
|
|
tags=["Stats"]
|
|
)
|
|
|
|
|
|
@router.get("/{plant_id}/stats")
|
|
async def get_plant_stats(
|
|
plant_id: str,
|
|
period: Literal["day", "month", "year"] = Query("day", description="통계 기간"),
|
|
db: Client = Depends(get_db)
|
|
) -> dict:
|
|
"""
|
|
발전소 통계 조회
|
|
|
|
Args:
|
|
plant_id: 발전소 ID
|
|
period: 'day' (최근 30일), 'month' (최근 12개월), 'year' (최근 5년)
|
|
|
|
Returns:
|
|
차트 라이브러리 친화적 포맷 [{"label": "...", "value": ...}, ...]
|
|
"""
|
|
try:
|
|
today = datetime.now().date()
|
|
|
|
if period == "day":
|
|
# 최근 30일
|
|
start_date = today - timedelta(days=30)
|
|
|
|
result = db.table("daily_stats") \
|
|
.select("date, total_generation") \
|
|
.eq("plant_id", plant_id) \
|
|
.gte("date", start_date.isoformat()) \
|
|
.lte("date", today.isoformat()) \
|
|
.order("date", desc=False) \
|
|
.execute()
|
|
|
|
data = [
|
|
{"label": row["date"], "value": row["total_generation"] or 0}
|
|
for row in result.data
|
|
]
|
|
|
|
elif period == "month":
|
|
# 최근 12개월 - 월별 합계
|
|
start_date = today.replace(day=1) - timedelta(days=365)
|
|
|
|
result = db.table("daily_stats") \
|
|
.select("date, total_generation") \
|
|
.eq("plant_id", plant_id) \
|
|
.gte("date", start_date.isoformat()) \
|
|
.lte("date", today.isoformat()) \
|
|
.execute()
|
|
|
|
# 월별 집계
|
|
monthly = {}
|
|
for row in result.data:
|
|
date_str = row["date"]
|
|
month_key = date_str[:7] # YYYY-MM
|
|
generation = row["total_generation"] or 0
|
|
monthly[month_key] = monthly.get(month_key, 0) + generation
|
|
|
|
data = [
|
|
{"label": month, "value": round(value, 2)}
|
|
for month, value in sorted(monthly.items())
|
|
][-12:] # 최근 12개월만
|
|
|
|
elif period == "year":
|
|
# 최근 5년 - 연도별 합계
|
|
start_year = today.year - 5
|
|
|
|
result = db.table("daily_stats") \
|
|
.select("date, total_generation") \
|
|
.eq("plant_id", plant_id) \
|
|
.gte("date", f"{start_year}-01-01") \
|
|
.lte("date", today.isoformat()) \
|
|
.execute()
|
|
|
|
# 연도별 집계
|
|
yearly = {}
|
|
for row in result.data:
|
|
date_str = row["date"]
|
|
year_key = date_str[:4] # YYYY
|
|
generation = row["total_generation"] or 0
|
|
yearly[year_key] = yearly.get(year_key, 0) + generation
|
|
|
|
data = [
|
|
{"label": year, "value": round(value, 2)}
|
|
for year, value in sorted(yearly.items())
|
|
]
|
|
else:
|
|
raise HTTPException(status_code=400, detail="Invalid period parameter")
|
|
|
|
return {
|
|
"status": "success",
|
|
"plant_id": plant_id,
|
|
"period": period,
|
|
"data": data,
|
|
"count": len(data)
|
|
}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"통계 조회 실패: {str(e)}"
|
|
)
|