surabhi-24/meta-hackathon
0
1"""2models.py3---------4Pydantic action / observation / state models for the Power Grid OpenEnv client.5Mirrors the structure of carla_env/models.py, calendar_env/models.py, etc.6 7Usage8-----9 from power_grid import PowerGridAction, PowerGridEnv10 async with PowerGridEnv(base_url="http://localhost:7860") as env:11 result = await env.reset(difficulty="hard", scenario="cascade_blackout")12 result = await env.step(PowerGridAction(dispatch_mw=[80,60,40,45,35,25]))13"""14 15from __future__ import annotations16 17from typing import Dict, List, Optional18from pydantic import BaseModel, Field19 20 21# ─────────────────────────────────────────────────────────────────────────────22# Action23# ─────────────────────────────────────────────────────────────────────────────24 25class PowerGridAction(BaseModel):26 """Action sent to the environment at each step.27 28 Fields29 ------30 dispatch_mw : list of 6 floats31 MW setpoints for generators 0-5.32 Gen 0 (Coal, Bus 1): 20-100 MW33 Gen 1 (Gas, Bus 2): 10-80 MW34 Gen 2 (Gas, Bus 3): 5-50 MW35 Gen 3 (Wind, Bus 6): 0-50 MW (weather-limited)36 Gen 4 (Hydro,Bus 8): 5-40 MW37 Gen 5 (Solar,Bus12): 0-30 MW (weather-limited)38 """39 dispatch_mw: List[float] = Field(40 default=[80.0, 60.0, 40.0, 45.0, 35.0, 25.0],41 description="MW setpoints for 6 generators",42 min_length=6,43 max_length=6,44 )45 46 47# ─────────────────────────────────────────────────────────────────────────────48# Observation (returned after reset() and step())49# ─────────────────────────────────────────────────────────────────────────────50 51class PowerGridObservation(BaseModel):52 """Full environment observation after reset or step.53 54 Physics fields55 --------------56 bus_angles_deg : voltage angles at all 14 buses (degrees)57 line_flows_mw : signed DC power flows on all 20 lines (MW)58 line_loading_frac : |flow| / rating per line (1.0 = at capacity)59 line_status : True = online, False = relay-tripped60 gen_dispatch_mw : actual generator output after dispatch (MW)61 gen_available_mw : maximum currently available output (weather-limited)62 gen_online : True = online, False = forced outage63 bus_loads_mw : stochastic load at each bus (MW)64 total_load_mw : sum of all bus loads65 total_gen_mw : sum of all generator outputs66 power_balance_mw : generation minus load (MW); ideal = 067 cf_wind : wind capacity factor [0,1]68 cf_solar : solar capacity factor [0,1]69 70 Episode metadata71 ----------------72 step : current step within episode73 difficulty : "easy" | "medium" | "hard"74 scenario_id : name of active scenario (None if free-play)75 scenario_description : human-readable scenario description76 77 Step result fields (None on reset)78 --------------------79 reward : scalar reward [-1, +1]80 reward_components : per-component reward breakdown81 done : True when episode ends82 relay_tripped : True if a relay trip happened this step83 disturbance : type and description of any disturbance this step84 """85 86 # Physics87 bus_angles_deg: List[float]88 line_flows_mw: List[float]89 line_loading_frac: List[float]90 line_status: List[bool]91 gen_dispatch_mw: List[float]92 gen_available_mw: List[float]93 gen_online: List[bool]94 bus_loads_mw: List[float]95 total_load_mw: float96 total_gen_mw: float97 power_balance_mw: float98 cf_wind: float99 cf_solar: float100 101 # Episode metadata102 step: int103 difficulty: str104 scenario_id: Optional[str] = None105 scenario_description: Optional[str] = None106 107 # Step result (None on reset)108 reward: Optional[float] = None109 reward_components: Optional[Dict[str, float]] = None110 done: Optional[bool] = None111 relay_tripped: Optional[bool] = None112 disturbance: Optional[Dict] = None113 114 115# ─────────────────────────────────────────────────────────────────────────────116# State (server-side persistent state)117# ─────────────────────────────────────────────────────────────────────────────118 119class PowerGridState(BaseModel):120 """Server-side state snapshot (returned by GET /state).121 122 Extends observation with grading-related episode statistics.123 """124 observation: PowerGridObservation125 episode_reward: float = 0.0126 overload_events: int = 0127 relay_trips: int = 0128 gen_outages: int = 0129 steps_elapsed: int = 0130 131 132# ─────────────────────────────────────────────────────────────────────────────133# Reset / Step request models (used internally by server)134# ─────────────────────────────────────────────────────────────────────────────135 136class ResetRequest(BaseModel):137 difficulty: str = "easy"138 scenario_id: Optional[str] = None139 seed: Optional[int] = None140 141 142class StepRequest(BaseModel):143 action: List[float]144 