Skip to main content

frequenz_microgrid/
metric.rs

1// License: MIT
2// Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
4//! Metrics supported by the logical meter.
5
6use crate::logical_meter::formula::aggregation_formula::AggregationFormula;
7use crate::logical_meter::formula::coalesce_formula::CoalesceFormula;
8use crate::{
9    logical_meter::formula, logical_meter::formula::FormulaSubscriber,
10    proto::common::metrics::Metric as MetricPb,
11};
12
13pub trait Metric:
14    std::fmt::Display + std::fmt::Debug + Clone + Copy + PartialEq + Eq + Sync + 'static
15{
16    type FormulaType: FormulaSubscriber<QuantityType = Self::QuantityType>
17        + formula::graph_formula_provider::GraphFormulaProvider<MetricType = Self>
18        + 'static;
19
20    type QuantityType: crate::quantity::Quantity;
21
22    const METRIC: MetricPb;
23}
24
25macro_rules! define_metric {
26    ($({
27        name: $metric_name:ident,
28        formula: $formula:ident,
29        quantity: $quantity:ident
30    }),+ $(,)?) => {
31        $(
32            // Define a metric
33            #[derive(Debug, Clone, Copy, PartialEq, Eq)]
34            pub struct $metric_name;
35
36            // Implement the AcMetric trait for the metric
37            impl Metric for $metric_name {
38                type FormulaType = $formula<$metric_name>;
39                type QuantityType = crate::quantity::$quantity;
40
41                const METRIC: MetricPb = MetricPb::$metric_name;
42            }
43
44            impl std::fmt::Display for $metric_name {
45                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46                    write!(f, "{}", stringify!($metric_name))
47                }
48            }
49
50        )+
51    };
52}
53
54define_metric! {
55    { name: AcPowerActive,         formula: AggregationFormula, quantity: Power },
56    { name: AcPowerReactive,       formula: AggregationFormula, quantity: ReactivePower },
57    { name: AcCurrent,             formula: AggregationFormula, quantity: Current },
58    { name: AcCurrentPhase1,       formula: AggregationFormula, quantity: Current },
59    { name: AcCurrentPhase2,       formula: AggregationFormula, quantity: Current },
60    { name: AcCurrentPhase3,       formula: AggregationFormula, quantity: Current },
61
62    { name: AcVoltage,             formula: CoalesceFormula,    quantity: Voltage },
63    { name: AcVoltagePhase1N,      formula: CoalesceFormula,    quantity: Voltage },
64    { name: AcVoltagePhase2N,      formula: CoalesceFormula,    quantity: Voltage },
65    { name: AcVoltagePhase3N,      formula: CoalesceFormula,    quantity: Voltage },
66    { name: AcVoltagePhase1Phase2, formula: CoalesceFormula,    quantity: Voltage },
67    { name: AcVoltagePhase2Phase3, formula: CoalesceFormula,    quantity: Voltage },
68    { name: AcVoltagePhase3Phase1, formula: CoalesceFormula,    quantity: Voltage },
69
70    { name: AcFrequency,           formula: CoalesceFormula,    quantity: Frequency },
71}