Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| import numpy as np | |
| # Add root directory to sys.path for absolute imports | |
| sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | |
| from openenv.tasks import Task, random_policy, heuristic_policy | |
| from openenv.models import Action | |
| from agent.baselines import ea_only_policy, fr_only_policy, ps_only_policy | |
| from infer import policy as rl_policy | |
| # ========================= | |
| # REAL KPI EVALUATOR | |
| # ========================= | |
| def evaluate_real_kpis(policy_func): | |
| task = Task("medium") | |
| env = task.env | |
| obs = env.reset().to_array() | |
| # Economic assumptions | |
| peak_tariff = 20.0 | |
| fr_price = 0.1 | |
| demand_history = [] | |
| net_history = [] | |
| real_ea = 0 | |
| real_fr = 0 | |
| total_deg = 0 | |
| voltage_violations = 0 | |
| max_line_loading = 0.0 | |
| done = False | |
| while not done: | |
| idx = env.t | |
| action_val = policy_func(obs) | |
| # step | |
| next_obs, _, done, _ = env.step(Action(power=action_val)) | |
| # ✅ actual power used (important for realism) | |
| power = action_val # (correct since no ramp/clip beyond bounds) | |
| # ------------------------- | |
| # GRID CONSTRAINTS TRACKING | |
| # ------------------------- | |
| if env.v_pu < 0.95 or env.v_pu > 1.05: | |
| voltage_violations += 1 | |
| if env.line_loading > max_line_loading: | |
| max_line_loading = env.line_loading | |
| # ------------------------- | |
| # DEGRADATION | |
| # ------------------------- | |
| deg_coeff = 0.02 | |
| total_deg += deg_coeff * (abs(power) ** 1.3) | |
| # ------------------------- | |
| # DEMAND TRACKING | |
| # ------------------------- | |
| d = env.demand_series[idx] | |
| demand_history.append(d) | |
| net_history.append(d + power) | |
| obs = next_obs.to_array() | |
| # ------------------------- | |
| # PEAK SHAVING | |
| # ------------------------- | |
| orig_peak = np.max(demand_history) | |
| new_peak = np.max(net_history) | |
| ps_savings = max(0, (orig_peak - new_peak) * peak_tariff) | |
| peak_reduction = (orig_peak - new_peak) / (orig_peak + 1e-6) | |
| # ------------------------- | |
| # FINAL ECONOMICS & GRID | |
| # ------------------------- | |
| real_ea = env.total_EA | |
| real_fr = env.total_FR | |
| net_profit = (real_ea + real_fr + ps_savings) - total_deg | |
| return net_profit, peak_reduction, voltage_violations, max_line_loading | |
| # ========================= | |
| # RUN | |
| # ========================= | |
| if __name__ == "__main__": | |
| policies = { | |
| "Random": random_policy, | |
| "Heuristic": heuristic_policy, | |
| "EA-Only": ea_only_policy, | |
| "FR-Only": fr_only_policy, | |
| "PS-Only": ps_only_policy, | |
| "RL Agent (Ours)": rl_policy | |
| } | |
| print(f"{'Policy':<20} | {'Avg Net Profit ($)':<18} | {'Peak Reduc %':<12}") | |
| print("-" * 60) | |
| NUM_EPISODES = 5 | |
| for name, pol in policies.items(): | |
| profits = [] | |
| peaks = [] | |
| v_viols = [] | |
| l_loads = [] | |
| for _ in range(NUM_EPISODES): | |
| p, pr, v_v, l_l = evaluate_real_kpis(pol) | |
| profits.append(p) | |
| peaks.append(pr) | |
| v_viols.append(v_v) | |
| l_loads.append(l_l) | |
| # Add grid constraint information to the print output | |
| print(f"{name:<20} | {np.mean(profits):>18.2f} | {np.mean(peaks)*100:>11.1f}% | V-Viols: {np.mean(v_viols):.1f} | MaxLoad: {np.mean(l_loads):.1f}%") | |