Adding a New Component#
This guide explains how to add a new plant component type to Hercules. The process involves three steps:
Create the component class
Register the component
Document the component
Step 1: Create the Component Class#
Create a new Python file in hercules/plant_components/ for your component. The class must:
Inherit from
ComponentBaseDefine a
component_categoryclass attributeImplement
__init__,step, andget_initial_conditions_and_meta_datamethods
Minimal Example#
# hercules/plant_components/my_component.py
from hercules.plant_components.component_base import ComponentBase
class MyComponent(ComponentBase):
"""Brief description of the component."""
component_category = "generator" # or "storage" or "load"
def __init__(self, h_dict, component_name):
"""Initialize the component.
Args:
h_dict: Dictionary containing simulation parameters.
component_name: Unique name for this instance (the YAML key).
"""
# Call base class init first
super().__init__(h_dict, component_name)
# Read component-specific parameters from h_dict
self.rated_power = h_dict[self.component_name]["rated_power"]
# Initialize internal state
self.power = 0.0
def get_initial_conditions_and_meta_data(self, h_dict):
"""Add initial conditions and metadata to h_dict.
Called once during HybridPlant initialization.
Args:
h_dict: Dictionary containing simulation parameters.
Returns:
Updated h_dict with initial conditions.
"""
h_dict[self.component_name]["power"] = self.power
return h_dict
def step(self, h_dict):
"""Advance the simulation by one time step.
Args:
h_dict: Dictionary containing current simulation state.
Returns:
Updated h_dict with component outputs.
"""
# Read inputs (e.g., setpoint from controller)
setpoint = h_dict[self.component_name].get("power_setpoint", 0.0)
# Compute outputs
self.power = min(setpoint, self.rated_power)
# Write outputs to h_dict
h_dict[self.component_name]["power"] = self.power
return h_dict
Key Requirements#
Requirement |
Description |
|---|---|
|
Must be |
|
Sets |
|
All components must write a |
Return |
Both |
Component Categories#
generator: Produces power (wind, solar, gas turbine). Power is summed intolocally_generated_power. Generator power should be positive signed to represent production.storage: Stores and releases power (batteries). Sign convention is automatically handled byHybridPlantin the following way. It is assumed at the component model level, battery dischage is negatively signed. At the plant levelHybridPlantinverts the sign of the setpoint going into the battery component model, and inverts the power output coming out of the battery component model. This way at the plant level, positive power represents discharge/production, consistent with the generator category.load: Consumes power (electrolyzers). Power of loads should be negative signed to represent consumption.
While only generator power is included in locally_generated_power, all categories’ power are combined into the total plant power in the HybridPlant class.
Step 2: Register the Component#
Add the component to COMPONENT_REGISTRY in hercules/hybrid_plant.py (see Hybrid Plant Components).
The key string (e.g., "MyComponent") is the component_type value users will specify in their YAML input files.
Testing#
Add unit tests in tests/my_component_test.py. Test at minimum:
Initialization with valid parameters
stepmethod produces expected outputsget_initial_conditions_and_meta_datasets initial state
Run tests with:
pytest tests/my_component_test.py -v
Step 3: Document the Component#
Create a docs page: Add
docs/my_component.mdwith usage examples and parameter reference.Update the table of contents: Add the page to
docs/_toc.ymlunder “Plant Components”:- caption: Plant Components chapters: - file: wind - file: solar_pv # ... - file: my_component # Add your page
Update reference tables: Add your component to the tables in:
hybrid_plant.md — Available Components table
component_types.md — Complete Component Type Reference table
Summary Checklist#
Create
hercules/plant_components/my_component.pyInherit from
ComponentBaseDefine
component_categoryclass attributeImplement
__init__,step,get_initial_conditions_and_meta_dataImport and add to
COMPONENT_REGISTRYinhercules/hybrid_plant.pyCreate tests in
tests/my_component_test.pyCreate
docs/my_component.mdAdd to
docs/_toc.ymlUpdate reference tables in
hybrid_plant.mdandcomponent_types.md