frequenz_microgrid_component_graph/graph/
formulas.rs1use std::collections::BTreeSet;
7
8use crate::ComponentGraph;
9use crate::Edge;
10use crate::Error;
11use crate::Node;
12use crate::component_category::CategoryPredicates;
13
14mod expr;
15mod fallback;
16mod formula;
17mod generators;
18mod traversal;
19
20use expr::Expr;
21pub use formula::Formula;
22
23impl<N, E> ComponentGraph<N, E>
25where
26 N: Node,
27 E: Edge,
28{
29 pub fn consumer_formula(&self) -> Result<Formula, Error> {
31 generators::consumer::ConsumerFormulaBuilder::try_new(self)?.build()
32 }
33
34 pub fn grid_formula(&self) -> Result<Formula, Error> {
36 generators::grid::GridFormulaBuilder::try_new(self)?.build()
37 }
38
39 pub fn producer_formula(&self) -> Result<Formula, Error> {
41 generators::producer::ProducerFormulaBuilder::try_new(self)?.build()
42 }
43
44 pub fn battery_formula(&self, battery_ids: Option<BTreeSet<u64>>) -> Result<Formula, Error> {
49 generators::battery::BatteryFormulaBuilder::try_new(self, battery_ids)?.build()
50 }
51
52 pub fn chp_formula(&self, chp_ids: Option<BTreeSet<u64>>) -> Result<Formula, Error> {
54 generators::category::category_formula(
55 self,
56 chp_ids,
57 |node| node.is_chp(),
58 "a CHP",
59 self.config.prefer_meters_in_chp_formula(),
60 )
61 }
62
63 pub fn pv_formula(&self, pv_inverter_ids: Option<BTreeSet<u64>>) -> Result<Formula, Error> {
65 generators::category::category_formula(
66 self,
67 pv_inverter_ids,
68 |node| node.is_pv_inverter(),
69 "a PV inverter",
70 self.config.prefer_meters_in_pv_formula(),
71 )
72 }
73
74 pub fn wind_turbine_formula(
76 &self,
77 wind_turbine_ids: Option<BTreeSet<u64>>,
78 ) -> Result<Formula, Error> {
79 generators::category::category_formula(
80 self,
81 wind_turbine_ids,
82 |node| node.is_wind_turbine(),
83 "a wind turbine",
84 self.config.prefer_meters_in_wind_turbine_formula(),
85 )
86 }
87
88 pub fn ev_charger_formula(
90 &self,
91 ev_charger_ids: Option<BTreeSet<u64>>,
92 ) -> Result<Formula, Error> {
93 generators::category::category_formula(
94 self,
95 ev_charger_ids,
96 |node| node.is_ev_charger(),
97 "an EV charger",
98 self.config.prefer_meters_in_ev_charger_formula(),
99 )
100 }
101
102 pub fn component_formula(&self, component_id: u64) -> Result<Formula, Error> {
104 Ok(Expr::component(component_id).into())
105 }
106
107 pub fn grid_coalesce_formula(&self) -> Result<Formula, Error> {
116 generators::grid_coalesce::GridCoalesceFormulaBuilder::try_new(self)?.build()
117 }
118
119 pub fn battery_ac_coalesce_formula(
130 &self,
131 battery_ids: Option<BTreeSet<u64>>,
132 ) -> Result<Formula, Error> {
133 generators::battery_ac_coalesce::BatteryAcCoalesceFormulaBuilder::try_new(
134 self,
135 battery_ids,
136 )?
137 .build()
138 }
139
140 pub fn pv_ac_coalesce_formula(
151 &self,
152 pv_inverter_ids: Option<BTreeSet<u64>>,
153 ) -> Result<Formula, Error> {
154 generators::pv_ac_coalesce::PVAcCoalesceFormulaBuilder::try_new(self, pv_inverter_ids)?
155 .build()
156 }
157
158 pub fn component_ac_coalesce_formula(&self, component_id: u64) -> Result<Formula, Error> {
160 Ok(Expr::component(component_id).into())
161 }
162
163 pub fn steam_boiler_formula(
165 &self,
166 steam_boiler_ids: Option<BTreeSet<u64>>,
167 ) -> Result<Formula, Error> {
168 generators::category::category_formula(
169 self,
170 steam_boiler_ids,
171 |node| node.is_steam_boiler(),
172 "a steam boiler",
173 self.config.prefer_meters_in_steam_boiler_formula(),
174 )
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use crate::{Error, graph::test_utils::ComponentGraphBuilder};
181
182 #[test]
186 fn test_component_formula() -> Result<(), Error> {
187 let mut builder = ComponentGraphBuilder::new();
188 let grid = builder.grid();
189 let meter = builder.meter();
190 let inverter = builder.battery_inverter();
191 let battery = builder.battery();
192 builder.connect(grid, meter);
193 builder.connect(meter, inverter);
194 builder.connect(inverter, battery);
195
196 let graph = builder.build(None)?;
197 let inv = inverter.component_id();
198
199 assert_eq!(graph.component_formula(inv)?.to_string(), format!("#{inv}"));
200 assert_eq!(
201 graph.component_ac_coalesce_formula(inv)?.to_string(),
202 format!("#{inv}")
203 );
204 Ok(())
205 }
206}