feat: Add year parameter to stats API and extend year range
This commit is contained in:
parent
060c32d105
commit
39c7928895
|
|
@ -20,6 +20,7 @@ router = APIRouter(
|
|||
async def get_plant_stats(
|
||||
plant_id: str,
|
||||
period: Literal["day", "month", "year"] = Query("day", description="통계 기간"),
|
||||
year: int = Query(None, description="특정 연도 (월별/연도별 조회 시)"),
|
||||
db: Client = Depends(get_db)
|
||||
) -> dict:
|
||||
"""
|
||||
|
|
@ -30,7 +31,8 @@ async def get_plant_stats(
|
|||
|
||||
Args:
|
||||
plant_id: 발전소 ID
|
||||
period: 'day' (최근 30일), 'month' (최근 12개월), 'year' (최근 5년)
|
||||
period: 'day' (최근 30일), 'month' (최근 12개월 또는 특정 연도), 'year' (최근 연도들)
|
||||
year: 특정 연도 (옵션, period='month' 시 해당 연도의 월별 데이터 반환)
|
||||
|
||||
Returns:
|
||||
차트 라이브러리 친화적 포맷 [{"label": "...", "value": ...}, ...]
|
||||
|
|
@ -46,37 +48,54 @@ async def get_plant_stats(
|
|||
start_date = today.replace(day=1)
|
||||
date_filter = start_date.isoformat()
|
||||
elif period == "month":
|
||||
start_date = today.replace(day=1) - timedelta(days=365)
|
||||
# year 파라미터가 있으면 해당 연도 1월~12월, 없으면 올해
|
||||
target_year = year if year else today.year
|
||||
start_date = datetime(target_year, 1, 1).date()
|
||||
# 종료일: 해당 연도 12월 31일 또는 오늘 중 작은 값
|
||||
end_date = min(datetime(target_year, 12, 31).date(), today)
|
||||
date_filter = start_date.isoformat()
|
||||
else: # year
|
||||
start_date = datetime(today.year - 5, 1, 1).date()
|
||||
# year 파라미터가 있으면 해당 연도부터, 없으면 최근 10년
|
||||
if year:
|
||||
start_year = year
|
||||
else:
|
||||
start_year = today.year - 9 # 10년치 데이터 (올해 포함)
|
||||
start_date = datetime(start_year, 1, 1).date()
|
||||
end_date = today
|
||||
date_filter = start_date.strftime("%Y-%m-%d")
|
||||
|
||||
stats_query = db.table("daily_stats") \
|
||||
.select("date, total_generation") \
|
||||
.eq("plant_id", plant_id) \
|
||||
.gte("date", date_filter) \
|
||||
.lte("date", today_str) \
|
||||
.order("date", desc=False)
|
||||
.gte("date", date_filter)
|
||||
|
||||
# period별 종료일 필터 추가
|
||||
if period in ["month", "year"]:
|
||||
stats_query = stats_query.lte("date", end_date.isoformat() if period == "month" else today_str)
|
||||
else:
|
||||
stats_query = stats_query.lte("date", today_str)
|
||||
|
||||
stats_query = stats_query.order("date", desc=False)
|
||||
|
||||
stats_result = stats_query.execute()
|
||||
|
||||
# 데이터 맵핑 {날짜: 발전량}
|
||||
data_map = {row["date"]: row["total_generation"] or 0 for row in stats_result.data}
|
||||
|
||||
# 2. 오늘 실시간 데이터 조회 (solar_logs)
|
||||
# 오늘의 가장 마지막 기록 1건만 조회 (성능 최적화)
|
||||
logs_result = db.table("solar_logs") \
|
||||
.select("today_kwh, created_at") \
|
||||
.eq("plant_id", plant_id) \
|
||||
.gte("created_at", f"{today_str}T00:00:00") \
|
||||
.order("created_at", desc=True) \
|
||||
.limit(1) \
|
||||
.execute()
|
||||
|
||||
# 2. 오늘 실시간 데이터 조회 (solar_logs) - 오늘이 조회 범위에 포함될 때만
|
||||
today_generation = 0.0
|
||||
if logs_result.data:
|
||||
today_generation = logs_result.data[0].get("today_kwh", 0.0)
|
||||
if period == "day" or (period == "month" and (not year or year == today.year)) or period == "year":
|
||||
# 오늘의 가장 마지막 기록 1건만 조회 (성능 최적화)
|
||||
logs_result = db.table("solar_logs") \
|
||||
.select("today_kwh, created_at") \
|
||||
.eq("plant_id", plant_id) \
|
||||
.gte("created_at", f"{today_str}T00:00:00") \
|
||||
.order("created_at", desc=True) \
|
||||
.limit(1) \
|
||||
.execute()
|
||||
|
||||
if logs_result.data:
|
||||
today_generation = logs_result.data[0].get("today_kwh", 0.0)
|
||||
|
||||
# 3. 데이터 병합 (오늘 데이터 갱신/추가)
|
||||
# solar_logs 값이 있으면 무조건 daily_stats 값보다 우선 (실시간성)
|
||||
|
|
@ -105,12 +124,17 @@ async def get_plant_stats(
|
|||
month_key = date_str[:7]
|
||||
monthly[month_key] = monthly.get(month_key, 0) + val
|
||||
|
||||
sorted_keys = sorted(monthly.keys())
|
||||
data = [
|
||||
{"label": k, "value": round(monthly[k], 2)}
|
||||
for k in sorted_keys
|
||||
if k >= start_date.strftime("%Y-%m")
|
||||
]
|
||||
# 특정 연도의 1~12월 데이터 생성 (누락된 월은 0)
|
||||
target_year = year if year else today.year
|
||||
for month in range(1, 13):
|
||||
month_key = f"{target_year}-{month:02d}"
|
||||
# 미래 월은 제외
|
||||
if datetime.strptime(month_key, "%Y-%m").date() > today.replace(day=1):
|
||||
break
|
||||
data.append({
|
||||
"label": month_key,
|
||||
"value": round(monthly.get(month_key, 0), 2)
|
||||
})
|
||||
|
||||
elif period == "year":
|
||||
# 연도별 집계
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user