aiBatteryLifeCycle / api /schemas.py
NeerajCodz's picture
feat: full project β€” ML simulation, dashboard UI, models on HF Hub
f381be8
"""
api.schemas
===========
Pydantic models for request / response validation.
"""
from __future__ import annotations
from pydantic import BaseModel, Field
from typing import Optional
# ── Prediction ───────────────────────────────────────────────────────────────
class PredictRequest(BaseModel):
"""Request body for single-cycle prediction."""
battery_id: str = Field(..., description="Battery identifier, e.g. 'B0005'")
cycle_number: int = Field(..., ge=1, description="Current cycle number")
ambient_temperature: float = Field(default=24.0, description="Ambient temperature (Β°C)")
peak_voltage: float = Field(default=4.19, description="Peak charge voltage (V)")
min_voltage: float = Field(default=2.61, description="Discharge cutoff voltage (V)")
avg_current: float = Field(default=1.82, description="Average discharge current (A)")
avg_temp: float = Field(default=32.6, description="Average cell temperature (Β°C) β€” typically higher than ambient")
temp_rise: float = Field(default=14.7, description="Temperature rise during cycle (Β°C) β€” NASA dataset mean β‰ˆ 15Β°C")
cycle_duration: float = Field(default=3690.0, description="Cycle duration (seconds)")
Re: float = Field(default=0.045, description="Electrolyte resistance (Ξ©) β€” training range 0.027–0.156")
Rct: float = Field(default=0.069, description="Charge transfer resistance (Ξ©) β€” training range 0.04–0.27")
delta_capacity: float = Field(default=-0.005, description="Capacity change from last cycle (Ah)")
class PredictResponse(BaseModel):
"""Response body for a prediction."""
battery_id: str
cycle_number: int
soh_pct: float = Field(..., description="Predicted State of Health (%)")
rul_cycles: Optional[float] = Field(None, description="Predicted Remaining Useful Life (cycles)")
degradation_state: str = Field(..., description="Degradation state label")
confidence_lower: Optional[float] = None
confidence_upper: Optional[float] = None
model_used: str = Field(..., description="Name of the model that produced the prediction")
model_version: Optional[str] = Field(None, description="Semantic version of the model used")
# ── Batch Prediction ─────────────────────────────────────────────────────────
class BatchPredictRequest(BaseModel):
"""Batch prediction for multiple cycles of one battery."""
battery_id: str
cycles: list[dict] = Field(..., description="List of cycle feature dicts")
class BatchPredictResponse(BaseModel):
"""Batch prediction response."""
battery_id: str
predictions: list[PredictResponse]
# ── Recommendation ───────────────────────────────────────────────────────────
class RecommendationRequest(BaseModel):
"""Request for operational recommendations."""
battery_id: str
current_cycle: int = Field(..., ge=1)
current_soh: float = Field(..., ge=0, le=100)
ambient_temperature: float = Field(default=24.0)
top_k: int = Field(default=5, ge=1, le=20)
class SingleRecommendation(BaseModel):
"""One recommendation entry."""
rank: int
ambient_temperature: float
discharge_current: float
cutoff_voltage: float
predicted_rul: float
rul_improvement: float
rul_improvement_pct: float
explanation: str
class RecommendationResponse(BaseModel):
"""Response with ranked recommendations."""
battery_id: str
current_soh: float
recommendations: list[SingleRecommendation]
# ── Model info ───────────────────────────────────────────────────────────────
class ModelInfo(BaseModel):
"""Info about a registered model."""
name: str
version: Optional[str] = None
display_name: Optional[str] = None
family: str
algorithm: Optional[str] = None
target: str
r2: Optional[float] = None
metrics: dict[str, float]
is_default: bool = False
loaded: bool = True
load_error: Optional[str] = None
class HealthResponse(BaseModel):
"""Health check response."""
status: str = "ok"
version: str
models_loaded: int
device: str
# ── Visualization ────────────────────────────────────────────────────────────
class BatteryVizData(BaseModel):
"""Data for 3D battery visualization."""
battery_id: str
soh_pct: float
temperature: float
cycle_number: int
degradation_state: str
color_hex: str = Field(..., description="Color hex code for SOH heatmap")
class DashboardData(BaseModel):
"""Full dashboard payload."""
batteries: list[BatteryVizData]
capacity_fade: dict[str, list[float]]
model_metrics: dict[str, dict[str, float]]
best_model: str