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