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