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    client::proto::common::metrics::Metric as MetricPb, logical_meter::formula,
10    logical_meter::formula::FormulaSubscriber,
11};
12
13pub trait Metric:
14    std::fmt::Display + std::fmt::Debug + Clone + Copy + PartialEq + Eq + Sync + 'static
15{
16    #[expect(private_bounds)]
17    type FormulaType: FormulaSubscriber<QuantityType = Self::QuantityType>
18        + formula::graph_formula_provider::GraphFormulaProvider<MetricType = Self>
19        + 'static;
20
21    type QuantityType: crate::quantity::Quantity;
22
23    const METRIC: MetricPb;
24
25    fn str_name() -> &'static str;
26}
27
28macro_rules! define_metric {
29    ($({
30        name: $metric_name:ident,
31        formula: $formula:ident,
32        quantity: $quantity:ident
33    }),+ $(,)?) => {
34        $(
35            // Define a metric
36            #[derive(Debug, Clone, Copy, PartialEq, Eq)]
37            pub struct $metric_name;
38
39            // Implement the AcMetric trait for the metric
40            impl Metric for $metric_name {
41                type FormulaType = $formula<$metric_name>;
42                type QuantityType = crate::quantity::$quantity;
43
44                const METRIC: MetricPb = MetricPb::$metric_name;
45
46                fn str_name() -> &'static str {
47                    stringify!($metric_name)
48                }
49            }
50
51            impl std::fmt::Display for $metric_name {
52                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53                    write!(f, "{}", stringify!($metric_name))
54                }
55            }
56        )+
57    };
58}
59
60define_metric! {
61    { name: DcPower,               formula: AggregationFormula, quantity: Power },
62    { name: AcPowerActive,         formula: AggregationFormula, quantity: Power },
63    { name: AcPowerReactive,       formula: AggregationFormula, quantity: ReactivePower },
64    { name: AcCurrent,             formula: AggregationFormula, quantity: Current },
65    { name: AcCurrentPhase1,       formula: AggregationFormula, quantity: Current },
66    { name: AcCurrentPhase2,       formula: AggregationFormula, quantity: Current },
67    { name: AcCurrentPhase3,       formula: AggregationFormula, quantity: Current },
68
69    { name: AcVoltage,             formula: CoalesceFormula,    quantity: Voltage },
70    { name: AcVoltagePhase1N,      formula: CoalesceFormula,    quantity: Voltage },
71    { name: AcVoltagePhase2N,      formula: CoalesceFormula,    quantity: Voltage },
72    { name: AcVoltagePhase3N,      formula: CoalesceFormula,    quantity: Voltage },
73    { name: AcVoltagePhase1Phase2, formula: CoalesceFormula,    quantity: Voltage },
74    { name: AcVoltagePhase2Phase3, formula: CoalesceFormula,    quantity: Voltage },
75    { name: AcVoltagePhase3Phase1, formula: CoalesceFormula,    quantity: Voltage },
76
77    { name: AcFrequency,           formula: CoalesceFormula,    quantity: Frequency },
78}