Skip to main content

frequenz_microgrid/
microgrid.rs

1// License: MIT
2// Copyright © 2026 Frequenz Energy-as-a-Service GmbH
3
4//! High-level interface for the Microgrid API.
5
6mod bounds_aggregation;
7mod caching_sender;
8mod pool_bounds;
9mod pool_bounds_tracker;
10mod pool_validation;
11
12#[cfg(test)]
13mod test_utils;
14
15mod battery_pool;
16pub use battery_pool::BatteryPool;
17
18mod pv_pool;
19pub use pv_pool::PvPool;
20
21pub(crate) mod telemetry_tracker;
22pub use telemetry_tracker::battery_pool_telemetry_tracker::{
23    BatteryPoolSnapshot, InverterBatteryGroup,
24};
25pub use telemetry_tracker::component_partition::ComponentHealthPartition;
26pub use telemetry_tracker::inverter_battery_group_telemetry_tracker::InverterBatteryGroupStatus;
27pub use telemetry_tracker::pv_pool_telemetry_tracker::PvPoolSnapshot;
28
29use crate::{Error, LogicalMeterConfig, LogicalMeterHandle, MicrogridClientHandle};
30
31/// A high-level interface for the Microgrid API.
32pub struct Microgrid {
33    client: MicrogridClientHandle,
34    logical_meter: LogicalMeterHandle,
35}
36
37impl Microgrid {
38    /// Creates a new `Microgrid` instance with the given microgrid API URL and
39    /// logical meter configuration.
40    ///
41    /// The microgrid API connection is established lazily and connection or
42    /// component-graph build errors during setup are retried indefinitely, so
43    /// this call blocks until the server is reachable and returns valid data.
44    /// Returns an error only if the URL is malformed or if the provided
45    /// logical meter configuration is invalid.
46    pub async fn try_new(
47        url: impl Into<String>,
48        config: LogicalMeterConfig,
49    ) -> Result<Self, Error> {
50        let client = MicrogridClientHandle::try_new(url).await?;
51        let logical_meter = LogicalMeterHandle::try_new(client.clone(), config).await?;
52
53        Ok(Microgrid {
54            client,
55            logical_meter,
56        })
57    }
58
59    /// Creates a new `Microgrid` instance from the given client and logical
60    /// meter handles.
61    pub fn new_from_handles(
62        client: MicrogridClientHandle,
63        logical_meter: LogicalMeterHandle,
64    ) -> Self {
65        Microgrid {
66            client,
67            logical_meter,
68        }
69    }
70
71    /// Returns a handle to the Microgrid client.
72    pub fn client(&self) -> MicrogridClientHandle {
73        self.client.clone()
74    }
75
76    /// Returns a handle to the logical meter.
77    pub fn logical_meter(&self) -> LogicalMeterHandle {
78        self.logical_meter.clone()
79    }
80
81    pub fn battery_pool(&self, component_ids: Option<Vec<u64>>) -> Result<BatteryPool, Error> {
82        BatteryPool::try_new(
83            component_ids.map(|ids| ids.into_iter().collect()),
84            self.client.clone(),
85            self.logical_meter.clone(),
86        )
87    }
88
89    pub fn pv_pool(&self, component_ids: Option<Vec<u64>>) -> Result<PvPool, Error> {
90        PvPool::try_new(
91            component_ids.map(|ids| ids.into_iter().collect()),
92            self.client.clone(),
93            self.logical_meter.clone(),
94        )
95    }
96}