Skip to content

Commit 672dcf8

Browse files
authored
Expect metric only as a generic argument in logical meter formulas (#31)
2 parents 153221f + 1404c90 commit 672dcf8

8 files changed

Lines changed: 85 additions & 82 deletions

File tree

RELEASE_NOTES.md

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

99
- `LogicalMeterConfig` instances can't be created directly anymore, and need to be created using the `LogicalMeterConfig::new` method. This helps avoid future breaking changes, as we add more config parameters.
1010

11+
- Formula streaming methods in the `LogicalMeterHandle` no longer take metric as a function parameter, but expect a generic argument. For example:
12+
13+
*Old syntax:*
14+
```rust
15+
let formula_grid = logical_meter.grid(metric::AcPowerActive)?;
16+
let formula_pv = logical_meter.pv(None, metric::AcVoltage)?;
17+
```
18+
19+
*New syntax:*
20+
```rust
21+
let formula_grid = logical_meter.grid::<metric::AcPowerActive>()?;
22+
let formula_pv = logical_meter.pv::<metric::AcVoltage>(None)?;
23+
```
24+
1125
## New Features
1226

1327
- It is now possible to change the default resampling function, and to override the resampling function for specific metrics.

examples/logical_meter.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ async fn main() -> Result<(), Error> {
1919
.init();
2020

2121
let client = MicrogridClientHandle::try_new("http://[::1]:8800").await?;
22-
let mut logical_meter = LogicalMeterHandle::try_new(
22+
let logical_meter = LogicalMeterHandle::try_new(
2323
client,
2424
LogicalMeterConfig::new(TimeDelta::try_seconds(1).unwrap()),
2525
)
2626
.await?;
2727

28-
let formula_grid = logical_meter.grid(metric::AcPowerActive)?;
29-
let formula_pv = logical_meter.pv(None, metric::AcPowerActive)?;
30-
let formula_consumer = logical_meter.consumer(metric::AcPowerActive)?;
28+
let formula_grid = logical_meter.grid::<metric::AcPowerActive>()?;
29+
let formula_pv = logical_meter.pv::<metric::AcPowerActive>(None)?;
30+
let formula_consumer = logical_meter.consumer::<metric::AcPowerActive>()?;
3131

3232
// Create a formula that calculates `grid_power - pv_power + consumer_power + 100kW`.
33-
let formula = logical_meter.grid(metric::AcPowerActive)?
34-
- logical_meter.pv(None, metric::AcPowerActive)?
35-
+ logical_meter.consumer(metric::AcPowerActive)?
33+
let formula = logical_meter.grid::<metric::AcPowerActive>()?
34+
- logical_meter.pv::<metric::AcPowerActive>(None)?
35+
+ logical_meter.consumer::<metric::AcPowerActive>()?
3636
+ Power::from_kilowatts(100.0);
3737

3838
let mut rx = formula.subscribe().await?;
@@ -68,10 +68,10 @@ async fn main() -> Result<(), Error> {
6868

6969
// Create a formula that calculates the grid voltage as:
7070
// COALESCE(grid_voltage, AVG(grid_voltage_p1, grid_voltage_p2, grid_voltage_p3) * SQRT(3))
71-
let formula_grid_voltage = logical_meter.grid(metric::AcVoltage)?.coalesce(
72-
logical_meter.grid(metric::AcVoltagePhase1N)?.avg(vec![
73-
logical_meter.grid(metric::AcVoltagePhase2N)?,
74-
logical_meter.grid(metric::AcVoltagePhase3N)?,
71+
let formula_grid_voltage = logical_meter.grid::<metric::AcVoltage>()?.coalesce(
72+
logical_meter.grid::<metric::AcVoltagePhase1N>()?.avg(vec![
73+
logical_meter.grid::<metric::AcVoltagePhase2N>()?,
74+
logical_meter.grid::<metric::AcVoltagePhase3N>()?,
7575
])? * 3.0_f32.sqrt(),
7676
)?;
7777

@@ -95,18 +95,21 @@ async fn main() -> Result<(), Error> {
9595
drop(consumer_rx);
9696

9797
let mut p1 = logical_meter
98-
.grid(metric::AcVoltagePhase1N)?
98+
.grid::<metric::AcVoltagePhase1N>()?
9999
.subscribe()
100100
.await?;
101101
let mut p2 = logical_meter
102-
.grid(metric::AcVoltagePhase2N)?
102+
.grid::<metric::AcVoltagePhase2N>()?
103103
.subscribe()
104104
.await?;
105105
let mut p3 = logical_meter
106-
.grid(metric::AcVoltagePhase3N)?
106+
.grid::<metric::AcVoltagePhase3N>()?
107+
.subscribe()
108+
.await?;
109+
let mut three_phase = logical_meter
110+
.grid::<metric::AcVoltage>()?
107111
.subscribe()
108112
.await?;
109-
let mut three_phase = logical_meter.grid(metric::AcVoltage)?.subscribe().await?;
110113

111114
loop {
112115
let sample = grid_voltage_rx.recv().await.unwrap();

src/logical_meter/formula.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
//! Formula module for the logical meter.
55
6+
use std::marker::PhantomData;
7+
68
use async_trait::async_trait;
79
pub(crate) mod aggregation_formula;
810
mod async_formula;
@@ -37,20 +39,19 @@ pub trait FormulaSubscriber: std::fmt::Display + Sync + Send {
3739
/// Parameters for creating a logical meter formula.
3840
pub(super) struct FormulaParams<F: GraphFormulaConnector, M: Metric> {
3941
pub(super) formula: F::GraphFormulaType,
40-
pub(super) metric: M,
4142
pub(super) instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
43+
phantom: PhantomData<M>,
4244
}
4345

4446
impl<F: GraphFormulaConnector, M: Metric> FormulaParams<F, M> {
4547
pub(super) fn new(
4648
formula: F::GraphFormulaType,
47-
metric: M,
4849
instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
4950
) -> Self {
5051
Self {
5152
formula,
52-
metric,
5353
instructions_tx,
54+
phantom: PhantomData,
5455
}
5556
}
5657
}

src/logical_meter/formula/aggregation_formula.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
//! An formula that supports aggregation operations.
55
6+
use std::marker::PhantomData;
7+
68
use super::{FormulaParams, FormulaSubscriber, GraphFormulaConnector};
79
use crate::{
810
Error, Sample, logical_meter::logical_meter_actor, metric::Metric, quantity::Quantity,
@@ -13,8 +15,8 @@ use tokio::sync::{broadcast, mpsc, oneshot};
1315
#[derive(Clone)]
1416
pub struct AggregationFormula<M: Metric> {
1517
formula: frequenz_microgrid_component_graph::AggregationFormula,
16-
metric: M,
1718
instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
19+
phantom: PhantomData<M>,
1820
}
1921

2022
impl<M: Metric> std::fmt::Display for AggregationFormula<M> {
@@ -56,8 +58,8 @@ impl<M: Metric> From<FormulaParams<AggregationFormula<M>, M>> for AggregationFor
5658
fn from(params: FormulaParams<AggregationFormula<M>, M>) -> Self {
5759
Self {
5860
formula: params.formula,
59-
metric: params.metric,
6061
instructions_tx: params.instructions_tx,
62+
phantom: PhantomData,
6163
}
6264
}
6365
}
@@ -66,8 +68,8 @@ impl<M: Metric> From<AggregationFormula<M>> for FormulaParams<AggregationFormula
6668
fn from(formula: AggregationFormula<M>) -> Self {
6769
FormulaParams {
6870
formula: formula.formula,
69-
metric: formula.metric,
7071
instructions_tx: formula.instructions_tx,
72+
phantom: PhantomData,
7173
}
7274
}
7375
}

src/logical_meter/formula/coalesce_formula.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
//! An coalesce formula.
55
6+
use std::marker::PhantomData;
7+
68
use super::{FormulaParams, FormulaSubscriber, GraphFormulaConnector};
79
use crate::{
810
Error, Sample, logical_meter::logical_meter_actor, metric::Metric, quantity::Quantity,
@@ -13,8 +15,8 @@ use tokio::sync::{broadcast, mpsc, oneshot};
1315
#[derive(Clone)]
1416
pub struct CoalesceFormula<M: Metric> {
1517
formula: frequenz_microgrid_component_graph::CoalesceFormula,
16-
metric: M,
1718
instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
19+
phantom: PhantomData<M>,
1820
}
1921

2022
impl<M: Metric> std::fmt::Display for CoalesceFormula<M> {
@@ -56,8 +58,8 @@ impl<M: Metric> From<FormulaParams<CoalesceFormula<M>, M>> for CoalesceFormula<M
5658
fn from(params: FormulaParams<CoalesceFormula<M>, M>) -> Self {
5759
Self {
5860
formula: params.formula,
59-
metric: params.metric,
6061
instructions_tx: params.instructions_tx,
62+
phantom: PhantomData,
6163
}
6264
}
6365
}
@@ -66,7 +68,7 @@ impl<M: Metric> From<CoalesceFormula<M>> for FormulaParams<CoalesceFormula<M>, M
6668
fn from(formula: CoalesceFormula<M>) -> Self {
6769
FormulaParams {
6870
formula: formula.formula,
69-
metric: formula.metric,
71+
phantom: formula.phantom,
7072
instructions_tx: formula.instructions_tx,
7173
}
7274
}

src/logical_meter/formula/graph_formula_provider.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ macro_rules! graph_formula_provider {
2222

2323
fn $fnname(
2424
_graph: &ComponentGraph<ElectricalComponent, ElectricalComponentConnection>,
25-
metric: Self::MetricType,
2625
_instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
2726
$($idsparam: Option<BTreeSet<u64>>,)?
2827
$($idparam: u64,)?
@@ -31,7 +30,7 @@ macro_rules! graph_formula_provider {
3130
format!(
3231
"The component graph does not support {} formula generation for {}.",
3332
stringify!($fnname),
34-
metric.to_string()
33+
Self::MetricType::str_name()
3534
)
3635
));
3736
}
@@ -70,7 +69,6 @@ macro_rules! impl_graph_formula_provider {
7069

7170
fn $fnname(
7271
graph: &ComponentGraph<ElectricalComponent, ElectricalComponentConnection>,
73-
metric: Self::MetricType,
7472
instructions_tx: mpsc::Sender<logical_meter_actor::Instruction>,
7573
$($idsparam: Option<BTreeSet<u64>>,)?
7674
$($idparam: u64,)?
@@ -80,7 +78,7 @@ macro_rules! impl_graph_formula_provider {
8078
format!("Could not get {} formula: {e}", stringify!($fnname))
8179
)
8280
})?;
83-
Ok(FormulaParams::new(formula, metric, instructions_tx).into())
81+
Ok(FormulaParams::new(formula, instructions_tx).into())
8482
}
8583

8684
)+};

0 commit comments

Comments
 (0)