Spaces:
Sleeping
Sleeping
| import numpy as np | |
| import pandas as pd | |
| import os | |
| def generate_synthetic_data(num_days=30, output_path="synthetic_bess_data.csv"): | |
| """ | |
| Generate synthetic time-series data for BESS RL Environment. | |
| Features: | |
| - price: Electricity price ($/MWh), higher during peak hours (e.g. 17:00-21:00) | |
| - load: Building/Grid load (MW), peak daytime. | |
| - frequency: Grid frequency (Hz), centered around 50 or 60. We use a standardized deviation -1.0 to 1.0. | |
| """ | |
| total_hours = num_days * 24 | |
| # Time | |
| hours_of_day = np.arange(total_hours) % 24 | |
| # Price ($/MWh) | |
| # Base price around $40. Peak price (17-21) goes up to $150. | |
| base_price = np.random.normal(40, 5, total_hours) | |
| peak_multiplier = np.where((hours_of_day >= 17) & (hours_of_day <= 21), 3.0, 1.0) | |
| price = base_price * peak_multiplier + np.random.normal(0, 10, total_hours) | |
| price = np.clip(price, 10, None) # Min price $10 | |
| # Load (MW) | |
| # Base load around 10MW, peaks during day 9-18 | |
| base_load = np.random.normal(10, 2, total_hours) | |
| load_multiplier = np.where((hours_of_day >= 9) & (hours_of_day <= 18), 1.5, 1.0) | |
| load = base_load * load_multiplier + np.random.normal(0, 1.5, total_hours) | |
| load = np.clip(load, 2, None) | |
| # Frequency Deviation (Hz) | |
| # Ideally 0. Deviates occasionally. | |
| # Simple autoregressive model for frequency to simulate persistence | |
| freq_dev = np.zeros(total_hours) | |
| freq_dev[0] = np.random.normal(0, 0.05) | |
| for i in range(1, total_hours): | |
| freq_dev[i] = 0.7 * freq_dev[i-1] + np.random.normal(0, 0.02) | |
| freq_dev = np.clip(freq_dev, -0.5, 0.5) | |
| df = pd.DataFrame({ | |
| "hour_of_day": hours_of_day, | |
| "price": price, | |
| "load": load, | |
| "frequency_deviation": freq_dev | |
| }) | |
| # Ensure directory exists if saving | |
| if output_path is not None: | |
| os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) | |
| df.to_csv(output_path, index=False) | |
| print(f"Saved synthetic data to {output_path}") | |
| return df | |
| if __name__ == "__main__": | |
| generate_synthetic_data(num_days=365, output_path=os.path.join(os.path.dirname(__file__), "synthetic_bess_data.csv")) | |