From 0942da8c85538c764ac215cd3e66d394d0403ffa Mon Sep 17 00:00:00 2001 From: tomni Date: Mon, 15 Dec 2025 13:13:53 +0100 Subject: [PATCH 01/17] * Changed TimeFilter to use frequenz.api.common.v1alpha8.types.Interval to align with MarketMetering API. * Formatting to align with other Frequenz APIs Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 408 +++++++++++------- 1 file changed, 245 insertions(+), 163 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index ea498a2..f1fe93e 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -14,56 +14,62 @@ package frequenz.api.reporting.v1alpha10; import "google/protobuf/timestamp.proto"; +import "frequenz/api/common/v1alpha8/types/interval.proto"; import "frequenz/api/common/v1alpha8/metrics/metrics.proto"; import "frequenz/api/common/v1alpha8/microgrid/electrical_components/electrical_components.proto"; import "frequenz/api/common/v1alpha8/microgrid/microgrid.proto"; import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; -// The Reporting service provides services for real-time and historical metrics monitoring -// of various microgrid components like Batteries, EV Chargers, and Inverters. +// The Reporting service provides services for real-time and historical +// metrics monitoring of various microgrid components like Batteries, EV +// Chargers, and Inverters. // -// Utilize these APIs for tasks ranging from real-time metric streaming to complex, -// formula-driven historical data aggregation. For detailed information on component -// categories and the metrics they provide, please consult the referenced component categories -// imported above. +// Utilize these APIs for tasks ranging from real-time metric streaming to +// complex, formula-driven historical data aggregation. For detailed +// information on component categories and the metrics they provide, please +// consult the referenced component categories imported above. // service Reporting { // Streams metrics for a list of microgrid components. // // !!! note - // This RPC endpoint streams metrics data for components of one or more microgrids. - // Clients need to provide at least one microgrid ID and one component ID - // to get a result. - rpc ReceiveMicrogridComponentsDataStream(ReceiveMicrogridComponentsDataStreamRequest) + // This RPC endpoint streams metrics data for components of one or more + // microgrids. Clients need to provide at least one microgrid ID and + // one component ID to get a result. + rpc ReceiveMicrogridComponentsDataStream + (ReceiveMicrogridComponentsDataStreamRequest) returns (stream ReceiveMicrogridComponentsDataStreamResponse) {} - // Streams aggregated metrics based on user-defined formulas for a list of microgrid - // components. + // Streams aggregated metrics based on user-defined formulas for a list of + // microgrid components. // // !!! note - // This RPC endpoint retrieves aggregated historical metrics data based on user-defined - // formulas for microgrid components. At least one formula for one microgrid must be provided - // for a valid result. - rpc ReceiveAggregatedMicrogridComponentsDataStream(ReceiveAggregatedMicrogridComponentsDataStreamRequest) + // This RPC endpoint retrieves aggregated historical metrics data based + // on user-defined formulas for microgrid components. At least one + // formula for one microgrid must be provided for a valid result. + rpc ReceiveAggregatedMicrogridComponentsDataStream + (ReceiveAggregatedMicrogridComponentsDataStreamRequest) returns (stream ReceiveAggregatedMicrogridComponentsDataStreamResponse) {} // Streams metrics for a list of microgrid sensors. // // !!! note - // This RPC endpoint streams metrics data for sensors of one or more microgrids. - // Clients need to provide at least one microgrid ID and one sensor ID - // to get a result. - rpc ReceiveMicrogridSensorsDataStream(ReceiveMicrogridSensorsDataStreamRequest) + // This RPC endpoint streams metrics data for sensors of one or more + // microgrids. Clients need to provide at least one microgrid ID and + // one sensor ID to get a result. + rpc ReceiveMicrogridSensorsDataStream + (ReceiveMicrogridSensorsDataStreamRequest) returns (stream ReceiveMicrogridSensorsDataStreamResponse) {} - // Streams aggregated metrics based on user-defined formulas for a list of microgrid - // sensors. + // Streams aggregated metrics based on user-defined formulas for a list of + // microgrid sensors. // // !!! note - // This RPC endpoint retrieves aggregated historical metrics data based on user-defined - // formulas for microgrid sensors. At least one formula for one microgrid must be provided - // for a valid result. - rpc ReceiveAggregatedMicrogridSensorsDataStream(ReceiveAggregatedMicrogridSensorsDataStreamRequest) + // This RPC endpoint retrieves aggregated historical metrics data based + // on user-defined formulas for microgrid sensors. At least one formula + // for one microgrid must be provided for a valid result. + rpc ReceiveAggregatedMicrogridSensorsDataStream + (ReceiveAggregatedMicrogridSensorsDataStreamRequest) returns (stream ReceiveAggregatedMicrogridSensorsDataStreamResponse) {} } @@ -74,7 +80,8 @@ enum FilterOption { FILTER_OPTION_INCLUDE = 2; } -// Time-filter defining the historical window and real-time behaviour of the stream. +// Time-filter defining the historical window and real-time behaviour of the +// stream. // // Semantics: // - If `end_time` is provided, it MUST be ≤ the current server time. The @@ -93,39 +100,46 @@ enum FilterOption { // // Validation rules: // - end_time > now() → INVALID_ARGUMENT +// message TimeFilter { - // Optional UTC start time for the query. - google.protobuf.Timestamp start_time = 1; - - // Optional UTC end time for the query. - google.protobuf.Timestamp end_time = 2; + // Optional; Time window for matching sample interval start timestamps. + // + // If omitted, samples from all timestamps are included. + frequenz.api.common.v1alpha8.types.Interval interval = 1; } // Resampling options for aggregated microgrid components data. +// // If data is resampled, all samples that fall in a left-closed time interval -// determined by the resolution will be aggregated. -// At the moment only mean aggregation is supported. -// The timestamp for each aggregated sample represents the beginning of its corresponding -// time interval, marking the earliest point from which data was aggregated. +// determined by the resolution will be aggregated. At the moment only mean +// aggregation is supported. The timestamp for each aggregated sample +// represents the beginning of its corresponding time interval, marking the +// earliest point from which data was aggregated. +// message ResamplingOptions { // Optional resampling resolution for the data, represented in seconds. // If omitted, data will be returned in its original resolution. optional uint32 resolution = 1; } -// Message defining the aggregation configuration for a custom formula within a specific microgrid. +// Message defining the aggregation configuration for a custom formula within +// a specific microgrid. // -// The AggregationConfig allows clients to specify how metrics should be aggregated across -// microgrid components. It serves as the configuration guideline for any aggregation operation. +// The AggregationConfig allows clients to specify how metrics should be +// aggregated across microgrid components. It serves as the configuration +// guideline for any aggregation operation. // // !!! example -// To calculate the total voltage across three components in series with IDs 1, 2, and 3, the -// configuration could look like: +// To calculate the total voltage across three components in series with +// IDs 1, 2, and 3, the configuration could look like: +// +// ```json // { // microgrid_id: 42, // metric: DC_VOLTAGE_V, // aggregation_formula: "#1 + #2 + #3" // } +// ``` // message AggregationConfig { // ID of the microgrid for which the formula is being specified. @@ -133,35 +147,41 @@ message AggregationConfig { // The metric that is to be aggregated using the specified formula. // - // !!! caution - // Ensure the chosen metric is supported by all relevant microgrid components. - // Failure to meet these conditions might results in an aggregation error. + // !!! caution "Supported metrics" + // Ensure the chosen metric is supported by all relevant microgrid + // components. Failure to meet these conditions might results in an + // aggregation error. frequenz.api.common.v1alpha8.metrics.Metric metric = 2; // The formula used for aggregating the component metric for this microgrid. // // !!! info // Two types of aggregation formulas are supported: - // 1. Aggregate functions: These are standard aggregation functions like `sum()` and `avg()`. + // 1. Aggregate functions: These are standard aggregation functions + // like `sum()` and `avg()`. // Example: `sum(#1,#2)`, `avg(#3,#4)` // - // 2. Dedicated formulas: These support basic math operators while concatenating microgrid - // component IDs. + // 2. Dedicated formulas: These support basic math operators while + // concatenating microgrid component IDs. // Example: `#1 + #2 - #3`, `(#3 * #2) /# 1` // - // Additionally, metric connection identifiers can be used in the formula, for components - // that e.g. provide the same metric from multiple connections/sensors. - // Example: `sum(#1[connection0], #2, #3)`, `#1[connection0] + #2[connection1]` + // Additionally, metric connection identifiers can be used in the + // formula, for components that e.g. provide the same metric from + // multiple connections/sensors. + // Example: + // `sum(#1[connection0], #2, #3)`, `#1[connection0] + #2[connection1]` string aggregation_formula = 3; } -// Defines a single aggregated metric sample, which represents a consolidated metric value -// over a collection of microgrid components within a specific timeframe. +// Defines a single aggregated metric sample, which represents a consolidated +// metric value over a collection of microgrid components within a specific +// timeframe. // -// This message serves to encapsulate aggregate metrics derived from multiple component -// measurements. It is particularly useful in scenarios where an overall metric needs to be -// calculated for a set of components. For instance, you could use it to represent the average -// voltage across multiple sources within a microgrid or to calculate the average state of +// This message serves to encapsulate aggregate metrics derived from multiple +// component measurements. It is particularly useful in scenarios where an +// overall metric needs to be calculated for a set of components. For +// instance, you could use it to represent the average voltage across +// multiple sources within a microgrid or to calculate the average state of // charge of several batteries. // message SimpleAggregatedMetricValue { @@ -176,28 +196,33 @@ message SimpleAggregatedMetricValue { frequenz.api.common.v1alpha8.metrics.SimpleMetricValue sample = 2; } -// Message defining a metric to receive data for, optionally filtering by connections. +// Message defining a metric to receive data for, optionally filtering by +// connections. // -// This message allows clients to request data for a specific metric, and optionally -// filter the data by connection identifiers. This is particularly useful when a metric can -// originate from multiple connections within a component, such as different DC strings for -// batteries or PV arrays connected to a hybrid inverter. +// This message allows clients to request data for a specific metric, and +// optionally filter the data by connection identifiers. This is particularly +// useful when a metric can originate from multiple connections within a +// component, such as different DC strings for batteries or PV arrays +// connected to a hybrid inverter. // // !!! note -// The `MetricConnections` message enables fine-grained control over which are included in the data stream. -// If multiple `MetricConnections` messages are specified for different metrics, the filters apply -// separately to each metric. -// The `connections` specified here correspond to the `connections` field in the `MetricSample` message -// defined in the common API. By filtering on `connections`, you effectively select which `MetricSample` -// messages to receive based on their `connections` value. +// The `MetricConnections` message enables fine-grained control over +// which are included in the data stream. If multiple `MetricConnections` +// messages are specified for different metrics, the filters apply +// separately to each metric. The `connections` specified here correspond +// to the `connections` field in the `MetricSample` message defined in +// the common API. By filtering on `connections`, you effectively select +// which `MetricSample` messages to receive based on their `connections` +// value. // // !!! example -// Suppose you have a hybrid inverter that provides the `VOLTAGE` metric from both its battery and -// PV array. If you're only interested in the voltage measurements from the battery, you can use -// `Metrics` message to specify the `VOLTAGE` metric and set `connections` to `["dc_battery_1"]` -// for the DC string connected to a battery. +// Suppose you have a hybrid inverter that provides the `VOLTAGE` metric +// from both its battery and PV array. If you're only interested in the +// voltage measurements from the battery, you can use `Metrics` message +// to specify the `VOLTAGE` metric and set `connections` to +// `["dc_battery_1"]` for the DC string connected to a battery. // -// ``` +// ```json // { // "metric": "VOLTAGE", // "connections": ["dc_battery_1"] @@ -207,29 +232,35 @@ message SimpleAggregatedMetricValue { message MetricConnections { // The metric for which data is requested. // - // If `connections` are specified, only data for this metric from those connections will be returned. - // If no `connections` are specified, data from all connections for this metric will be returned. + // If `connections` are specified, only data for this metric from those + // connections will be returned. If no `connections` are specified, data + // from all connections for this metric will be returned. frequenz.api.common.v1alpha8.metrics.Metric metric = 1; - // An optional list of connections to filter the data for the specified metric. + // An optional list of connections to filter the data for the specified + // metric. // - // Each connection corresponds to the `connections` field in `MetricSample` messages - // (see the common API definition). - // If this list is empty or not specified, data from all sources for this metric will be returned. + // Each connection corresponds to the `connections` field in `MetricSample` + // messages (see the common API definition). If this list is empty or not + // specified, data from all sources for this metric will be returned. // // !!! important - // The connections identifiers must match exactly those used in the `MetricSample` messages. - // Ensure that the connections specified here are valid for the given metric and component. + // The connections identifiers must match exactly those used in the + // `MetricSample` messages. Ensure that the connections specified here + // are valid for the given metric and component. // // !!! important - // There is an important distinction between these connection strings, and the `ComponentConnection` - // message in the common API. A connection string here may, unlike the `ComponentConnection` message, - // refer to a connection that is not present in the microgrid's component graph. + // There is an important distinction between these connection strings, + // and the `ComponentConnection` message in the common API. A + // connection string here may, unlike the `ComponentConnection` message, + // refer to a connection that is not present in the microgrid's + // component graph. // // !!! example - // For a metric that can come from multiple DC strings in a PV array, you might specify: + // For a metric that can come from multiple DC strings in a PV array, + // you might specify: // - // ``` + // ```json // { // "connections": ["dc_string_1", "dc_string_2"] // } @@ -242,8 +273,9 @@ message MetricConnections { // measurements, and other information for individual microgrid components. // // !!! note -// In addition to the raw metrics, the API can also return additional information -// like errors or operational states of the components during the specified time period. +// In addition to the raw metrics, the API can also return additional +// information like errors or operational states of the components during +// the specified time period. // message ReceiveMicrogridComponentsDataStreamRequest { // Include options for filtering microgrid components data. @@ -252,10 +284,12 @@ message ReceiveMicrogridComponentsDataStreamRequest { // Specifies which additional fields should be included in the response. // message IncludeOptions { - // Optional bound inclusion. By default, bounds are not included in the response. + // Optional bound inclusion. By default, bounds are not included in the + // response. optional FilterOption bounds = 1; - // Optional operational state inclusion. By default, states are not included in the response. + // Optional operational state inclusion. By default, states are not + // included in the response. optional FilterOption states = 2; } @@ -265,37 +299,44 @@ message ReceiveMicrogridComponentsDataStreamRequest { // The filter criteria defined here are applied universally across all // specified microgrids and their respective components. message StreamFilter { - // Optional resampling options like resolution for the data, represented in seconds. + // Optional resampling options like resolution for the data, represented + // in seconds. // If omitted, data will be returned in its original representation. ResamplingOptions resampling_options = 1; - // Include options specifying additional fields to be included in the response. + // Include options specifying additional fields to be included in the + // response. IncludeOptions include_options = 2; // Optional time-based filter criteria. - // If omitted, data will start streaming from the timestamp that the request was received. + // If omitted, data will start streaming from the timestamp that the + // request was received. TimeFilter time_filter = 3; } - // Encapsulates the microgrid ID and the component IDs within that microgrid for which - // the historical data should be retrieved. + // Encapsulates the microgrid ID and the component IDs within that + // microgrid for which the historical data should be retrieved. // // !!! note - // Each entry in this repeated field associates a microgrid ID with its respective - // component IDs. At least one such association must be provided for a valid request. + // Each entry in this repeated field associates a microgrid ID with its + // respective component IDs. At least one such association must be + // provided for a valid request. repeated frequenz.api.common.v1alpha8.microgrid.MicrogridElectricalComponentIDs microgrid_components = 1; // List of metrics to receive data for, each possibly with connection filters. // // !!! note - // At least one metric must be specified. Each metric can have an optional list of connections. - // If connections are provided for a metric, only data from those connections will be returned. - // If no connections are provided for a metric, data from all connections will be returned for that metric. + // At least one metric must be specified. Each metric can have an + // optional list of connections. If connections are provided for a + // metric, only data from those connections will be returned. + // If no connections are provided for a metric, data from all + // connections will be returned for that metric. // // !!! example - // To receive `VOLTAGE` data only from the battery connection and `CURRENT` data from all connections: + // To receive `VOLTAGE` data only from the battery connection and + // `CURRENT` data from all connections: // - // ``` + // ```json // { // "metrics": [ // { @@ -304,18 +345,20 @@ message ReceiveMicrogridComponentsDataStreamRequest { // }, // { // "metric": "CURRENT" - // // No connections specified; data from all connections will be returned for CURRENT + // // No connections specified; data from all connections will be + // // returned for CURRENT // } // ] // } // ``` repeated MetricConnections metrics = 2; - // General filter that applies to the data retrieval for all specified microgrids and components. + // General filter that applies to the data retrieval for all specified + // microgrids and components. // // !!! note - // The filter can specify a list of metrics to be return but also specify bounds, operational - // state, or errors to be returned. + // The filter can specify a list of metrics to be return but also + // specify bounds, operational state, or errors to be returned. StreamFilter filter = 3; } @@ -323,10 +366,10 @@ message ReceiveMicrogridComponentsDataStreamRequest { // // !!! note // The microgrid's components are provided as single data samples that -// encapsulate metrics, bounds, errors, and operational states along with their -// associated timestamps. Each response message covers a single microgrid. -// If multiple microgrids are provided in the request, expect sequential messages -// in the stream. +// encapsulate metrics, bounds, errors, and operational states along with +// their associated timestamps. Each response message covers a single +// microgrid. If multiple microgrids are provided in the request, expect +// sequential messages in the stream. // // !!! example // Example output structure: @@ -339,8 +382,17 @@ message ReceiveMicrogridComponentsDataStreamRequest { // metric_samples: [ // /* all metrics belong to the same timestamp */ // /* sample is type MetricSampleVariant */ -// { sample_time: "2023-10-01T00:00:00Z", metric: "DC_VOLTAGE_V", sample: {...}, bounds: {...} }, -// { sample_time: "2023-10-01T00:00:00Z", metric: "DC_CURRENT_A", sample: {...}, bounds: {...} } +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "DC_VOLTAGE_V", +// sample: {...}, bounds: {...} +// }, +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "DC_CURRENT_A", +// sample: {...}, +// bounds: {...} +// } // ], // state: { // sample_time: "2023-10-01T00:00:13.12Z", @@ -354,8 +406,18 @@ message ReceiveMicrogridComponentsDataStreamRequest { // metric_samples: [ // /* all metrics belong to the same timestamp */ // /* sample is type MetricSampleVariant */ -// { sample_time: "2023-10-01T00:00:00Z", metric: "DC_VOLTAGE_V", sample: {...}, bounds: {...} }, -// { sample_time: "2023-10-01T00:00:00Z", metric: "DC_CURRENT_A", sample: {...}, bounds: {...} } +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "DC_VOLTAGE_V", +// sample: {...}, +// bounds: {...} +// }, +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "DC_CURRENT_A", +// sample: {...}, +// bounds: {...} +// } // ], // state: { // sample_time: "2023-10-01T00:00:13.12Z", @@ -372,26 +434,30 @@ message ReceiveMicrogridComponentsDataStreamResponse { // Microgrid ID for which the components and samples are reported. uint64 microgrid_id = 1; - // List of components within this microgrid, each with its associated data samples. - repeated frequenz.api.common.v1alpha8.microgrid.electrical_components.ElectricalComponentTelemetry components = 2; + // List of components within this microgrid, each with its associated data + // samples. + repeated frequenz.api.common.v1alpha8.microgrid.electrical_components. + ElectricalComponentTelemetry components = 2; } -// Message defining the request format for streaming aggregated historical metrics. -// This request allows to specify custom aggregation formulas, along with general -// filtering. +// Message defining the request format for streaming aggregated historical +// metrics. // -// At least one aggregation formula config must be provided. The aggregation -// follows the passive sign convention. +// This request allows to specify custom aggregation formulas, along with +// general filtering. At least one aggregation formula config must be +// provided. The aggregation follows the passive sign convention. // message ReceiveAggregatedMicrogridComponentsDataStreamRequest { // General filter criteria for querying microgrid components data. message AggregationStreamFilter { - // Optional resampling options like resolution for the data, represented in seconds. + // Optional resampling options like resolution for the data, represented + // in seconds. // If omitted, data will be returned in its original representation. ResamplingOptions resampling_options = 1; // Optional time-based filter criteria. - // If omitted, data will start streaming from the timestamp that the request was received. + // If omitted, data will start streaming from the timestamp that the + // request was received. TimeFilter time_filter = 2; } @@ -402,14 +468,15 @@ message ReceiveAggregatedMicrogridComponentsDataStreamRequest { AggregationStreamFilter filter = 2; } -// Message defining the response format for a stream that fetches aggregated real-time metrics -// for the provided custom aggregation formulas. +// Message defining the response format for a stream that fetches aggregated +// real-time metrics for the provided custom aggregation formulas. // // !!! note -// The formula and metric must have been specified in the corresponding request. -// A single aggregated sample for the metric is returned in the sample field. Each message -// covers a single formula. For multiple formulars provided in the request, expect sequential -// messages in the stream. +// The formula and metric must have been specified in the corresponding +// request. A single aggregated sample for the metric is returned in the +// sample field. Each message covers a single formula. For multiple +// formulars provided in the request, expect sequential messages in the +// stream. // // !!! example // Given a stream output, a single sample might be: @@ -431,7 +498,8 @@ message ReceiveAggregatedMicrogridComponentsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; - // Aggregated sample value and corresponding UTC timestamp when it was sampled. + // Aggregated sample value and corresponding UTC timestamp when it was + // sampled. SimpleAggregatedMetricValue sample = 2; } @@ -439,8 +507,9 @@ message ReceiveAggregatedMicrogridComponentsDataStreamResponse { // measurements, and other information for individual microgrid sensors. // // !!! note -// In addition to the raw metrics, the API can also return additional information -// like errors or operational states of the sensors during the specified time period. +// In addition to the raw metrics, the API can also return additional +// information like errors or operational states of the sensors during +// the specified time period. // message ReceiveMicrogridSensorsDataStreamRequest { // Include options for filtering microgrid sensors data. @@ -449,7 +518,8 @@ message ReceiveMicrogridSensorsDataStreamRequest { // Specifies which additional fields should be included in the response. // message IncludeOptions { - // Optional operational state inclusion. By default, states are not included in the response. + // Optional operational state inclusion. By default, states are not + // included in the response. optional FilterOption states = 1; } @@ -459,38 +529,45 @@ message ReceiveMicrogridSensorsDataStreamRequest { // The filter criteria defined here are applied universally across all // specified microgrids and their respective sensors. message StreamFilter { - // Optional resampling options like resolution for the data, represented in seconds. + // Optional resampling options like resolution for the data, represented + // in seconds. // If omitted, data will be returned in its original representation. ResamplingOptions resampling_options = 1; - // Include options specifying additional fields to be included in the response. + // Include options specifying additional fields to be included in the + // response. IncludeOptions include_options = 2; // Optional time-based filter criteria. - // If omitted, data will start streaming from the timestamp that the request was received. + // If omitted, data will start streaming from the timestamp that the + // request was received. TimeFilter time_filter = 3; } - // Encapsulates the microgrid ID and the sensor IDs within that microgrid for which - // the historical data should be retrieved. + // Encapsulates the microgrid ID and the sensor IDs within that microgrid + // for which the historical data should be retrieved. // // !!! note - // Each entry in this repeated field associates a microgrid ID with its respective - // sensor IDs. At least one such association must be provided for a valid request. + // Each entry in this repeated field associates a microgrid ID with its + // respective sensor IDs. At least one such association must be + // provided for a valid request. repeated frequenz.api.common.v1alpha8.microgrid.MicrogridSensorIDs microgrid_sensors = 1; // List of metrics to receive data for, each possibly with connection filters. // // !!! note - // At least one metric must be specified. Each metric can have an optional list of connections. - // If connections are provided for a metric, only data from those connections will be returned. - // If no connections are provided for a metric, data from all connections will be returned for that metric. + // At least one metric must be specified. Each metric can have an + // optional list of connections. If connections are provided for a + // metric, only data from those connections will be returned. If no + // connections are provided for a metric, data from all connections + // will be returned for that metric. repeated MetricConnections metrics = 2; - // General filter that applies to the data retrieval for all specified microgrids and sensors. + // General filter that applies to the data retrieval for all specified + // microgrids and sensors. // // !!! note - // The filter can specify a list of metrics to be return but also specify bounds, operational - // state, or errors to be returned. + // The filter can specify a list of metrics to be return but also + // specify bounds, operational state, or errors to be returned. StreamFilter filter = 3; } @@ -498,35 +575,39 @@ message ReceiveMicrogridSensorsDataStreamRequest { // // !!! note // The microgrid's sensors are provided as single data samples that -// encapsulate metrics, bounds, errors, and operational states along with their -// associated timestamps. Each response message covers a single microgrid. -// If multiple microgrids are provided in the request, expect sequential messages -// in the stream. +// encapsulate metrics, bounds, errors, and operational states along with +// their associated timestamps. Each response message covers a single +// microgrid. If multiple microgrids are provided in the request, expect +// sequential messages in the stream. // message ReceiveMicrogridSensorsDataStreamResponse { // Microgrid ID for which the sensors and samples are reported. uint64 microgrid_id = 1; - // List of sensors within this microgrid, each with its associated data samples. - repeated frequenz.api.common.v1alpha8.microgrid.sensors.SensorTelemetry sensors = 2; + // List of sensors within this microgrid, each with its associated data + // samples. + repeated frequenz.api.common.v1alpha8.microgrid.sensors.SensorTelemetry + sensors = 2; } -// Message defining the request format for streaming aggregated historical metrics. -// This request allows to specify custom aggregation formulas, along with general -// filtering. +// Message defining the request format for streaming aggregated historical +// metrics. // -// At least one aggregation formula config must be provided. The aggregation -// follows the passive sign convention. +// This request allows to specify custom aggregation formulas, along with general +// filtering. At least one aggregation formula config must be provided. The +// aggregation follows the passive sign convention. // message ReceiveAggregatedMicrogridSensorsDataStreamRequest { // General filter criteria for querying microgrid sensors data. message AggregationStreamFilter { - // Optional resampling options like resolution for the data, represented in seconds. + // Optional resampling options like resolution for the data, represented + // in seconds. // If omitted, data will be returned in its original representation. ResamplingOptions resampling_options = 1; // Optional time-based filter criteria. - // If omitted, data will start streaming from the timestamp that the request was received. + // If omitted, data will start streaming from the timestamp that the + // request was received. TimeFilter time_filter = 2; } @@ -537,13 +618,14 @@ message ReceiveAggregatedMicrogridSensorsDataStreamRequest { AggregationStreamFilter filter = 2; } -// Message defining the response format for a stream that fetches aggregated real-time metrics -// for the provided custom aggregation formulas. +// Message defining the response format for a stream that fetches aggregated +// real-time metrics for the provided custom aggregation formulas. // // !!! note -// The formula and metric must have been specified in the corresponding request. -// A single aggregated sample for the metric is returned in the sample field. Each message -// covers a single formula. For multiple formulars provided in the request, expect sequential +// The formula and metric must have been specified in the corresponding +// request. A single aggregated sample for the metric is returned in the +// sample field. Each message covers a single formula. For multiple +// formulars provided in the request, expect sequential // messages in the stream. // message ReceiveAggregatedMicrogridSensorsDataStreamResponse { From 1ce5186da5094585112f675652073fa522715e7e Mon Sep 17 00:00:00 2001 From: tomni Date: Mon, 15 Dec 2025 20:34:01 +0100 Subject: [PATCH 02/17] * Extended the header documentation Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 147 +++++++++++++++--- 1 file changed, 127 insertions(+), 20 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index f1fe93e..1a32be9 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -20,33 +20,127 @@ import "frequenz/api/common/v1alpha8/microgrid/electrical_components/electrical_ import "frequenz/api/common/v1alpha8/microgrid/microgrid.proto"; import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; -// The Reporting service provides services for real-time and historical -// metrics monitoring of various microgrid components like Batteries, EV -// Chargers, and Inverters. +// The Reporting service provides access to historical and real-time telemetry +// data from microgrids. // -// Utilize these APIs for tasks ranging from real-time metric streaming to -// complex, formula-driven historical data aggregation. For detailed -// information on component categories and the metrics they provide, please -// consult the referenced component categories imported above. +// It exposes raw metrics originating from microgrid electrical components +// and sensors. +// +// Electrical components represent assets involved in energy conversion, +// storage, or flow within a microgrid (e.g. batteries, inverters, EV +// chargers, meters). Sensors represent auxiliary measurement devices that +// are not part of the electrical topology (e.g. temperature, irradiance, +// environmental, or external reference sensors). +// +// In addition to raw metrics, clients may optionally request server-side +// aggregation and resampling of metrics, applied deterministically to both +// historical and real-time telemetry data based on explicitly provided +// parameters. +// +// Aggregation is defined using user-provided formulas, while resampling +// allows telemetry samples to be grouped into fixed time windows. +// +// The service is designed as a general-purpose data access layer for telemetry +// analysis, notebooks, forecasting, trading, and other downstream analytics +// and optimization systems. The service is streaming-first and enables the +// replay of historical telemetry data for a requested time range, and +// may continue with real-time telemetry updates if specified. +// +// Aggregation, resampling, and filtering are all optional and performed +// server-side according to the parameters provided in the request. +// +// 1. Metrics and telemetry +// +// In the Reporting API, a metric represents a well-defined physical or +// logical quantity (e.g. voltage, active power, state of charge, temperature) +// measured at a specific point in time. +// +// Metrics originate from telemetry samples produced by microgrid electrical +// components or sensors. Each telemetry sample: +// • has a UTC timestamp, +// • represents exactly one metric value, +// • may be associated with a logical connection or channel, +// • may optionally include bounds or operational state. +// +// Aggregated metrics are derived exclusively from telemetry samples. +// No additional inference, estimation, or semantic transformation is +// performed by the Reporting API. +// +// 2. Aggregation formulas +// +// An aggregation formula defines how multiple telemetry samples for the +// same metric are combined into a single aggregated value. +// +// Aggregation formulas are optional and provided explicitly by the client. +// They are evaluated deterministically by the server and may: +// • reference electrical component identifiers, +// • reference sensor identifiers, +// • use basic mathematical operators, +// • use supported aggregation functions such as sum() or avg(). +// +// Aggregation formulas operate only on telemetry samples and do not introduce +// additional inference, estimation, or business logic. +// +// 3. Resampling +// +// Resampling is an optional operation that groups telemetry samples into +// fixed, contiguous time windows and produces at most one output sample per +// window. +// +// Resampling applies uniformly to historical replay and real-time streaming +// data. +// +// When resampling is enabled by default: +// • samples are grouped using left-closed, right-open time intervals, +// • all samples within a window are aggregated, +// • the resulting timestamp represents the start of the window. +// +// If no resampling resolution is specified, data is returned in its original +// resolution without modification. +// +// 4. Time windows and stream lifecycle +// +// All time filtering follows a left-closed, right-open interval convention: +// +// [start_time, end_time) +// +// A bounded time window results in a finite stream that closes automatically +// once all matching samples have been emitted. +// +// An unbounded time window (i.e. no end_time) results in a stream that may +// continue emitting real-time samples indefinitely. +// +// 5. Data inclusion (Filtering) +// +// Some data categories (e.g. bounds, operational states) are excluded by +// default. +// +// Clients may explicitly request inclusion of this data in order to: +// • reduce payload size when not needed, +// • minimize server-side computation, +// • keep high-frequency streams efficient and predictable. +// +// Unless explicitly requested, optional data MUST NOT be assumed to be +// present in responses. // service Reporting { // Streams metrics for a list of microgrid components. // // !!! note - // This RPC endpoint streams metrics data for components of one or more - // microgrids. Clients need to provide at least one microgrid ID and - // one component ID to get a result. + // This RPC endpoint streams metrics data for electrical components of one + // or more microgrids. Clients need to provide at least one microgrid + // ID and one electrical component ID to get a result. rpc ReceiveMicrogridComponentsDataStream (ReceiveMicrogridComponentsDataStreamRequest) returns (stream ReceiveMicrogridComponentsDataStreamResponse) {} // Streams aggregated metrics based on user-defined formulas for a list of - // microgrid components. + // microgrid electrical components. // // !!! note // This RPC endpoint retrieves aggregated historical metrics data based - // on user-defined formulas for microgrid components. At least one - // formula for one microgrid must be provided for a valid result. + // on user-defined formulas for microgrid electrical components. At least + // one formula for one microgrid must be provided for a valid result. rpc ReceiveAggregatedMicrogridComponentsDataStream (ReceiveAggregatedMicrogridComponentsDataStreamRequest) returns (stream ReceiveAggregatedMicrogridComponentsDataStreamResponse) {} @@ -73,10 +167,20 @@ service Reporting { returns (stream ReceiveAggregatedMicrogridSensorsDataStreamResponse) {} } -// Defines whether to include results in the response message. +// Defines whether a specific data category should be included in the response. +// +// The FilterOption enum is used in `IncludeOptions` to explicitly control +// whether optional data blocks (e.g. bounds, operational states) are emitted +// in stream responses. +// enum FilterOption { + // UNSPECIFIED: Default unspecified value — must not be used. FILTER_OPTION_UNSPECIFIED = 0; + + // EXCLUDED: Explicitly exclude the corresponding data from the response. FILTER_OPTION_EXCLUDE = 1; + + // INCLUDED: Explicitly include the corresponding data in the response. FILTER_OPTION_INCLUDE = 2; } @@ -321,7 +425,8 @@ message ReceiveMicrogridComponentsDataStreamRequest { // Each entry in this repeated field associates a microgrid ID with its // respective component IDs. At least one such association must be // provided for a valid request. - repeated frequenz.api.common.v1alpha8.microgrid.MicrogridElectricalComponentIDs microgrid_components = 1; + repeated frequenz.api.common.v1alpha8.microgrid. + MicrogridElectricalComponentIDs microgrid_components = 1; // List of metrics to receive data for, each possibly with connection filters. // @@ -550,7 +655,8 @@ message ReceiveMicrogridSensorsDataStreamRequest { // Each entry in this repeated field associates a microgrid ID with its // respective sensor IDs. At least one such association must be // provided for a valid request. - repeated frequenz.api.common.v1alpha8.microgrid.MicrogridSensorIDs microgrid_sensors = 1; + repeated frequenz.api.common.v1alpha8.microgrid.MicrogridSensorIDs + microgrid_sensors = 1; // List of metrics to receive data for, each possibly with connection filters. // @@ -593,9 +699,9 @@ message ReceiveMicrogridSensorsDataStreamResponse { // Message defining the request format for streaming aggregated historical // metrics. // -// This request allows to specify custom aggregation formulas, along with general -// filtering. At least one aggregation formula config must be provided. The -// aggregation follows the passive sign convention. +// This request allows to specify custom aggregation formulas, along with +// general filtering. At least one aggregation formula config must be +// provided. The aggregation follows the passive sign convention. // message ReceiveAggregatedMicrogridSensorsDataStreamRequest { // General filter criteria for querying microgrid sensors data. @@ -632,6 +738,7 @@ message ReceiveAggregatedMicrogridSensorsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; - // Aggregated sample value and corresponding UTC timestamp when it was sampled. + // Aggregated sample value and corresponding UTC timestamp when it was + // sampled. SimpleAggregatedMetricValue sample = 2; } From 0ca93cd8555786826f5fe0b711b879d4e323c31a Mon Sep 17 00:00:00 2001 From: tomni Date: Mon, 15 Dec 2025 22:36:23 +0100 Subject: [PATCH 03/17] * Refined terminology around electrical components Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 1a32be9..70a4ee3 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -212,7 +212,8 @@ message TimeFilter { frequenz.api.common.v1alpha8.types.Interval interval = 1; } -// Resampling options for aggregated microgrid components data. +// Resampling options for aggregated microgrid electrical components or sensor +// data. // // If data is resampled, all samples that fall in a left-closed time interval // determined by the resolution will be aggregated. At the moment only mean @@ -230,12 +231,12 @@ message ResamplingOptions { // a specific microgrid. // // The AggregationConfig allows clients to specify how metrics should be -// aggregated across microgrid components. It serves as the configuration -// guideline for any aggregation operation. +// aggregated across microgrid electrical components. It serves as the +// configuration guideline for any aggregation operation. // // !!! example -// To calculate the total voltage across three components in series with -// IDs 1, 2, and 3, the configuration could look like: +// To calculate the total voltage across three electrical components in +// series with IDs 1, 2, and 3, the configuration could look like: // // ```json // { @@ -253,8 +254,8 @@ message AggregationConfig { // // !!! caution "Supported metrics" // Ensure the chosen metric is supported by all relevant microgrid - // components. Failure to meet these conditions might results in an - // aggregation error. + // electrical components. Failure to meet these conditions might results + // in an aggregation error. frequenz.api.common.v1alpha8.metrics.Metric metric = 2; // The formula used for aggregating the component metric for this microgrid. @@ -266,12 +267,13 @@ message AggregationConfig { // Example: `sum(#1,#2)`, `avg(#3,#4)` // // 2. Dedicated formulas: These support basic math operators while - // concatenating microgrid component IDs. + // concatenating microgrid electrical component IDs. // Example: `#1 + #2 - #3`, `(#3 * #2) /# 1` // // Additionally, metric connection identifiers can be used in the - // formula, for components that e.g. provide the same metric from - // multiple connections/sensors. + // formula, for electrical components that e.g. provide the same metric + // from multiple connections/sensors. + // // Example: // `sum(#1[connection0], #2, #3)`, `#1[connection0] + #2[connection1]` string aggregation_formula = 3; @@ -374,15 +376,16 @@ message MetricConnections { } // Request message for receiving stream of metrics, such as electrical -// measurements, and other information for individual microgrid components. +// measurements, and other information for individual microgrid electrical +// components. // // !!! note // In addition to the raw metrics, the API can also return additional -// information like errors or operational states of the components during -// the specified time period. +// information like errors or operational states of the +// electrical components during the specified time period. // message ReceiveMicrogridComponentsDataStreamRequest { - // Include options for filtering microgrid components data. + // Include options for filtering microgrid electrical components data. // // !!! note // Specifies which additional fields should be included in the response. @@ -397,11 +400,11 @@ message ReceiveMicrogridComponentsDataStreamRequest { optional FilterOption states = 2; } - // General filter criteria for querying microgrid components data. + // General filter criteria for querying microgrid electrical components data. // // !!! note // The filter criteria defined here are applied universally across all - // specified microgrids and their respective components. + // specified microgrids and their respective electrical components. message StreamFilter { // Optional resampling options like resolution for the data, represented // in seconds. @@ -459,7 +462,7 @@ message ReceiveMicrogridComponentsDataStreamRequest { repeated MetricConnections metrics = 2; // General filter that applies to the data retrieval for all specified - // microgrids and components. + // microgrids and electrical components. // // !!! note // The filter can specify a list of metrics to be return but also @@ -467,14 +470,15 @@ message ReceiveMicrogridComponentsDataStreamRequest { StreamFilter filter = 3; } -// Response containing a single data sample for one microgrid's components. +// Response containing a single data sample for one microgrid's +// electrical components. // // !!! note -// The microgrid's components are provided as single data samples that -// encapsulate metrics, bounds, errors, and operational states along with -// their associated timestamps. Each response message covers a single -// microgrid. If multiple microgrids are provided in the request, expect -// sequential messages in the stream. +// The microgrid's electrical components are provided as single data +// samples that encapsulate metrics, bounds, errors, and operational +// states along with their associated timestamps. Each response message +// covers a single microgrid. If multiple microgrids are provided in the +// request, expect sequential messages in the stream. // // !!! example // Example output structure: @@ -536,11 +540,11 @@ message ReceiveMicrogridComponentsDataStreamRequest { // ``` // message ReceiveMicrogridComponentsDataStreamResponse { - // Microgrid ID for which the components and samples are reported. + // Microgrid ID for which the electrical components and samples are reported. uint64 microgrid_id = 1; - // List of components within this microgrid, each with its associated data - // samples. + // List of electrical components within this microgrid, each with its + // associated data samples. repeated frequenz.api.common.v1alpha8.microgrid.electrical_components. ElectricalComponentTelemetry components = 2; } @@ -553,7 +557,7 @@ message ReceiveMicrogridComponentsDataStreamResponse { // provided. The aggregation follows the passive sign convention. // message ReceiveAggregatedMicrogridComponentsDataStreamRequest { - // General filter criteria for querying microgrid components data. + // General filter criteria for querying microgrid electrical components data. message AggregationStreamFilter { // Optional resampling options like resolution for the data, represented // in seconds. From 6e72a5e881307e754831c4e22edea0153b4ea57a Mon Sep 17 00:00:00 2001 From: tomni Date: Mon, 15 Dec 2025 22:41:25 +0100 Subject: [PATCH 04/17] * Added at Authentication note to service header. Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 70a4ee3..4bc98ed 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -123,6 +123,13 @@ import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; // Unless explicitly requested, optional data MUST NOT be assumed to be // present in responses. // +// !!! important "Authentication" +// All requests to the Reporting service must be signed. The key identifier +// and signature must be included in the request metadata (gRPC metadata +// / HTTP headers). The signature must be computed using the HMAC-SHA256 +// algorithm and secret key. All requests to this service must be made +// over TLS (HTTPS). +// service Reporting { // Streams metrics for a list of microgrid components. // From 8a794fc33cfa649831f47fe38799e466365e76e3 Mon Sep 17 00:00:00 2001 From: tomni Date: Mon, 15 Dec 2025 22:54:26 +0100 Subject: [PATCH 05/17] * Renamed ReportingService * Renamed ReceiveMicrogridElectricalComponentsDataStream RPC * Renamed ReceiveAggregatedMicrogridElectricalComponentsDataStream RPC Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 4bc98ed..0a51237 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -130,16 +130,16 @@ import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; // algorithm and secret key. All requests to this service must be made // over TLS (HTTPS). // -service Reporting { +service ReportingService { // Streams metrics for a list of microgrid components. // // !!! note // This RPC endpoint streams metrics data for electrical components of one // or more microgrids. Clients need to provide at least one microgrid // ID and one electrical component ID to get a result. - rpc ReceiveMicrogridComponentsDataStream - (ReceiveMicrogridComponentsDataStreamRequest) - returns (stream ReceiveMicrogridComponentsDataStreamResponse) {} + rpc ReceiveMicrogridElectricalComponentsDataStream + (ReceiveMicrogridElectricalComponentsDataStreamRequest) + returns (stream ReceiveMicrogridElectricalComponentsDataStreamResponse) {} // Streams aggregated metrics based on user-defined formulas for a list of // microgrid electrical components. @@ -148,9 +148,9 @@ service Reporting { // This RPC endpoint retrieves aggregated historical metrics data based // on user-defined formulas for microgrid electrical components. At least // one formula for one microgrid must be provided for a valid result. - rpc ReceiveAggregatedMicrogridComponentsDataStream - (ReceiveAggregatedMicrogridComponentsDataStreamRequest) - returns (stream ReceiveAggregatedMicrogridComponentsDataStreamResponse) {} + rpc ReceiveAggregatedMicrogridElectricalComponentsDataStream + (ReceiveAggregatedMicrogridElectricalComponentsDataStreamRequest) + returns (stream ReceiveAggregatedMicrogridElectricalComponentsDataStreamResponse) {} // Streams metrics for a list of microgrid sensors. // @@ -391,7 +391,7 @@ message MetricConnections { // information like errors or operational states of the // electrical components during the specified time period. // -message ReceiveMicrogridComponentsDataStreamRequest { +message ReceiveMicrogridElectricalComponentsDataStreamRequest { // Include options for filtering microgrid electrical components data. // // !!! note @@ -546,7 +546,7 @@ message ReceiveMicrogridComponentsDataStreamRequest { // } // ``` // -message ReceiveMicrogridComponentsDataStreamResponse { +message ReceiveMicrogridElectricalComponentsDataStreamResponse { // Microgrid ID for which the electrical components and samples are reported. uint64 microgrid_id = 1; @@ -563,7 +563,7 @@ message ReceiveMicrogridComponentsDataStreamResponse { // general filtering. At least one aggregation formula config must be // provided. The aggregation follows the passive sign convention. // -message ReceiveAggregatedMicrogridComponentsDataStreamRequest { +message ReceiveAggregatedMicrogridElectricalComponentsDataStreamRequest { // General filter criteria for querying microgrid electrical components data. message AggregationStreamFilter { // Optional resampling options like resolution for the data, represented @@ -610,7 +610,7 @@ message ReceiveAggregatedMicrogridComponentsDataStreamRequest { // } // ``` // -message ReceiveAggregatedMicrogridComponentsDataStreamResponse { +message ReceiveAggregatedMicrogridElectricalComponentsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; From 6bcc95fe5188ae6959c7d9117960c4a1da13969e Mon Sep 17 00:00:00 2001 From: tomni Date: Wed, 17 Dec 2025 15:23:37 +0100 Subject: [PATCH 06/17] * Increase version to v1alpha11 * Introduced DownsamplingMethod to ResamplingOptions * Enhanced ResamplingOptions documentation Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 91 +++++++++++++++++-- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 0a51237..64c9018 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -10,7 +10,7 @@ syntax = "proto3"; -package frequenz.api.reporting.v1alpha10; +package frequenz.api.reporting.v1alpha11; import "google/protobuf/timestamp.proto"; @@ -191,6 +191,16 @@ enum FilterOption { FILTER_OPTION_INCLUDE = 2; } +// Defines how multiple native samples are combined when downsampling +// to a coarser resolution. +enum DownsamplingMethod { + // UNSPECIFIED: Defaults to MEAN. + DOWNSAMPLING_METHOD_UNSPECIFIED = 0; + + // MEAN: Arithmetic mean of all samples within the interval. + DOWNSAMPLING_METHOD_MEAN = 1; +} + // Time-filter defining the historical window and real-time behaviour of the // stream. // @@ -219,19 +229,75 @@ message TimeFilter { frequenz.api.common.v1alpha8.types.Interval interval = 1; } -// Resampling options for aggregated microgrid electrical components or sensor -// data. +// Resampling options for microgrid electrical component or sensor telemetry. +// +// Resampling allows clients to request a regular, uniform time grid onto +// which high-resolution telemetry samples are aggregated. +// +// The Reporting service operates on telemetry data that may be sampled at +// sub-second resolution and whose sampling characteristics can differ +// between microgrids, components, and metrics. Resampling therefore +// materializes a fixed time grid and aggregates all telemetry samples whose +// timestamps fall into each grid interval. +// +// The output time series contains at most one sample per interval. The +// timestamp of each output sample equals the start of the corresponding +// interval. +// +// !!! note "Sparse telemetry and fine-grained resolutions" +// If the requested resampling resolution is finer than the effective +// sampling density of the telemetry, some resampling intervals may +// contain no telemetry samples. +// +// In such cases, the corresponding output sample will have no value +// set. The Reporting API does not interpolate, extrapolate, or carry +// values forward across intervals. +// +// !!! note "Resolution constraints" +// The service enforces an upper bound on the resampling resolution. // -// If data is resampled, all samples that fall in a left-closed time interval -// determined by the resolution will be aggregated. At the moment only mean -// aggregation is supported. The timestamp for each aggregated sample -// represents the beginning of its corresponding time interval, marking the -// earliest point from which data was aggregated. +// Resolutions larger than one calendar month are not supported, as +// they exceed the intended scope of telemetry resampling. +// +// Typical and recommended resolutions include 5 minutes, 15 minutes, +// 1 hour, and 1 day. Monthly resolution may be used for long-horizon +// analysis and backtesting. +// +// !!! note "Real-time streams" +// For open-ended streams, resampling windows advance according to +// wall-clock time. Window emission is time-driven, not event-driven. +// A window MAY be emitted even if no new telemetry samples arrive +// during the interval, depending on metric availability. +// +// !!! example "Example: Downsampling from 1-second to 15-minute intervals" +// The stored time series has a native resolution of Δt = 1 second. +// Resampling is requested with a resolution of ΔT = 15 minutes. In +// this case all native samples whose timestamps fall within an interval +// [t, t + Δt) contribute to the aggregated value for that interval. The +// timestamp of the aggregated sample is exactly t, the start of the +// interval. +// +// For each interval k: +// Ik = [T0 + k·ΔT, T0 + (k+1)·ΔT) +// +// The aggregated value A_k is by default the arithmetic mean of all +// samples whose timestamps ts satisfy: ts ∈ Ik +// +// The resampled series consists of points: +// (t = T0 + k·ΔT, value = A_k) // message ResamplingOptions { - // Optional resampling resolution for the data, represented in seconds. - // If omitted, data will be returned in its original resolution. + // Optional resampling resolution for the output time grid, expressed in + // seconds. The resolution MUST NOT exceed the maximum supported resampling + // interval. + // + // If omitted, telemetry is returned in its original, event-driven form + // without resampling. optional uint32 resolution = 1; + + // Optional aggregation method applied when downsampling. + // Defaults to DOWNSAMPLING_METHOD_MEAN when omitted. + DownsamplingMethod downsampling_method = 2; } // Message defining the aggregation configuration for a custom formula within @@ -610,6 +676,11 @@ message ReceiveAggregatedMicrogridElectricalComponentsDataStreamRequest { // } // ``` // +// !!! todo "we need to say when the sample value is unset in case of ..." +// !!! todo ".. resampling without samples in e.g. realtime stream" +// !!! todo "in this case resampled samples might be updated" +// !!! todo "in case of historic data that might also happen" +// message ReceiveAggregatedMicrogridElectricalComponentsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; From e00b16ade44c9c6099cf28188416c31f8eec5958 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 09:33:43 +0100 Subject: [PATCH 07/17] * Refined SimpleAggregatedMetricValue documentation Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 99 +++++++++++++------ 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 64c9018..205d332 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -232,13 +232,12 @@ message TimeFilter { // Resampling options for microgrid electrical component or sensor telemetry. // // Resampling allows clients to request a regular, uniform time grid onto -// which high-resolution telemetry samples are aggregated. -// -// The Reporting service operates on telemetry data that may be sampled at -// sub-second resolution and whose sampling characteristics can differ -// between microgrids, components, and metrics. Resampling therefore -// materializes a fixed time grid and aggregates all telemetry samples whose -// timestamps fall into each grid interval. +// which high-resolution telemetry samples are aggregated. The service +// operates on telemetry data that may be sampled at sub-second resolution +// and whose sampling characteristics can differ between microgrids, +// electrical components, and sensors. Resampling therefore materializes a +// fixed time grid and aggregates all telemetry samples whose timestamps fall into each +// grid interval. // // The output time series contains at most one sample per interval. The // timestamp of each output sample equals the start of the corresponding @@ -250,7 +249,7 @@ message TimeFilter { // contain no telemetry samples. // // In such cases, the corresponding output sample will have no value -// set. The Reporting API does not interpolate, extrapolate, or carry +// set. The Reporting service does not interpolate, extrapolate, or carry // values forward across intervals. // // !!! note "Resolution constraints" @@ -263,12 +262,6 @@ message TimeFilter { // 1 hour, and 1 day. Monthly resolution may be used for long-horizon // analysis and backtesting. // -// !!! note "Real-time streams" -// For open-ended streams, resampling windows advance according to -// wall-clock time. Window emission is time-driven, not event-driven. -// A window MAY be emitted even if no new telemetry samples arrive -// during the interval, depending on metric availability. -// // !!! example "Example: Downsampling from 1-second to 15-minute intervals" // The stored time series has a native resolution of Δt = 1 second. // Resampling is requested with a resolution of ΔT = 15 minutes. In @@ -286,10 +279,22 @@ message TimeFilter { // The resampled series consists of points: // (t = T0 + k·ΔT, value = A_k) // +// !!! note "Real-time streams" +// For open-ended streams, resampling windows advance according to +// wall-clock time. Window emission is time-driven, not event-driven. +// As telemetry samples may arrive late (e.g. due to +// buffering, transport delays, or upstream batching) a window MAY be +// emitted even if the telemetry samples have not yet arrived during the +// interval. In consequence a resampling interval that has already been +// emitted MAY be re-emitted later with an updated value when additional +// samples for that interval arrive. +// +// Clients must be able to handle interval updates (upserts) and must not +// assume that emitted intervals are final. +// message ResamplingOptions { - // Optional resampling resolution for the output time grid, expressed in - // seconds. The resolution MUST NOT exceed the maximum supported resampling - // interval. + // Optional resampling resolution, expressed in seconds. The resolution + // MUST NOT exceed the maximum supported resampling interval. // // If omitted, telemetry is returned in its original, event-driven form // without resampling. @@ -352,26 +357,56 @@ message AggregationConfig { string aggregation_formula = 3; } -// Defines a single aggregated metric sample, which represents a consolidated -// metric value over a collection of microgrid components within a specific -// timeframe. +// Defines a single aggregated metric value. +// +// This message represents the aggregated - across multiple electrical +// components or sensors- result for one metric and one aggregation +// configuration. It is particularly useful in scenarios where an overall +// metric needs to be calculated for a set of components. For instance, it +// can be used to represent the average voltage across multiple sources +// within a microgrid or to calculate the average state of charge of several +// batteries. // -// This message serves to encapsulate aggregate metrics derived from multiple -// component measurements. It is particularly useful in scenarios where an -// overall metric needs to be calculated for a set of components. For -// instance, you could use it to represent the average voltage across -// multiple sources within a microgrid or to calculate the average state of -// charge of several batteries. +// Depending on whether resampling is enabled in the request, it can +// represent either: +// • a point-in-time aggregated value (no resampling requested), or +// • an aggregated value for a resampling interval (resampling requested). // message SimpleAggregatedMetricValue { - // The UTC sample timestamp for the aggregated metrics. + // The UTC timestamp associated with this aggregated value. // - // !!! info - // This is the original timestamp of the samples that were aggregated. + // Semantics depend on whether resampling is enabled: + // + // • Without resampling: + // `sample_time` represents the origin time of the underlying + // telemetry measurement(s), i.e. the time at which the metric + // value was observed at the component or sensor. This is the + // original timestamp of the samples that were aggregated. + // + // • With resampling: + // `sample_time` represents the start of the resampling interval + // [t, t + ΔT) to which contributing telemetry samples are assigned + // based on their origin timestamps. + // + // In all cases, `sample_time` refers to measurement time, not processing + // or emission time. google.protobuf.Timestamp sample_time = 1; - // The aggregated value of the metric. - // float value = 2; + // The aggregated metric value. + // + // !!! note "Unset values (resampling)" + // When resampling is enabled, the sample value MAY be unset if no + // telemetry measurements were observed within the corresponding + // resampling interval. + // + // !!! important "Late measurements and updates" + // Telemetry measurements are assigned based on their origin timestamps, + // not their arrival time. As a result, when resampling is enabled, + // previously emitted intervals MAY be re-emitted later with updated + // values if additional measurements arrive for the same interval. + // + // Clients MUST be able to handle such updates and MUST NOT assume that + // emitted values are final. frequenz.api.common.v1alpha8.metrics.SimpleMetricValue sample = 2; } @@ -481,6 +516,7 @@ message ReceiveMicrogridElectricalComponentsDataStreamRequest { message StreamFilter { // Optional resampling options like resolution for the data, represented // in seconds. + // // If omitted, data will be returned in its original representation. ResamplingOptions resampling_options = 1; @@ -618,6 +654,7 @@ message ReceiveMicrogridElectricalComponentsDataStreamResponse { // List of electrical components within this microgrid, each with its // associated data samples. + // !!! todo "This can be empty. We might need to adjust the common definition" repeated frequenz.api.common.v1alpha8.microgrid.electrical_components. ElectricalComponentTelemetry components = 2; } From a4bfcd9afb0f7e69d86d673818f9cce143db4d9b Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 09:40:58 +0100 Subject: [PATCH 08/17] * Extended service header around streamed resampling requests Signed-off-by: tomni --- .../frequenz/api/reporting/v1alpha10/reporting.proto | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 205d332..ca4fb32 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -90,10 +90,15 @@ import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; // Resampling applies uniformly to historical replay and real-time streaming // data. // -// When resampling is enabled by default: +// When resampling is enabled: // • samples are grouped using left-closed, right-open time intervals, // • all samples within a window are aggregated, // • the resulting timestamp represents the start of the window. +// • every stream must be treated as an upsert stream keyed by +// (aggregation_config, sample.sample_time): +// - intervals may be emitted with an unset sample value, and +// - intervals may be re-emitted later with updated values due to +// late-arriving telemetry. // // If no resampling resolution is specified, data is returned in its original // resolution without modification. @@ -713,11 +718,6 @@ message ReceiveAggregatedMicrogridElectricalComponentsDataStreamRequest { // } // ``` // -// !!! todo "we need to say when the sample value is unset in case of ..." -// !!! todo ".. resampling without samples in e.g. realtime stream" -// !!! todo "in this case resampled samples might be updated" -// !!! todo "in case of historic data that might also happen" -// message ReceiveAggregatedMicrogridElectricalComponentsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; From 6f8e6a8880c95f1f10cf7839cbf9ef0fd456ed43 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 10:03:09 +0100 Subject: [PATCH 09/17] * Updated header documentation. Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index ca4fb32..c529af7 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -93,7 +93,8 @@ import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; // When resampling is enabled: // • samples are grouped using left-closed, right-open time intervals, // • all samples within a window are aggregated, -// • the resulting timestamp represents the start of the window. +// • the resulting timestamp represents the start of the resampling +// interval [t, t + ΔT) // • every stream must be treated as an upsert stream keyed by // (aggregation_config, sample.sample_time): // - intervals may be emitted with an unset sample value, and @@ -584,15 +585,13 @@ message ReceiveMicrogridElectricalComponentsDataStreamRequest { StreamFilter filter = 3; } -// Response containing a single data sample for one microgrid's -// electrical components. +// Response containing telemetry data for one microgrid's electrical components. // -// !!! note -// The microgrid's electrical components are provided as single data -// samples that encapsulate metrics, bounds, errors, and operational -// states along with their associated timestamps. Each response message -// covers a single microgrid. If multiple microgrids are provided in the -// request, expect sequential messages in the stream. +// The microgrid's electrical components are provided as single data samples +// that encapsulate metrics, bounds, errors, and operational states along +// with their associated timestamps. Each response message covers a single +// microgrid. If multiple microgrids are provided in the request, expect +// sequential messages in the stream. // // !!! example // Example output structure: @@ -659,7 +658,6 @@ message ReceiveMicrogridElectricalComponentsDataStreamResponse { // List of electrical components within this microgrid, each with its // associated data samples. - // !!! todo "This can be empty. We might need to adjust the common definition" repeated frequenz.api.common.v1alpha8.microgrid.electrical_components. ElectricalComponentTelemetry components = 2; } From 910fe3ddfcf7492a9b52cee215700898c35d9b0c Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 10:04:22 +0100 Subject: [PATCH 10/17] * Reverted to v1alpha10. Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index c529af7..9858564 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -10,7 +10,7 @@ syntax = "proto3"; -package frequenz.api.reporting.v1alpha11; +package frequenz.api.reporting.v1alpha10; import "google/protobuf/timestamp.proto"; From 3c6f1e54ece3ad5f2e540f6677d2c555720f90a1 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 10:22:46 +0100 Subject: [PATCH 11/17] * Added example to ReceiveAggregatedMicrogridSensorsDataStreamResponse and ReceiveMicrogridSensorsDataStreamResponse Signed-off-by: tomni --- .../api/reporting/v1alpha10/reporting.proto | 183 +++++++++++++----- 1 file changed, 133 insertions(+), 50 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 9858564..5240451 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -587,65 +587,54 @@ message ReceiveMicrogridElectricalComponentsDataStreamRequest { // Response containing telemetry data for one microgrid's electrical components. // -// The microgrid's electrical components are provided as single data samples -// that encapsulate metrics, bounds, errors, and operational states along -// with their associated timestamps. Each response message covers a single -// microgrid. If multiple microgrids are provided in the request, expect -// sequential messages in the stream. -// -// !!! example -// Example output structure: +// The microgrid's electrical components are provided as telemetry samples that +// encapsulate metrics, bounds, and operational states along with their +// associated measurement timestamps. +// +// Each response message covers a single microgrid. If multiple microgrids are +// provided in the request, expect sequential messages in the stream. +// +// !!! example "Example output structure (resampling enabled)" +// This example shows telemetry for a single electrical component when +// resampling is enabled. All metric samples share the same `sample_time`, +// which represents the start of the resampling interval [t, t + ΔT). +// Metric values may be present if telemetry measurements contributed to +// the interval, or unset if no measurements were observed at the time of +// emission. State data is not resampled and always uses the origin time +// at which the state was observed. // ``` // { // microgrid_id: 1, // components: [ // { -// component_id: 13, +// electrical_component_id: 13, // metric_samples: [ -// /* all metrics belong to the same timestamp */ -// /* sample is type MetricSampleVariant */ // { +// // Interval start time (resampling enabled) // sample_time: "2023-10-01T00:00:00Z", -// metric: "DC_VOLTAGE_V", -// sample: {...}, bounds: {...} +// metric: "METRIC_DC_VOLTAGE", +// value: { +// // value present because telemetry contributed +// simple_metric: { value: 720.5 } +// }, +// bounds: { ... } // }, // { +// // Same interval, but no telemetry contributed for this metric // sample_time: "2023-10-01T00:00:00Z", -// metric: "DC_CURRENT_A", -// sample: {...}, -// bounds: {...} +// metric: "METRIC_DC_CURRENT", +// // value intentionally unset +// bounds: { ... } // } // ], -// state: { -// sample_time: "2023-10-01T00:00:13.12Z", -// states: ["COMPONENT_STATE_CHARGING", "CABLE_CONNECTED"], -// warnings: [] -// errors: [], -// ] -// }, -// { -// component_id: 59, -// metric_samples: [ -// /* all metrics belong to the same timestamp */ -// /* sample is type MetricSampleVariant */ -// { -// sample_time: "2023-10-01T00:00:00Z", -// metric: "DC_VOLTAGE_V", -// sample: {...}, -// bounds: {...} -// }, +// state_snapshots: [ // { -// sample_time: "2023-10-01T00:00:00Z", -// metric: "DC_CURRENT_A", -// sample: {...}, -// bounds: {...} +// // State snapshots are not resampled and use origin time +// origin_time: "2023-10-01T00:00:13.12Z", +// states: ["ELECTRICAL_COMPONENT_STATE_CODE_CHARGING"], +// warnings: [], +// errors: [] // } -// ], -// state: { -// sample_time: "2023-10-01T00:00:13.12Z", -// states: ["COMPONENT_STATE_ERROR"], -// warnings: [] -// errors: ["COMPONENT_ERROR_CODE_BATTERY_RELAY_ERROR"], // ] // } // ] @@ -658,6 +647,12 @@ message ReceiveMicrogridElectricalComponentsDataStreamResponse { // List of electrical components within this microgrid, each with its // associated data samples. + // + // !!! important "Empty values and updates" + // When resampling is enabled, metric sample values MAY be unset for a + // given resampling interval and MAY be updated later if additional + // telemetry measurements arrive. Clients MUST be able to handle empty + // values and updates. repeated frequenz.api.common.v1alpha8.microgrid.electrical_components. ElectricalComponentTelemetry components = 2; } @@ -722,6 +717,12 @@ message ReceiveAggregatedMicrogridElectricalComponentsDataStreamResponse { // Aggregated sample value and corresponding UTC timestamp when it was // sampled. + // + // !!! important "Empty values and updates" + // When resampling is enabled, metric sample values MAY be unset for a + // given resampling interval and MAY be updated later if additional + // telemetry measurements arrive. Clients MUST be able to handle empty + // values and updates. SimpleAggregatedMetricValue sample = 2; } @@ -765,6 +766,7 @@ message ReceiveMicrogridSensorsDataStreamRequest { // request was received. TimeFilter time_filter = 3; } + // Encapsulates the microgrid ID and the sensor IDs within that microgrid // for which the historical data should be retrieved. // @@ -796,12 +798,53 @@ message ReceiveMicrogridSensorsDataStreamRequest { // Response containing a single data sample for one microgrid's sensors. // -// !!! note -// The microgrid's sensors are provided as single data samples that -// encapsulate metrics, bounds, errors, and operational states along with -// their associated timestamps. Each response message covers a single -// microgrid. If multiple microgrids are provided in the request, expect -// sequential messages in the stream. +// The microgrid's sensors are provided as telemetry samples that encapsulate +// metric measurements and sensor state snapshots along with their associated +// timestamps. +// +// Each response message covers a single microgrid. If multiple microgrids are +// provided in the request, expect sequential messages in the stream. +// +// !!! example "Example output structure (resampling enabled)" +// This example shows telemetry for a single sensor when resampling is +// enabled. Both metric samples share the same `sample_time`, which +// represents the start of the resampling interval. One metric has a value +// because telemetry contributed to the interval, while the other metric +// has no value set because no measurements were observed for that metric +// during the interval. The sensor state snapshot uses its own origin time. +// +// ``` +// { +// "microgrid_id": 1, +// "sensors": [ +// { +// "sensor_id": 7, +// "metric_samples": [ +// { +// "sample_time": "2023-10-01T00:00:00Z", +// "metric": "METRIC_TEMPERATURE_C", +// "value": { +// "simple_metric": { "value": 21.4 } +// } +// }, +// { +// "sample_time": "2023-10-01T00:00:00Z", +// "metric": "METRIC_HUMIDITY_PERCENT" +// // value intentionally unset: no telemetry in this interval +// } +// ], +// "state_snapshots": [ +// { +// "origin_time": "2023-10-01T00:00:12.45Z", +// "states": ["SENSOR_STATE_OK"], +// "warnings": [], +// "errors": [] +// } +// ] +// } +// ] +// } +// ``` // message ReceiveMicrogridSensorsDataStreamResponse { // Microgrid ID for which the sensors and samples are reported. @@ -809,6 +852,12 @@ message ReceiveMicrogridSensorsDataStreamResponse { // List of sensors within this microgrid, each with its associated data // samples. + // + // !!! important "Empty values and updates" + // When resampling is enabled, metric sample values MAY be unset for a + // given resampling interval and MAY be updated later if additional + // telemetry measurements arrive. Clients MUST be able to handle empty + // values and updates. repeated frequenz.api.common.v1alpha8.microgrid.sensors.SensorTelemetry sensors = 2; } @@ -851,11 +900,45 @@ message ReceiveAggregatedMicrogridSensorsDataStreamRequest { // formulars provided in the request, expect sequential // messages in the stream. // +// !!! example +// Example output structure (resampling enabled): +// +// This example shows an aggregated sensor metric for a single resampling +// interval. The `sample_time` represents the start of the resampling +// interval [t, t + ΔT). The aggregated value is present because telemetry +// measurements from one or more sensors contributed to the interval. +// +// If no telemetry measurements had contributed, the `sample` value would +// be unset. The same interval may be re-emitted later with an updated +// value if additional telemetry measurements arrive. +// +// ``` +// { +// "aggregation_config": { +// "microgrid_id": 1, +// "metric": "METRIC_TEMPERATURE_C", +// "aggregation_formula": "avg(#7,#9,#12)" +// }, +// "sample": { +// "sample_time": "2023-10-01T00:00:00Z", +// "sample": { +// "simple_metric": { "value": 21.8 } +// } +// } +// } +// ``` +// message ReceiveAggregatedMicrogridSensorsDataStreamResponse { // The metric and formula that has been used to aggregate the sample. AggregationConfig aggregation_config = 1; // Aggregated sample value and corresponding UTC timestamp when it was // sampled. + // + // !!! important "Empty values and updates" + // When resampling is enabled, metric sample values MAY be unset for a + // given resampling interval and MAY be updated later if additional + // telemetry measurements arrive. Clients MUST be able to handle empty + // values and updates. SimpleAggregatedMetricValue sample = 2; } From 30fa97b8d12f450ca7719549dc7a37ec878bc246 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 10:36:32 +0100 Subject: [PATCH 12/17] * Added two clarifications to FilterOption and ResamplingOptions Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 5240451..e8c4fb6 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -186,6 +186,9 @@ service ReportingService { // whether optional data blocks (e.g. bounds, operational states) are emitted // in stream responses. // +// If a FilterOption is omitted, the default behavior is equivalent to +// FILTER_OPTION_EXCLUDE. +// enum FilterOption { // UNSPECIFIED: Default unspecified value — must not be used. FILTER_OPTION_UNSPECIFIED = 0; @@ -269,8 +272,8 @@ message TimeFilter { // analysis and backtesting. // // !!! example "Example: Downsampling from 1-second to 15-minute intervals" -// The stored time series has a native resolution of Δt = 1 second. -// Resampling is requested with a resolution of ΔT = 15 minutes. In +// The stored time series has a effective sampling resolution of Δt = 1 +// second. Resampling is requested with a resolution of ΔT = 15 minutes. In // this case all native samples whose timestamps fall within an interval // [t, t + Δt) contribute to the aggregated value for that interval. The // timestamp of the aggregated sample is exactly t, the start of the @@ -318,6 +321,9 @@ message ResamplingOptions { // aggregated across microgrid electrical components. It serves as the // configuration guideline for any aggregation operation. // +// Aggregation formulas operate on exactly one metric per configuration. +// Cross-metric aggregation is not supported. +// // !!! example // To calculate the total voltage across three electrical components in // series with IDs 1, 2, and 3, the configuration could look like: From 1087bb0526ad50aef8ef725db9b41f667cf0b41b Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 17:44:07 +0100 Subject: [PATCH 13/17] docs: add release note for reporting API documentation updates Signed-off-by: tomni --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 14cd83b..e87e2d1 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,6 +3,7 @@ ## Summary - The behavior of the TimeFilter has changed, and its documentation has been updated accordingly. +- Clarified resampling and streaming semantics in the Reporting API, including interval-based timestamps, empty values, and update (upsert) behavior for resampled streams. ## Upgrading From 2f2611db6a49b0750caa47903af599e49e4c0757 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 17:51:33 +0100 Subject: [PATCH 14/17] style(proto): sort imports in reporting.proto Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index e8c4fb6..7ff3aa7 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -12,13 +12,12 @@ syntax = "proto3"; package frequenz.api.reporting.v1alpha10; -import "google/protobuf/timestamp.proto"; - import "frequenz/api/common/v1alpha8/types/interval.proto"; import "frequenz/api/common/v1alpha8/metrics/metrics.proto"; import "frequenz/api/common/v1alpha8/microgrid/electrical_components/electrical_components.proto"; import "frequenz/api/common/v1alpha8/microgrid/microgrid.proto"; import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; +import "google/protobuf/timestamp.proto"; // The Reporting service provides access to historical and real-time telemetry // data from microgrids. From 6edbc73d2cb70970a276399b4d908413278563e4 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 18:08:51 +0100 Subject: [PATCH 15/17] style(proto): sort imports in reporting.proto Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 7ff3aa7..b28b404 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -12,12 +12,12 @@ syntax = "proto3"; package frequenz.api.reporting.v1alpha10; -import "frequenz/api/common/v1alpha8/types/interval.proto"; +import "google/protobuf/timestamp.proto"; import "frequenz/api/common/v1alpha8/metrics/metrics.proto"; import "frequenz/api/common/v1alpha8/microgrid/electrical_components/electrical_components.proto"; import "frequenz/api/common/v1alpha8/microgrid/microgrid.proto"; import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; -import "google/protobuf/timestamp.proto"; +import "frequenz/api/common/v1alpha8/types/interval.proto"; // The Reporting service provides access to historical and real-time telemetry // data from microgrids. From 166af942daef5a376142a23c565b7fbe0dcccd75 Mon Sep 17 00:00:00 2001 From: tomni Date: Thu, 18 Dec 2025 18:14:29 +0100 Subject: [PATCH 16/17] style(proto): sort imports in reporting.proto Signed-off-by: tomni --- proto/frequenz/api/reporting/v1alpha10/reporting.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index b28b404..5a784e9 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -12,12 +12,12 @@ syntax = "proto3"; package frequenz.api.reporting.v1alpha10; -import "google/protobuf/timestamp.proto"; import "frequenz/api/common/v1alpha8/metrics/metrics.proto"; import "frequenz/api/common/v1alpha8/microgrid/electrical_components/electrical_components.proto"; import "frequenz/api/common/v1alpha8/microgrid/microgrid.proto"; import "frequenz/api/common/v1alpha8/microgrid/sensors/sensors.proto"; import "frequenz/api/common/v1alpha8/types/interval.proto"; +import "google/protobuf/timestamp.proto"; // The Reporting service provides access to historical and real-time telemetry // data from microgrids. From 1c83e50f965d4d0c7ceec62e9ec70011044d01da Mon Sep 17 00:00:00 2001 From: tomni Date: Sat, 10 Jan 2026 17:43:34 +0100 Subject: [PATCH 17/17] Docs: Clarify resampling semantics and resolution limits in the Reporting API. Signed-off-by: tomni --- RELEASE_NOTES.md | 2 + .../api/reporting/v1alpha10/reporting.proto | 73 ++++++++++--------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e87e2d1..ecf6a6d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,6 +4,8 @@ - The behavior of the TimeFilter has changed, and its documentation has been updated accordingly. - Clarified resampling and streaming semantics in the Reporting API, including interval-based timestamps, empty values, and update (upsert) behavior for resampled streams. +- Renamed the service to align with other Frequenz services. +- TimeFilter has been changed to make use of frequenz.api.common.v1alpha8.types.Interval ## Upgrading diff --git a/proto/frequenz/api/reporting/v1alpha10/reporting.proto b/proto/frequenz/api/reporting/v1alpha10/reporting.proto index 5a784e9..ab017b3 100644 --- a/proto/frequenz/api/reporting/v1alpha10/reporting.proto +++ b/proto/frequenz/api/reporting/v1alpha10/reporting.proto @@ -136,7 +136,7 @@ import "google/protobuf/timestamp.proto"; // over TLS (HTTPS). // service ReportingService { - // Streams metrics for a list of microgrid components. + // Streams metrics for a list of microgrid electrical components. // // !!! note // This RPC endpoint streams metrics data for electrical components of one @@ -261,14 +261,17 @@ message TimeFilter { // values forward across intervals. // // !!! note "Resolution constraints" -// The service enforces an upper bound on the resampling resolution. +// Resampling resolutions are fixed-duration intervals expressed in +// seconds and are not calendar-aware. The service enforces an upper +// bound on the resampling resolution. // -// Resolutions larger than one calendar month are not supported, as -// they exceed the intended scope of telemetry resampling. +// Resolutions larger than 7 days are not supported, as they exceed the +// intended scope of fixed-duration telemetry resampling. // // Typical and recommended resolutions include 5 minutes, 15 minutes, -// 1 hour, and 1 day. Monthly resolution may be used for long-horizon -// analysis and backtesting. +// 1 hour, 1 day, and 7 days. Longer-horizon or calendar-based aggregation +// (for example monthly analysis) should be performed client-side on the +// resampled data. // // !!! example "Example: Downsampling from 1-second to 15-minute intervals" // The stored time series has a effective sampling resolution of Δt = 1 @@ -281,8 +284,14 @@ message TimeFilter { // For each interval k: // Ik = [T0 + k·ΔT, T0 + (k+1)·ΔT) // -// The aggregated value A_k is by default the arithmetic mean of all -// samples whose timestamps ts satisfy: ts ∈ Ik +// The aggregated value A_k is computed using the configured aggregation +// method (see `downsampling_method`) and may additionally follow +// metric-specific semantics. +// +// For example, for instantaneous metrics the arithmetic mean is commonly +// used, while for cumulative (counter-like) metrics averaging is not +// meaningful and a representative value within the interval is used +// instead. // // The resampled series consists of points: // (t = T0 + k·ΔT, value = A_k) @@ -290,14 +299,20 @@ message TimeFilter { // !!! note "Real-time streams" // For open-ended streams, resampling windows advance according to // wall-clock time. Window emission is time-driven, not event-driven. -// As telemetry samples may arrive late (e.g. due to -// buffering, transport delays, or upstream batching) a window MAY be -// emitted even if the telemetry samples have not yet arrived during the -// interval. In consequence a resampling interval that has already been -// emitted MAY be re-emitted later with an updated value when additional -// samples for that interval arrive. -// -// Clients must be able to handle interval updates (upserts) and must not +// +// The service does not provide a fixed guarantee for when an interval’s +// sample will be emitted. In particular, delivery latency may vary due to +// buffering, transport delays, upstream batching, scheduling, or load. +// Clients MUST NOT rely on sample arrival time to infer measurement time +// or completeness. +// +// Because telemetry samples may arrive late, an interval MAY be emitted +// before all telemetry for that interval has arrived. In consequence, a +// resampling interval that has already been emitted MAY be re-emitted +// later with an updated value when additional samples for that interval +// arrive. +// +// Clients MUST be able to handle interval updates (upserts) and MUST NOT // assume that emitted intervals are final. // message ResamplingOptions { @@ -378,28 +393,18 @@ message AggregationConfig { // within a microgrid or to calculate the average state of charge of several // batteries. // -// Depending on whether resampling is enabled in the request, it can -// represent either: -// • a point-in-time aggregated value (no resampling requested), or -// • an aggregated value for a resampling interval (resampling requested). +// !!! note "Resampling is required" +// Aggregated/formula streams always use resampling to align measurements +// from various sources in time. // message SimpleAggregatedMetricValue { - // The UTC timestamp associated with this aggregated value. - // - // Semantics depend on whether resampling is enabled: - // - // • Without resampling: - // `sample_time` represents the origin time of the underlying - // telemetry measurement(s), i.e. the time at which the metric - // value was observed at the component or sensor. This is the - // original timestamp of the samples that were aggregated. + // The UTC timestamp identifying the resampling interval. // - // • With resampling: - // `sample_time` represents the start of the resampling interval - // [t, t + ΔT) to which contributing telemetry samples are assigned - // based on their origin timestamps. + // This timestamp is the start of the resampling interval [t, t + ΔT) to + // which contributing telemetry measurements are assigned based on their + // origin timestamps. // - // In all cases, `sample_time` refers to measurement time, not processing + // `sample_time` refers to measurement time (interval start), not processing // or emission time. google.protobuf.Timestamp sample_time = 1;