Flexible Response Optimization for Seasonal Thermal Loads
A framework for comparing different HVAC controllers using OCHRE building simulations to analyze grid impacts.
- Multi-Building Portfolio Analysis: Simulate representative building populations with weights
- Multi-Weather Scenarios: Compare performance across different weather conditions and time periods
- Controller Comparison: Built-in support for demand response, setpoint, and custom controllers
- Statistical Aggregation: Weighted analysis for population-level grid impact assessment
- Extensible Architecture: Easy to add new controllers and analysis methods
This repository uses uv for dependency management:
uv sync --devBasic single-building demo:
uv run python scripts/single_building_demo.pyPortfolio experiment demo:
uv run python scripts/portfolio_demo.pyuv run pytestuv run ruff check .
uv run ruff format .frost/
├── src/frost/ # Main package
│ ├── config.py # Simulation configuration
│ ├── data_manager.py # Building data download/management
│ ├── dwelling_simulator.py # OCHRE simulation wrapper
│ ├── portfolio_runner.py # Multi-building batch experiments
│ ├── analysis.py # Results analysis and comparison
│ └── controllers/ # HVAC controller implementations
├── scripts/ # Demonstration scripts
│ ├── single_building_demo.py # Basic single-building demo
│ └── portfolio_demo.py # Portfolio experiment demo
├── tests/ # Unit tests (organized by functionality)
│ ├── test_analysis/ # Results analysis tests
│ ├── test_config/ # Configuration tests
│ ├── test_controllers/ # Controller tests
│ └── test_data_management/ # Data management tests
├── notebooks/ # Jupyter analysis notebooks
└── data/ # Input files (weather, buildings)
from frost import SimulationConfig, DwellingSimulator, DemandResponseController
# Configure simulation
config = SimulationConfig(
weighted_buildings={"bldg0112631": 1.0},
weather_scenarios=[{
"name": "winter_week",
"weather_file": "USA_MA_Worcester.Rgnl.AP.725095_TMY3.epw",
"start_date": "2018-01-15",
"end_date": "2018-01-22"
}],
upgrade_id=8
)
# Run simulation
simulator = DwellingSimulator(...)
controller = DemandResponseController(...)
results = simulator.simulate(controller)from frost import run_portfolio_experiment, analyze_portfolio_results, load_portfolio_timeseries
# Configure portfolio
config = SimulationConfig(
weighted_buildings={
"bldg0112631": 2500.0, # Represents 2500 buildings
"bldg0459562": 1800.0, # Represents 1800 buildings
},
weather_scenarios=[
{"name": "2018_cold", "weather_file": "MA_2018.epw",
"start_date": "2018-01-15", "end_date": "2018-01-22"},
{"name": "2019_cold", "weather_file": "MA_2019.epw",
"start_date": "2019-02-01", "end_date": "2019-02-08"}
],
upgrade_id=8
)
# Run experiments
results = run_portfolio_experiment(config, controllers)
# Analyze aggregated results
comparator = analyze_portfolio_results(results, save_timeseries=True)
total_load = comparator.get_portfolio_load_profile("controller", "scenario")
# Load individual time series data for detailed analysis
timeseries_data = load_portfolio_timeseries("portfolio_results")
# Filter for specific experiments
noop_data = load_portfolio_timeseries("portfolio_results", controller="NoOpController")
specific_building = load_portfolio_timeseries("portfolio_results", building_id="bldg0112631")Portfolio experiments generate the following outputs in the specified directory:
portfolio_results/
├── portfolio_summary.csv # Summary metrics for each building/controller/scenario
├── scenario_aggregates.csv # Aggregated metrics by controller and scenario
└── portfolio_timeseries.parquet # Complete time series data (efficient Parquet format)
- portfolio_summary.csv: Individual experiment metrics (energy, peak power, etc.)
- scenario_aggregates.csv: Portfolio-level aggregated results
- portfolio_timeseries.parquet: All individual time series data with metadata for detailed analysis
The Parquet format provides 2-10x smaller file sizes and faster loading compared to CSV, while preserving data types and enabling efficient filtering.
See CLAUDE.md for development commands and project-specific guidance.