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