Skip to content

Commit 2aa9de3

Browse files
authored
Introduce the BatteryPool, and implement power bounds calculation for the pool (#32)
This PR introduces a high-level `BatteryPool` API and supporting telemetry/bounds trackers to compute aggregated dispatch power bounds for a pool of batteries (grouped by inverter↔battery topology), along with a refactor of formula streaming APIs to use metric generics. **Changes:** - Add battery pool telemetry tracking (healthy/unhealthy partitioning with latest telemetry) and bounds aggregation across inverter-battery groups. - Expose `Microgrid`/`BatteryPool` as public high-level APIs and add a bounds example.
2 parents 672dcf8 + 8a56776 commit 2aa9de3

26 files changed

Lines changed: 2117 additions & 46 deletions

RELEASE_NOTES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828

2929
- The resampler's `max_age_in_intervals` has also become configurable, through `LogicalMeterConfig`.
3030

31+
- The `Quantity` trait now exposes numeric operations (`abs`, `floor`, `ceil`, `round`, `trunc`, `fract`, `is_nan`, `is_infinite`, `min`, `max`) as trait methods, so they can be used in generic code over any `Quantity` (including `f32` and all quantity types).
32+
33+
- The `Quantity` trait now provides associated `MIN` and `MAX` constants.
34+
35+
- New `BatteryPool` type (accessible via `Microgrid::battery_pool`) exposing:
36+
- `power()` — a `Formula<Power>` for the pool's aggregated power.
37+
- `power_bounds()` — a `broadcast::Receiver<Vec<Bounds<Power>>>` tracking the pool's power bounds.
38+
3139
## Bug Fixes
3240

3341
<!-- Here goes notable bug fixes that are worth a special mention or explanation -->

examples/bounds.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// License: MIT
2+
// Copyright © 2026 Frequenz Energy-as-a-Service GmbH
3+
4+
use chrono::TimeDelta;
5+
use frequenz_microgrid::Microgrid;
6+
use frequenz_microgrid::{Error, LogicalMeterConfig};
7+
use tracing_subscriber::{
8+
EnvFilter,
9+
fmt::{self},
10+
prelude::*,
11+
};
12+
13+
#[tokio::main]
14+
async fn main() -> Result<(), Error> {
15+
tracing_subscriber::registry()
16+
.with(EnvFilter::new("info,frequenz_microgrid=warn"))
17+
.with(fmt::layer().with_file(true).with_line_number(true))
18+
.init();
19+
20+
let microgrid = Microgrid::try_new(
21+
"http://[::1]:8800",
22+
LogicalMeterConfig::new(TimeDelta::try_seconds(1).unwrap()),
23+
)
24+
.await?;
25+
26+
let mut battery_pool = microgrid.battery_pool(None)?;
27+
let mut bounds_rx = battery_pool.power_bounds();
28+
29+
while let Ok(bounds) = bounds_rx.recv().await {
30+
tracing::info!("Battery pool active-power bounds: {:?}", bounds);
31+
}
32+
33+
Ok(())
34+
}

0 commit comments

Comments
 (0)