157 lines
5.6 KiB
Python
157 lines
5.6 KiB
Python
"""
|
|
Pydantic models for Battery Management Service
|
|
"""
|
|
|
|
from pydantic import BaseModel, Field
|
|
from typing import List, Optional, Dict, Any, Literal
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
|
|
class BatteryState(str, Enum):
|
|
IDLE = "idle"
|
|
CHARGING = "charging"
|
|
DISCHARGING = "discharging"
|
|
MAINTENANCE = "maintenance"
|
|
ERROR = "error"
|
|
|
|
class BatteryType(str, Enum):
|
|
LITHIUM_ION = "lithium_ion"
|
|
LEAD_ACID = "lead_acid"
|
|
NICKEL_METAL_HYDRIDE = "nickel_metal_hydride"
|
|
FLOW_BATTERY = "flow_battery"
|
|
|
|
class BatteryStatus(BaseModel):
|
|
"""Battery status model"""
|
|
battery_id: str = Field(..., description="Unique battery identifier")
|
|
name: str = Field(..., description="Human-readable battery name")
|
|
type: BatteryType = Field(..., description="Battery technology type")
|
|
state: BatteryState = Field(..., description="Current operational state")
|
|
|
|
# Energy metrics
|
|
capacity_kwh: float = Field(..., description="Total battery capacity in kWh")
|
|
stored_energy_kwh: float = Field(..., description="Currently stored energy in kWh")
|
|
state_of_charge: float = Field(..., description="State of charge (0-100%)")
|
|
|
|
# Power metrics
|
|
max_charge_power_kw: float = Field(..., description="Maximum charging power in kW")
|
|
max_discharge_power_kw: float = Field(..., description="Maximum discharging power in kW")
|
|
current_power_kw: float = Field(0, description="Current power flow in kW (positive = charging)")
|
|
|
|
# Technical specifications
|
|
efficiency: float = Field(0.95, description="Round-trip efficiency (0-1)")
|
|
cycles_completed: int = Field(0, description="Number of charge/discharge cycles")
|
|
max_cycles: int = Field(5000, description="Maximum rated cycles")
|
|
|
|
# Health and maintenance
|
|
health_percentage: float = Field(100, description="Battery health (0-100%)")
|
|
temperature_celsius: Optional[float] = Field(None, description="Battery temperature")
|
|
last_maintenance: Optional[datetime] = Field(None, description="Last maintenance date")
|
|
next_maintenance: Optional[datetime] = Field(None, description="Next maintenance date")
|
|
|
|
# Location and installation
|
|
location: Optional[str] = Field(None, description="Physical location")
|
|
building: Optional[str] = Field(None, description="Building identifier")
|
|
room: Optional[str] = Field(None, description="Room identifier")
|
|
|
|
# Operational data
|
|
installed_date: Optional[datetime] = Field(None, description="Installation date")
|
|
last_updated: datetime = Field(default_factory=datetime.utcnow, description="Last status update")
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat() if v else None
|
|
}
|
|
|
|
class BatteryCommand(BaseModel):
|
|
"""Battery control command"""
|
|
battery_id: str = Field(..., description="Target battery ID")
|
|
command: Literal["charge", "discharge", "stop"] = Field(..., description="Command type")
|
|
power_kw: Optional[float] = Field(None, description="Power level in kW")
|
|
duration_minutes: Optional[int] = Field(None, description="Command duration in minutes")
|
|
target_soc: Optional[float] = Field(None, description="Target state of charge (0-100%)")
|
|
|
|
class ChargingRequest(BaseModel):
|
|
"""Battery charging/discharging request"""
|
|
power_kw: float = Field(..., description="Power level in kW", gt=0)
|
|
duration_minutes: Optional[int] = Field(None, description="Duration in minutes", gt=0)
|
|
target_soc: Optional[float] = Field(None, description="Target SOC (0-100%)", ge=0, le=100)
|
|
|
|
class BatteryResponse(BaseModel):
|
|
"""Battery operation response"""
|
|
battery_id: str
|
|
status: Dict[str, Any]
|
|
message: Optional[str] = None
|
|
|
|
class BatteryListResponse(BaseModel):
|
|
"""Response for battery list endpoint"""
|
|
batteries: List[Dict[str, Any]]
|
|
count: int
|
|
total_capacity: float = Field(description="Total system capacity in kWh")
|
|
total_stored_energy: float = Field(description="Total stored energy in kWh")
|
|
|
|
class HistoricalDataRequest(BaseModel):
|
|
"""Request for historical battery data"""
|
|
battery_id: str
|
|
start_time: Optional[datetime] = None
|
|
end_time: Optional[datetime] = None
|
|
hours: int = Field(default=24, description="Hours of data to retrieve")
|
|
|
|
class BatteryHistoricalData(BaseModel):
|
|
"""Historical battery data point"""
|
|
timestamp: datetime
|
|
state_of_charge: float
|
|
power_kw: float
|
|
temperature_celsius: Optional[float] = None
|
|
efficiency: float
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat()
|
|
}
|
|
|
|
class BatteryAnalytics(BaseModel):
|
|
"""Battery system analytics"""
|
|
total_batteries: int
|
|
active_batteries: int
|
|
total_capacity_kwh: float
|
|
total_stored_energy_kwh: float
|
|
average_soc: float
|
|
|
|
# Energy flows
|
|
total_energy_charged_kwh: float
|
|
total_energy_discharged_kwh: float
|
|
net_energy_flow_kwh: float
|
|
|
|
# Efficiency metrics
|
|
round_trip_efficiency: float
|
|
capacity_utilization: float
|
|
|
|
# Health metrics
|
|
average_health: float
|
|
batteries_needing_maintenance: int
|
|
|
|
class MaintenanceAlert(BaseModel):
|
|
"""Battery maintenance alert"""
|
|
battery_id: str
|
|
alert_type: Literal["scheduled", "health", "temperature", "cycles"]
|
|
severity: Literal["info", "warning", "critical"]
|
|
message: str
|
|
recommended_action: str
|
|
timestamp: datetime
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat()
|
|
}
|
|
|
|
class HealthResponse(BaseModel):
|
|
"""Health check response"""
|
|
service: str
|
|
status: str
|
|
timestamp: datetime
|
|
version: str
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat()
|
|
} |