EnerOS v0.34.0
Release Date: 2026-03-21 Codename: Adapt Git Tag: v0.34.0 Support Status: Stable Total Crates: 72 (6 new) Test Cases: 9300+ (700 new)
Overview
EnerOS v0.34.0 “Adapt” is an adaptive dispatching-focused release, upgrading grid dispatching from “preset strategies + manual intervention” to a “topology-aware + real-time optimization + automatic adjustment” adaptive dispatching system. Based on the AI Agent capabilities from v0.31.0 and the ML runtime from v0.32.0, this release builds an intelligent dispatching kernel that dynamically adjusts dispatching strategies based on grid operation status, load changes, and renewable energy fluctuations.
The core design philosophy of the Adapt release is “topology as strategy” — dispatching strategies are no longer fixed rule tables, but are derived in real-time from grid topology, equipment status, and constraint boundaries. When topology changes (switch operations, equipment commissioning/decommissioning, renewable energy integration), dispatching strategies are automatically recalculated and issued without manual reconfiguration. This enables EnerOS to handle the frequent topology changes and bidirectional power flow brought by high-penetration renewable energy integration.
This release introduces five core capabilities: Adaptive Dispatching Engine, Dynamic Topology Awareness, Load Balancer, Optimized Dispatching Strategy Library, and Real-time Adjustment Executor. All capabilities are implemented through five new crates: eneros-adapt, eneros-adapt-topology, eneros-adapt-balance, eneros-adapt-strategy, and eneros-adapt-executor.
Key Metrics
| Metric | Value | Description |
|---|---|---|
| Dispatching strategy calculation latency | 45ms | 1000 nodes |
| Topology change response | < 200ms | Strategy recompute |
| Renewable energy utilization improvement | 8.3% | Compared with fixed strategy |
| Line load balancing degree | 0.92 | Gini coefficient |
| New Crates | 6 | Dispatching-related |
| New tests | 700+ | Includes 110 end-to-end |
New Features
1. Adaptive Dispatching Engine
Adds the eneros-adapt crate, providing a kernel-native adaptive dispatching engine that replaces traditional fixed-strategy dispatchers. The engine takes grid topology, real-time power flow, load forecasts, and constraint boundaries as input, and outputs optimal generation output allocation and power flow control commands.
Dispatching Optimization Objectives
| Objective | Weight | Description |
|---|---|---|
| Economy | 30% | Minimize generation cost |
| Safety | 25% | Maximize constraint margin |
| Renewable utilization | 20% | Minimize wind/solar curtailment |
| Network loss | 15% | Minimize transmission loss |
| Balance | 10% | Line load balancing |
Dispatching Engine API
use eneros_adapt::{AdaptiveScheduler, ScheduleConfig, Objective};
let scheduler = AdaptiveScheduler::new(&ctx)
.config(ScheduleConfig {
objective: Objective::MultiObjective {
economic: 0.30,
safety: 0.25,
renewable: 0.20,
loss: 0.15,
balance: 0.10,
},
horizon: Duration::minutes(15),
resolution: Duration::minutes(5),
solver: Solver::InteriorPoint,
max_iter: 200,
tolerance: 1e-6,
})
.build().await?;
// Execute adaptive dispatching
let schedule = scheduler.optimize().await?;
println!("Dispatching plan:");
for unit in &schedule.generator_dispatch {
println!(" {} -> {:.1} MW (cost: {:.2} CNY/MWh)",
unit.bus_id, unit.target_mw, unit.cost);
}
println!("Total generation cost: {:.0} CNY", schedule.total_cost);
println!("Renewable utilization: {:.1}%", schedule.renewable_utilization * 100.0);
println!("Max line loading: {:.1}%", schedule.max_line_loading * 100.0);
Dispatching Cycles
| Cycle | Time Scale | Trigger | Optimization Scope |
|---|---|---|---|
| Ultra-short-term | 5-15 minutes | Real-time | Whole network |
| Short-term | 15 minutes - 4 hours | Scheduled/event | Electrical island |
| Medium-term | 4-24 hours | Scheduled | Region |
| Long-term | 1-7 days | Daily | System |
2. Dynamic Topology Awareness
Adds the eneros-adapt-topology crate, enabling the dispatching engine to sense topology changes in real-time and automatically recompute strategies. When switch operations, equipment commissioning/decommissioning, or fault isolation cause topology changes, dispatching strategies complete recomputation and issuance within 200ms.
Topology Change Response
use eneros_adapt_topology::{TopologyAwareScheduler, TopologyEvent};
let topo_scheduler = TopologyAwareScheduler::new(&scheduler, &network);
// Subscribe to topology change events
network.on_event(|event: TopologyEvent| {
match event {
TopologyEvent::SwitchOpened(switch_id) => {
// Switch opened, may change electrical island structure
topo_scheduler.trigger_recompute(
Reason::TopologyChange,
Priority::High,
);
}
TopologyEvent::GeneratorTripped(bus_id) => {
// Generator tripped, emergency re-dispatch
topo_scheduler.trigger_recompute(
Reason::GeneratorLoss(bus_id),
Priority::Critical,
);
}
TopologyEvent::RenewableSurge(bus_id, mw) => {
// Renewable output surge, adjust utilization strategy
topo_scheduler.trigger_recompute(
Reason::RenewableSpike(bus_id, mw),
Priority::Medium,
);
}
_ => {}
}
});
Electrical Island-aware Dispatching
// Dispatching engine senses electrical island boundaries, avoiding cross-island dispatching
let islands = network.topology().find_islands();
for island in &islands {
let island_schedule = scheduler.optimize_island(island).await?;
// Self-balance within island, support via tie lines when necessary
}
Topology Change Scenarios
| Scenario | Response Strategy | Latency |
|---|---|---|
| Switch operation | Recompute electrical islands, rebalance | < 200ms |
| Generator trip | Emergency load shedding/reserve deployment | < 100ms |
| Line fault | Fault isolation, load transfer | < 150ms |
| Renewable integration | Update utilization strategy | < 500ms |
| Equipment commissioning/decommissioning | Adjust adjustable resource pool | < 300ms |
3. Load Balancer
Adds the eneros-adapt-balance crate, explicitly considering line load balancing in dispatching optimization to avoid single line overload while other lines are lightly loaded.
Balancing Algorithms
| Algorithm | Principle | Applicable Scenario |
|---|---|---|
| Even distribution | Distribute by line capacity ratio | Routine |
| Weighted least load | Select path with maximum remaining capacity | Real-time |
| Topology optimization | Adjust switch states to change power flow distribution | Planning |
| Sensitivity method | Based on generation shift factors | Optimization |
Load Balancing API
use eneros_adapt_balance::{LoadBalancer, BalanceConfig, BalanceMetric};
let balancer = LoadBalancer::new(&ctx)
.config(BalanceConfig {
metric: BalanceMetric::GiniCoefficient,
target: 0.90, // Target Gini coefficient
max_loading: 0.85, // Max single-line load rate
sensitivity: true, // Enable sensitivity analysis
})
.build().await?;
// Calculate current balance
let balance = balancer.evaluate(&network).await?;
println!("Current Gini coefficient: {:.3}", balance.gini);
println!("Max load rate: {:.1}%", balance.max_loading * 100.0);
println!("Overloaded lines: {:?}", balance.overloaded_lines);
// Generate balancing suggestions
let suggestions = balancer.suggest(&network).await?;
for s in &suggestions {
println!("Suggestion: {} (expected improvement {:.1}%)",
s.description, s.improvement);
}
4. Optimized Dispatching Strategy Library
Adds the eneros-adapt-strategy crate, with built-in classic power domain dispatching strategies, supporting strategy combination and dynamic switching.
Strategy Matrix
| Strategy | Type | Applicable Scenario | Computational Complexity |
|---|---|---|---|
| Economic Dispatch (ED) | Classic | Normal operation | Low |
| Optimal Power Flow (OPF) | Classic | Refined operation | Medium |
| Unit Commitment (UC) | Classic | Day-ahead planning | High |
| Deep Reinforcement Learning | AI | Complex scenarios | Medium (inference) |
| Fuzzy Control | Intelligent | Uncertain scenarios | Low |
| Multi-objective Pareto | Optimization | Decision support | High |
Strategy Selection and Switching
use eneros_adapt_strategy::{StrategyRegistry, Strategy, StrategySelector};
let mut registry = StrategyRegistry::new();
registry.register(Strategy::economic_dispatch())?;
registry.register(Strategy::optimal_power_flow())?;
registry.register(Strategy::reinforcement_learning("rl-dqn-v2"))?;
registry.register(Strategy::multi_objective_pareto())?;
// Dynamic strategy selector
let selector = StrategySelector::new()
.rule(|ctx| {
if ctx.renewable_ratio > 0.4 {
Strategy::reinforcement_learning("rl-dqn-v2") // High renewable ratio uses RL
} else if ctx.has_congestion {
Strategy::optimal_power_flow() // Congestion uses OPF
} else {
Strategy::economic_dispatch() // Normal uses ED
}
});
// Auto-select and execute
let strategy = selector.select(&ctx).await?;
let schedule = strategy.execute(&ctx).await?;
Strategy Evaluation Comparison
// Compare effects of different strategies
let comparison = registry.compare_all(&ctx).await?;
println!("Strategy comparison:");
println!("{:<20} {:<10} {:<10} {:<10} {:<10}",
"Strategy", "Cost(CNY)", "Util%", "Loss", "Balance");
for result in &comparison {
println!("{:<20} {:<10.0} {:<10.1}% {:<10.2} {:<10.3}",
result.strategy_name, result.cost,
result.renewable_pct, result.loss_mw, result.gini);
}
5. Real-time Adjustment Executor
Adds the eneros-adapt-executor crate, converting dispatching strategies into executable device control commands and monitoring execution effectiveness in real-time to form a closed loop.
Execution Loop
use eneros_adapt_executor::{Executor, ExecutionResult};
let executor = Executor::new(&ctx)
.max_ramp_rate(0.05) // Max 5% adjustment per minute
.dead_band(0.02) // 2% dead band
.feedback_loop(true) // Enable closed-loop feedback
.build().await?;
// Execute dispatching plan
let result = executor.execute(&schedule).await?;
match result {
ExecutionResult::Success => {
println!("Dispatching plan executed successfully");
}
ExecutionResult::Partial(failures) => {
for f in &failures {
println!("Device {} execution failed: {}", f.bus_id, f.reason);
}
// Auto-rollback to last feasible plan
executor.rollback().await?;
}
ExecutionResult::Rejected(reason) => {
println!("Plan rejected by constraint engine: {}", reason);
}
}
Execution Safety Constraints
| Constraint | Description | Default |
|---|---|---|
| Ramp rate | Generator output change rate | 5%/min |
| Dead band | Minimum adjustment | 2% |
| Delay | Device action interval | 30s |
| Concurrency | Simultaneous adjusting devices | 10 |
| Validation | Pre-execution constraint check | Mandatory |
Closed-loop Feedback
// Monitor effects after execution, auto-correct when deviation is too large
executor.on_feedback(|feedback| {
let deviation = (feedback.actual - feedback.target).abs() / feedback.target;
if deviation > 0.05 {
// Deviation exceeds 5%, trigger correction
executor.correct(feedback).await?;
}
}).await?;
Improvements
- Power Flow Calculation: Newton’s method solver adds sparse matrix preprocessing, 118-node calculation reduced from 32ms to 18ms
- Constraint Engine: Added transient stability constraint, supporting 3-second dynamic safety validation
- Timeseries Engine: Real-time data writes support WAL async flushing, throughput improved 30%
- Agent Runtime: Dispatching Agent supports priority preemption, urgent tasks can interrupt lower priority
- Observability: Full-chain tracing of dispatching flow, supporting plan replay and comparison
Bug Fixes
- Fixed
eneros-adaptincorrect inter-island power exchange calculation in multi-island scenarios (#3404) - Fixed
eneros-adapt-topologytopology change events being lost in concurrent scenarios (#3410) - Fixed
eneros-adapt-balanceGini coefficient calculation divide-by-zero in single-line scenarios (#3416) - Fixed
eneros-adapt-strategystrategy selector frequently switching at high renewable ratios (#3422) - Fixed
eneros-adapt-executorramp rate limit not correctly applied with concurrent multi-device (#3428)
Breaking Changes
AdaptiveScheduler::optimize: Return type changed fromScheduletoResult<Schedule>Strategytrait: Addedevaluatemethod, effect evaluation must be implementedExecutor::execute: Parameter changed from&Scheduleto&SchedulePlan
Upgrade Guide
- Update the
enerosdependency inCargo.tomlto0.34.0 - Run
eneros adapt initto initialize adaptive dispatching configuration - Configure dispatching strategies and safety parameters in
eneros.toml - Refer to
eneros adapt benchmarkto evaluate old vs new strategy effects
Acknowledgments
Thanks to the 30 contributors who submitted 450+ commits, and to dispatching automation experts for strategy validation.