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