diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4a5ab36b..b9ebe66d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -76,6 +76,8 @@ - The type of the field `metrics.MetricSample.connection` has been changed from `string` to `metrics.MetricConnection`. The latter is a newly added message that provides a better categorization of the connection type. +- The `v1` package has been renamed to `v1alpha7`. The current `v1` package now consists of the contents the same directory from the v0.6.x branch, which is the latest stable version of the API. + ## New Features Added many new messages and enum values: diff --git a/proto/frequenz/api/common/v1/grid/delivery_area.proto b/proto/frequenz/api/common/v1/grid/delivery_area.proto index 6639147b..bfa4ad88 100644 --- a/proto/frequenz/api/common/v1/grid/delivery_area.proto +++ b/proto/frequenz/api/common/v1/grid/delivery_area.proto @@ -1,4 +1,4 @@ -// Frequenz definitions of grids as entites participating in trading. +// Frequenz definitions of grids as entities participating in trading. // // Copyright 2023 Frequenz Energy-as-a-Service GmbH // diff --git a/proto/frequenz/api/common/v1/type/location.proto b/proto/frequenz/api/common/v1/location.proto similarity index 93% rename from proto/frequenz/api/common/v1/type/location.proto rename to proto/frequenz/api/common/v1/location.proto index 130fef63..e3a30181 100644 --- a/proto/frequenz/api/common/v1/type/location.proto +++ b/proto/frequenz/api/common/v1/location.proto @@ -7,7 +7,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.type; +package frequenz.api.common.v1; // A pair of geographical co-ordinates, representing the location of a place. message Location { diff --git a/proto/frequenz/api/common/v1/market/energy.proto b/proto/frequenz/api/common/v1/market/energy.proto index fed894a5..9157f1e6 100644 --- a/proto/frequenz/api/common/v1/market/energy.proto +++ b/proto/frequenz/api/common/v1/market/energy.proto @@ -9,7 +9,7 @@ syntax = "proto3"; package frequenz.api.common.v1.market; -import "frequenz/api/common/v1/type/decimal.proto"; +import "frequenz/api/common/v1/types/decimal.proto"; // Represents a single unit of electricity. // @@ -20,5 +20,5 @@ import "frequenz/api/common/v1/type/decimal.proto"; // production or consumption. message Energy { // Energy unit in Megawatthours (MWh). - frequenz.api.common.v1.type.Decimal mwh = 1; + frequenz.api.common.v1.types.Decimal mwh = 1; } diff --git a/proto/frequenz/api/common/v1/market/power.proto b/proto/frequenz/api/common/v1/market/power.proto index b6b47568..a77308e7 100644 --- a/proto/frequenz/api/common/v1/market/power.proto +++ b/proto/frequenz/api/common/v1/market/power.proto @@ -9,7 +9,7 @@ syntax = "proto3"; package frequenz.api.common.v1.market; -import "frequenz/api/common/v1/type/decimal.proto"; +import "frequenz/api/common/v1/types/decimal.proto"; // Represents a single unit of power. // @@ -26,5 +26,5 @@ import "frequenz/api/common/v1/type/decimal.proto"; // market applications. message Power { // Power amount in Megawatts (MW). - frequenz.api.common.v1.type.Decimal mw = 1; + frequenz.api.common.v1.types.Decimal mw = 1; } diff --git a/proto/frequenz/api/common/v1/market/price.proto b/proto/frequenz/api/common/v1/market/price.proto index 22c57691..1791fcc0 100644 --- a/proto/frequenz/api/common/v1/market/price.proto +++ b/proto/frequenz/api/common/v1/market/price.proto @@ -9,7 +9,7 @@ syntax = "proto3"; package frequenz.api.common.v1.market; -import "frequenz/api/common/v1/type/decimal.proto"; +import "frequenz/api/common/v1/types/decimal.proto"; // Represents a monetary price for electricity trading, including // the amount and currency. The currency used should align with the @@ -46,7 +46,7 @@ message Price { } // The amount of the price. - frequenz.api.common.v1.type.Decimal amount = 1; + frequenz.api.common.v1.types.Decimal amount = 1; // The currency in which the price is denominated. Currency currency = 2; diff --git a/proto/frequenz/api/common/v1/metrics/metric_sample.proto b/proto/frequenz/api/common/v1/metrics/metric_sample.proto new file mode 100644 index 00000000..dd9bc533 --- /dev/null +++ b/proto/frequenz/api/common/v1/metrics/metric_sample.proto @@ -0,0 +1,240 @@ +// Metrics definitions. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1.metrics; + +import "frequenz/api/common/v1/metrics/bounds.proto"; + +import "google/protobuf/timestamp.proto"; + +// Represents a single sample of a specific metric, the value of which is either +// measured or derived at a particular time. +message SimpleMetricValue { + // The value of the metric, which could be either measured or derived. + float value = 2; +} + +// Encapsulates derived statistical summaries of a single metric. +// +// The message allows for the reporting of statistical summaries — minimum, +// maximum, and average values - as well as the complete list of individual +// samples if available. +// +// This message represents derived metrics and contains fields for statistical +// summaries—minimum, maximum, and average values. Individual measurements are +// are optional, accommodating scenarios where only subsets of this information +// are available. +message AggregatedMetricValue { + // The derived average value of the metric. + float avg_value = 2; + + // The minimum measured value of the metric. + optional float min_value = 3; + + // The maximum measured value of the metric. + optional float max_value = 4; + + // Optional array of all the raw individual values. + repeated float raw_values = 5; +} + +// `MetricValueVariant` serves as a union type that can encapsulate either a +// `SimpleMetricValue` or an `AggregatedMetricValue`. +// +// This message is designed to offer flexibility in capturing different +// granularities of metric samples—either a simple single-point measurement +// or an aggregated set of measurements for a metric. +// +// A `MetricValueVariant` can hold either a `SimpleMetricValue` or an +// `AggregatedMetricValue`, but not both simultaneously. Setting one will +// nullify the other. +message MetricValueVariant { + oneof metric_value_variant { + SimpleMetricValue simple_metric = 1; + AggregatedMetricValue aggregated_metric = 2; + } +} + +// List of supported metrics. +// +// !!! note +// AC energy metrics information: +// +// * This energy metric is reported directly from the component, and not a +// result of aggregations in our systems. If a component does not have this +// metric, this field cannot be populated. +// +// * Components that provide energy metrics reset this metric from time to +// time. This behaviour is specific to each component model. E.g., some +// components reset it on UTC 00:00:00. +// +// * This energy metric does not specify the timestamp since when the energy +// was being accumulated, and therefore can be inconsistent. +enum Metric { + // Default value. + METRIC_UNSPECIFIED = 0; + + // DC electricity metrics + METRIC_DC_VOLTAGE = 1; + METRIC_DC_CURRENT = 2; + METRIC_DC_POWER = 3; + + // General AC electricity metrics + METRIC_AC_FREQUENCY = 10; + METRIC_AC_VOLTAGE = 11; + METRIC_AC_VOLTAGE_PHASE_1_N = 12; + METRIC_AC_VOLTAGE_PHASE_2_N = 13; + METRIC_AC_VOLTAGE_PHASE_3_N = 14; + METRIC_AC_VOLTAGE_PHASE_1_PHASE_2 = 15; + METRIC_AC_VOLTAGE_PHASE_2_PHASE_3 = 16; + METRIC_AC_VOLTAGE_PHASE_3_PHASE_1 = 17; + METRIC_AC_CURRENT = 18; + METRIC_AC_CURRENT_PHASE_1 = 19; + METRIC_AC_CURRENT_PHASE_2 = 20; + METRIC_AC_CURRENT_PHASE_3 = 21; + + // AC power metrics + METRIC_AC_APPARENT_POWER = 22; + METRIC_AC_APPARENT_POWER_PHASE_1 = 23; + METRIC_AC_APPARENT_POWER_PHASE_2 = 24; + METRIC_AC_APPARENT_POWER_PHASE_3 = 25; + METRIC_AC_ACTIVE_POWER = 26; + METRIC_AC_ACTIVE_POWER_PHASE_1 = 27; + METRIC_AC_ACTIVE_POWER_PHASE_2 = 28; + METRIC_AC_ACTIVE_POWER_PHASE_3 = 29; + METRIC_AC_REACTIVE_POWER = 30; + METRIC_AC_REACTIVE_POWER_PHASE_1 = 31; + METRIC_AC_REACTIVE_POWER_PHASE_2 = 32; + METRIC_AC_REACTIVE_POWER_PHASE_3 = 33; + + // AC Power factor + METRIC_AC_POWER_FACTOR = 40; + METRIC_AC_POWER_FACTOR_PHASE_1 = 41; + METRIC_AC_POWER_FACTOR_PHASE_2 = 42; + METRIC_AC_POWER_FACTOR_PHASE_3 = 43; + + // AC energy metrics + METRIC_AC_APPARENT_ENERGY = 50; + METRIC_AC_APPARENT_ENERGY_PHASE_1 = 51; + METRIC_AC_APPARENT_ENERGY_PHASE_2 = 52; + METRIC_AC_APPARENT_ENERGY_PHASE_3 = 53; + METRIC_AC_ACTIVE_ENERGY = 54; + METRIC_AC_ACTIVE_ENERGY_PHASE_1 = 55; + METRIC_AC_ACTIVE_ENERGY_PHASE_2 = 56; + METRIC_AC_ACTIVE_ENERGY_PHASE_3 = 57; + METRIC_AC_ACTIVE_ENERGY_CONSUMED = 58; + METRIC_AC_ACTIVE_ENERGY_CONSUMED_PHASE_1 = 59; + METRIC_AC_ACTIVE_ENERGY_CONSUMED_PHASE_2 = 60; + METRIC_AC_ACTIVE_ENERGY_CONSUMED_PHASE_3 = 61; + METRIC_AC_ACTIVE_ENERGY_DELIVERED = 62; + METRIC_AC_ACTIVE_ENERGY_DELIVERED_PHASE_1 = 63; + METRIC_AC_ACTIVE_ENERGY_DELIVERED_PHASE_2 = 64; + METRIC_AC_ACTIVE_ENERGY_DELIVERED_PHASE_3 = 65; + METRIC_AC_REACTIVE_ENERGY = 66; + METRIC_AC_REACTIVE_ENERGY_PHASE_1 = 67; + METRIC_AC_REACTIVE_ENERGY_PHASE_2 = 69; + METRIC_AC_REACTIVE_ENERGY_PHASE_3 = 70; + + // AC harmonics + METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT = 80; + METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_1 = 81; + METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_2 = 82; + METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_3 = 83; + + // General BMS metrics. + METRIC_BATTERY_CAPACITY = 101; + METRIC_BATTERY_SOC_PCT = 102; + METRIC_BATTERY_TEMPERATURE = 103; + + // General inverter metrics. + METRIC_INVERTER_TEMPERATURE = 120; + METRIC_INVERTER_TEMPERATURE_CABINET = 121; + METRIC_INVERTER_TEMPERATURE_HEATSINK = 122; + METRIC_INVERTER_TEMPERATURE_TRANSFORMER = 123; + + // EV charging station metrics. + METRIC_EV_CHARGER_TEMPERATURE = 140; + + // General sensor metrics + METRIC_SENSOR_WIND_SPEED = 160; + METRIC_SENSOR_WIND_DIRECTION = 162; + METRIC_SENSOR_TEMPERATURE = 163; + METRIC_SENSOR_RELATIVE_HUMIDITY = 164; + METRIC_SENSOR_DEW_POINT = 165; + METRIC_SENSOR_AIR_PRESSURE = 166; + METRIC_SENSOR_IRRADIANCE = 167; +} + +// Representation of a sampled metric along with its value. +// +// !!! note +// This represents a single sample of a specific metric, the value of which +// is either measured or derived at a particular time. The real-time +// system-defined bounds are optional and may not always be present or set. +// +// !!! note +// ### Relationship Between Bounds and Metric Samples +// Suppose a metric sample for active power has a lower-bound of -10,000 W, +// and an upper-bound of 10,000 W. For the system to accept a charge +// command, clients need to request current values within the bounds. +message MetricSample { + // The UTC timestamp of when the metric was sampled. + google.protobuf.Timestamp sampled_at = 1; + + // The metric that was sampled. + Metric metric = 2; + + // The value of the sampled metric. + MetricValueVariant value = 3; + + // List of bounds that apply to the metric sample. + // + // These bounds adapt in real-time to reflect the operating conditions at the + // time of aggregation or derivation. + // + // #### Multiple Bounds + // + // In the case of certain components like batteries, multiple bounds might + // exist. These multiple bounds collectively extend the range of allowable + // values, effectively forming a union of all given bounds. In such cases, + // the value of the metric must be within at least one of the bounds. + // In accordance with the passive sign convention, bounds that limit discharge + // would have negative numbers, while those limiting charge, such as for the + // State of Power (SoP) metric, would be positive. Hence bounds can have + // positive and negative values depending on the metric they represent. + // + // #### Example + // + // The diagram below illustrates the relationship between the bounds. + // ``` + // bound[0].lower bound[1].upper + // <-------|============|------------------|============|---------> + // bound[0].upper bound[1].lower + // ``` + // ---- values here are disallowed and will be rejected + // ==== values here are allowed and will be accepted + repeated Bounds bounds = 4; + + // An optional string that can be used to identify the source of the metric. + // + // This is expected to be populated when the same `Metric` variant can be + // obtained from multiple sensors in the component. Knowing the source of the + // metric can help in certain control and monitoring applications. + // + // E.g., a hybrid inverter can have a DC string for a battery and another DC + // string for a PV array. The source names could resemble, say, + // `dc_battery_0` and ``dc_pv_0`. A metric like DC voltage can be obtained + // from both sources. For an application to determine the SoC of the battery + // using the battery voltage, the source of the voltage metric is important. + // + // In cases where the component has just one source for a metric, then this + // field is not expected to be present, because the source is implicit. + optional string source = 5; +} diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/battery.proto b/proto/frequenz/api/common/v1/microgrid/components/battery.proto similarity index 87% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/battery.proto rename to proto/frequenz/api/common/v1/microgrid/components/battery.proto index e1413b1b..2d0e8da6 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/battery.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/battery.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1.microgrid.components; // Enumerated battery types. enum BatteryType { diff --git a/proto/frequenz/api/common/v1/microgrid/components/components.proto b/proto/frequenz/api/common/v1/microgrid/components/components.proto new file mode 100644 index 00000000..8b9520ff --- /dev/null +++ b/proto/frequenz/api/common/v1/microgrid/components/components.proto @@ -0,0 +1,492 @@ +// Frequenz microgrid components definitions. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1.microgrid.components; + +import "frequenz/api/common/v1/metrics/bounds.proto"; +import "frequenz/api/common/v1/metrics/metric_sample.proto"; +import "frequenz/api/common/v1/microgrid/components/battery.proto"; +import "frequenz/api/common/v1/microgrid/components/ev_charger.proto"; +import "frequenz/api/common/v1/microgrid/components/fuse.proto"; +import "frequenz/api/common/v1/microgrid/components/grid.proto"; +import "frequenz/api/common/v1/microgrid/components/inverter.proto"; +import "frequenz/api/common/v1/microgrid/components/transformer.proto"; +import "frequenz/api/common/v1/microgrid/lifetime.proto"; + +import "google/protobuf/timestamp.proto"; + +// Enumrated component categories. +enum ComponentCategory { + // The component category is unspecified. This should not be used. + COMPONENT_CATEGORY_UNSPECIFIED = 0; + + // The point where the local microgrid is connected to the grid. + COMPONENT_CATEGORY_GRID = 1; + + // A meter, for measuring electrical metrics, e.g., current, voltage, etc. + COMPONENT_CATEGORY_METER = 2; + + // An electricity generator, with batteries or solar energy. + COMPONENT_CATEGORY_INVERTER = 3; + + // A DC-DC converter. + COMPONENT_CATEGORY_CONVERTER = 4; + + // A storage system for electrical energy, used by inverters. + COMPONENT_CATEGORY_BATTERY = 5; + + // A station for charging electrical vehicles. + COMPONENT_CATEGORY_EV_CHARGER = 6; + + // A crypto miner. + COMPONENT_CATEGORY_CRYPTO_MINER = 8; + + // An electrolyzer for converting water into hydrogen and oxygen. + COMPONENT_CATEGORY_ELECTROLYZER = 9; + + // A heat and power combustion plant (CHP stands for combined heat and power). + COMPONENT_CATEGORY_CHP = 10; + + // A relay. + // Relays generally have two states: open (connected) and closed + // (disconnected). + // They are generally placed in front of a component, e.g., an inverter, to + // control whether the component is connected to the grid or not. + COMPONENT_CATEGORY_RELAY = 11; + + // A precharge module. + // Precharging involves gradually ramping up the DC voltage to prevent any + // potential damage to sensitive electrical components like capacitors. + // While many inverters and batteries come equipped with in-built precharging + // mechanisms, some may lack this feature. In such cases, we need to use + // external precharging modules. + COMPONENT_CATEGORY_PRECHARGER = 12; + + // A fuse. + // Fuses are used to protect electrical components from overcurrents. + COMPONENT_CATEGORY_FUSE = 13; + + // A voltage transformer. + // Voltage transformers are used to step up or step down the voltage, keeping + // the power somewhat constant by increasing or decreasing the current. + // If voltage is stepped up, current is stepped down, and vice versa. + // Note that voltage transformers have efficiency losses, so the output power + // is always less than the input power. + COMPONENT_CATEGORY_VOLTAGE_TRANSFORMER = 14; + + // An HVAC (Heating, Ventilation, and Air Conditioning) system. + COMPONENT_CATEGORY_HVAC = 15; +} + +// Metadata specific to a microgrid component. +message ComponentCategoryMetadataVariant { + oneof metadata { + frequenz.api.common.v1.microgrid.components.Battery battery = 1; + frequenz.api.common.v1.microgrid.components.EvCharger ev_charger = 2; + frequenz.api.common.v1.microgrid.components.Fuse fuse = 3; + frequenz.api.common.v1.microgrid.components.GridConnectionPoint grid = 4; + frequenz.api.common.v1.microgrid.components.Inverter inverter = 5; + frequenz.api.common.v1.microgrid.components.VoltageTransformer + voltage_transformer = 6; + } +} + +// ComponentStatus defines the possible statuses for a component. +// +// !!! note +// The status indicates the status set by the user via the user interface. +// The status is not yet included in the Component messages and should be +// added. +// +enum ComponentStatus { + // The status is unspecified. This should not be used. + COMPONENT_STATUS_UNSPECIFIED = 0; + + // The component is active. + COMPONENT_STATUS_ACTIVE = 1; + + // The component is inactive. + COMPONENT_STATUS_INACTIVE = 2; +} + +// Microgrid electrical component details. +message Component { + // The component ID. + uint64 id = 1; + + // Unique identifier of the parent microgrid_id. + uint64 microgrid_id = 2; + + // The component name. + string name = 3; + + // The component category. E.g., Inverter, Battery, etc. + ComponentCategory category = 4; + + // The metadata specific to the component category type. + ComponentCategoryMetadataVariant category_type = 5; + + // The component manufacturer. + string manufacturer = 6; + + // The model name of the component. + string model_name = 7; + + // The status of the component. + ComponentStatus status = 8; + + // The operational lifetime of the component. + frequenz.api.common.v1.microgrid.Lifetime operational_lifetime = 9; + + // List of rated bounds present for the component identified by Metric. + repeated MetricConfigBounds metric_config_bounds = 10; +} + +// MetricConfigBounds describes a set of limits for a specific metric consisting +// of a lower and upper bound for said metric. +// +// This can be used for example to specify an allowed range of power output +// for a component. +message MetricConfigBounds { + // Metric type the config bounds are for + frequenz.api.common.v1.metrics.Metric metric = 1; + + // The set of bounds for the specified metric. + // + // This contains the lower and upper bounds for said metric. + // Sources these may be derived from include the component configuration, + // manufacturers limits, and limits of other devices. + frequenz.api.common.v1.metrics.Bounds config_bounds = 2; +} + +// ComponentConnection describes a single electrical link between two components +// within a microgrid, effectively representing the physical wiring as viewed +// from the grid connection point, if one exists, or from the islanding point, +// in case of an islanded microgrids. +// +// !!! note "Physical Representation" +// This message is not about data flow but rather about the physical +// electrical connections between components. Therefore, the IDs for the +// source and destination components correspond to the actual setup within +// the microgrid. +// +// !!! note "Direction" +// The direction of the connection follows the flow of current away from the +// grid connection point, or in case of islands, away from the islanding +// point. This direction is aligned with positive current according to the +// [Passive Sign Convention] +// (https://en.wikipedia.org/wiki/Passive_sign_convention). +// +// !!! info "Historical Data" +// The timestamps of when a connection was created and terminated allows for +// tracking the changes over time to a microgrid, providing insights into +// when and how the microgrid infrastructure has been modified. +// +message ComponentConnection { + // Unique identifier of the component where the connection originates. This is + // aligned with the direction of current flow away from the grid connection + // point, or in case of islands, away from the islanding point. + uint64 source_component_id = 1; + + // Unique ID of the component where the connection terminates. This is the + // component towards which the current flows. + uint64 destination_component_id = 2; + + // The operational lifetime of the connection. + frequenz.api.common.v1.microgrid.Lifetime operational_lifetime = 3; +} + +// ComponentData message aggregates multiple metrics, operational states, and +// errors, related to a specific microgrid component. +// +// !!! example +// Example output of a component data message: +// ``` +// { +// component_id: 13, +// metric_samples: [ +// /* list of metrics for multiple timestamps */ +// { +// sampled_at: "2023-10-01T00:00:00Z", +// metric: "DC_VOLTAGE_V", +// value: {}, +// bounds: {}, +// }, +// { +// sampled_at: "2023-10-01T00:00:00Z", +// metric: "DC_VOLTAGE_V", +// value: {}, +// bounds: {}, +// } +// ], +// states: [ +// /* list of states for multiple timestamps */ +// { +// sampled_at: "2023-10-01T00:00:00Z", +// states: [], +// warnings: [], +// errors: [], +// }, +// { +// sampled_at: "2023-10-01T00:00:00Z", +// states: [], +// warnings: [], +// errors: [], +// }, +// ] +// } +// ``` +message ComponentData { + // The ID of the microgrid component. + uint64 component_id = 1; + + // List of measurements for a metric of the specific microgrid component. + repeated frequenz.api.common.v1.metrics.MetricSample metric_samples = 2; + + // List of states of a specific microgrid component. + repeated ComponentState states = 3; +} + +// Enum to represent the various states that a component can be in. +// This enum is unified across all component categories for consistency. +enum ComponentStateCode { + // Default value when the component state is not explicitly set. + // This is the zero value of the enum. + COMPONENT_STATE_CODE_UNSPECIFIED = 0; + + // State when the component is in an unknown or undefined condition. + // This is used when the sender is unable to classify the component into any + // other state. + COMPONENT_STATE_CODE_UNKNOWN = 1; + + // State when the component is temporarily unavailable for operation. + COMPONENT_STATE_CODE_UNAVAILABLE = 2; + + // State when the component is in the process of switching off. + COMPONENT_STATE_CODE_SWITCHING_OFF = 3; + + // State when the component has successfully switched off. + COMPONENT_STATE_CODE_OFF = 4; + + // State when the component is in the process of switching on from an off + // state. + COMPONENT_STATE_CODE_SWITCHING_ON = 5; + + // State when the component is in standby mode, and not immediately ready for + // immediate operations. + COMPONENT_STATE_CODE_STANDBY = 6; + + // State when the component is fully operational and ready for use. + COMPONENT_STATE_CODE_READY = 7; + + // State when the component is actively consuming energy. + COMPONENT_STATE_CODE_CHARGING = 8; + + // State when the component is actively producing or releasing energy. + COMPONENT_STATE_CODE_DISCHARGING = 9; + + // State when the component is in an error state and may need attention. + COMPONENT_STATE_CODE_ERROR = 10; + + // The Electric Vehicle (EV) charging cable is unplugged from the charging + // station. + COMPONENT_STATE_CODE_EV_CHARGING_CABLE_UNPLUGGED = 20; + + // The EV charging cable is plugged into the charging station. + COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_STATION = 21; + + // The EV charging cable is plugged into the vehicle. + COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_EV = 22; + + // The EV charging cable is locked at the charging station end, indicating + // readiness for charging. + COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_STATION = 23; + + // The EV charging cable is locked at the vehicle end, indicating that + // charging is active. + COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_EV = 24; + + // The relay is in an open state, meaning no current can flow through. + COMPONENT_STATE_CODE_RELAY_OPEN = 30; + + // The relay is in a closed state, allowing current to flow. + COMPONENT_STATE_CODE_RELAY_CLOSED = 31; + + // The precharger circuit is open, meaning it's not currently active. + COMPONENT_STATE_CODE_PRECHARGER_OPEN = 40; + + // The precharger is in a precharging state, preparing the main circuit for + // activation. + COMPONENT_STATE_CODE_PRECHARGER_PRECHARGING = 41; + + // The precharger circuit is closed, allowing full current to flow to the main + // circuit. + COMPONENT_STATE_CODE_PRECHARGER_CLOSED = 42; +} + +// A representation of all possible errors that can occur across all component +// categories. +enum ComponentErrorCode { + // Default value. No specific error is specified. + COMPONENT_ERROR_CODE_UNSPECIFIED = 0; + + // The component is reporting an unknown or an undefined error, and the sender + // cannot parse the component error to any of the variants below. + COMPONENT_ERROR_CODE_UNKNOWN = 1; + + // Error indicating that the component could not be switched on. + COMPONENT_ERROR_CODE_SWITCH_ON_FAULT = 2; + + // Error indicating that the component is operating under the minimum rated + // voltage. + COMPONENT_ERROR_CODE_UNDERVOLTAGE = 3; + + // Error indicating that the component is operating over the maximum rated + // voltage. + COMPONENT_ERROR_CODE_OVERVOLTAGE = 4; + + // Error indicating that the component is drawing more current than the + // maximum rated value. + COMPONENT_ERROR_CODE_OVERCURRENT = 5; + + // Error indicating that the component's consumption current is over the + // maximum rated value during charging. + COMPONENT_ERROR_CODE_OVERCURRENT_CHARGING = 6; + + // Error indicating that the component's production current is over the + // maximum rated value during discharging. + COMPONENT_ERROR_CODE_OVERCURRENT_DISCHARGING = 7; + + // Error indicating that the component is operating over the maximum rated + // temperature. + COMPONENT_ERROR_CODE_OVERTEMPERATURE = 8; + + // Error indicating that the component is operating under the minimum rated + // temperature. + COMPONENT_ERROR_CODE_UNDERTEMPERATURE = 9; + + // Error indicating that the component is exposed to high humidity levels over + // the maximum rated value. + COMPONENT_ERROR_CODE_HIGH_HUMIDITY = 10; + + // Error indicating that the component's fuse has blown. + COMPONENT_ERROR_CODE_FUSE_ERROR = 11; + + // Error indicating that the component's precharge unit has failed. + COMPONENT_ERROR_CODE_PRECHARGE_ERROR = 12; + + // Error indicating plausibility issues within the system involving this + // component. + COMPONENT_ERROR_CODE_PLAUSIBILITY_ERROR = 13; + + // Error indicating system shutdown due to undervoltage involving this + // component. + COMPONENT_ERROR_CODE_UNDERVOLTAGE_SHUTDOWN = 14; + + // Error indicating unexpected pilot failure in an electric vehicle (EV) + // component. + COMPONENT_ERROR_CODE_EV_UNEXPECTED_PILOT_FAILURE = 15; + + // Error indicating fault current detected in the component. + COMPONENT_ERROR_CODE_FAULT_CURRENT = 16; + + // Error indicating a short circuit detected in the component. + COMPONENT_ERROR_CODE_SHORT_CIRCUIT = 17; + + // Error indicating a configuration error related to the component. + COMPONENT_ERROR_CODE_CONFIG_ERROR = 18; + + // Error indicating an illegal state requested for the component. + COMPONENT_ERROR_CODE_ILLEGAL_COMPONENT_STATE_CODE_REQUESTED = 19; + + // Error indicating that the hardware of the component is inaccessible. + COMPONENT_ERROR_CODE_HARDWARE_INACCESSIBLE = 20; + + // Error indicating an internal error within the component. + COMPONENT_ERROR_CODE_INTERNAL = 21; + + // Error indicating that the component is unauthorized to perform the + // last requested action. + COMPONENT_ERROR_CODE_UNAUTHORIZED = 22; + + // Error indicating electric vehicle (EV) cable was abruptly unplugged from + // the charging station. + COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_STATION = 40; + + // Error indicating electric vehicle (EV) cable was abruptly unplugged from + // the vehicle. + COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_EV = 41; + + // Error indicating electric vehicle (EV) cable lock failure. + COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_LOCK_FAILED = 42; + + // Error indicating an invalid electric vehicle (EV) cable. + COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_INVALID = 43; + + // Error indicating an incompatible electric vehicle (EV) plug. + COMPONENT_ERROR_CODE_EV_CONSUMER_INCOMPATIBLE = 44; + + // Error indicating a battery system imbalance. + COMPONENT_ERROR_CODE_BATTERY_IMBALANCE = 50; + + // Error indicating a low state of health (SOH) detected in the battery. + COMPONENT_ERROR_CODE_BATTERY_LOW_SOH = 51; + + // Error indicating a battery block error. + COMPONENT_ERROR_CODE_BATTERY_BLOCK_ERROR = 52; + + // Error indicating a battery controller error. + COMPONENT_ERROR_CODE_BATTERY_CONTROLLER_ERROR = 53; + + // Error indicating a battery relay error. + COMPONENT_ERROR_CODE_BATTERY_RELAY_ERROR = 54; + + // Error indicating that battery calibration is needed. + COMPONENT_ERROR_CODE_BATTERY_CALIBRATION_NEEDED = 56; + + // Error indicating that the relays have been cycled for the maximum number of + // times. + COMPONENT_ERROR_CODE_RELAY_CYCLE_LIMIT_REACHED = 60; +} + +// Representation of a component state and errors. +message ComponentState { + // The time at which the state was sampled. + google.protobuf.Timestamp sampled_at = 1; + + // List of states of the microgrid component. + // + // !!! note + // The list will contain unique members. No state will exist twice in + // this list. + repeated ComponentStateCode states = 2; + + // List of warnings for the microgrid component. + // + // !!! note + // This list may have warnings even if the component state is not in an + // error state. + // + // !!! note + // The list will contain unique members. No warning will exist twice in + // this list. + repeated ComponentErrorCode warnings = 3; + + // List of errors for the microgrid component. + // + // !!! note + // This list is expected to have errors if and only if the component is in + // an error state. + // + // !!! note + // The list will contain unique members. No error will exist twice in + // this list. + repeated ComponentErrorCode errors = 4; +} diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/ev_charger.proto b/proto/frequenz/api/common/v1/microgrid/components/ev_charger.proto similarity index 90% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/ev_charger.proto rename to proto/frequenz/api/common/v1/microgrid/components/ev_charger.proto index 7a8be4e0..f7a78475 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/ev_charger.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/ev_charger.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1.microgrid.components; // Enumerated EV charger types. enum EvChargerType { diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/fuse.proto b/proto/frequenz/api/common/v1/microgrid/components/fuse.proto similarity index 92% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/fuse.proto rename to proto/frequenz/api/common/v1/microgrid/components/fuse.proto index c50526b0..6f128d38 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/fuse.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/fuse.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1.microgrid.components; // A representation of a fuse. // The fuse component represents a fuse in the microgrid. It is used to protect diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/grid.proto b/proto/frequenz/api/common/v1/microgrid/components/grid.proto similarity index 96% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/grid.proto rename to proto/frequenz/api/common/v1/microgrid/components/grid.proto index a11c1861..11e144fa 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/grid.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/grid.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1.microgrid.components; // A representation of a grid connection point. This is the point where a // microgrid connects to the grid. diff --git a/proto/frequenz/api/common/v1/microgrid/components/inverter.proto b/proto/frequenz/api/common/v1/microgrid/components/inverter.proto new file mode 100644 index 00000000..bb99e5ed --- /dev/null +++ b/proto/frequenz/api/common/v1/microgrid/components/inverter.proto @@ -0,0 +1,33 @@ +// Frequenz definitions for inverters. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1.microgrid.components; + +// Enumerated inverter types. +enum InverterType { + // Unspecified. + INVERTER_TYPE_UNSPECIFIED = 0; + + // Battery inverter. + INVERTER_TYPE_BATTERY = 1; + + // Solar inverter. + INVERTER_TYPE_SOLAR = 2; + + // Hybrid inverter. + INVERTER_TYPE_HYBRID = 3; +} + +// A representation of an inverter. +// The inverter metadata. +message Inverter { + // The inverter type. + InverterType type = 1; +} diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/transformer.proto b/proto/frequenz/api/common/v1/microgrid/components/transformer.proto similarity index 93% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/transformer.proto rename to proto/frequenz/api/common/v1/microgrid/components/transformer.proto index 10423fd2..2df79de1 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/transformer.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/transformer.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1.microgrid.components; // A representation of a voltage transformer. // Voltage transformers are used to step up or step down the voltage, keeping diff --git a/proto/frequenz/api/common/v1/microgrid/microgrid.proto b/proto/frequenz/api/common/v1/microgrid/microgrid.proto index 09fcf031..419a1f02 100644 --- a/proto/frequenz/api/common/v1/microgrid/microgrid.proto +++ b/proto/frequenz/api/common/v1/microgrid/microgrid.proto @@ -10,7 +10,7 @@ syntax = "proto3"; package frequenz.api.common.v1.microgrid; import "frequenz/api/common/v1/grid/delivery_area.proto"; -import "frequenz/api/common/v1/type/location.proto"; +import "frequenz/api/common/v1/location.proto"; import "google/protobuf/timestamp.proto"; @@ -60,7 +60,7 @@ message Microgrid { // Physical location of the microgrid, in geographical co-ordinates. // // If the location is not known, this field will be missing. - frequenz.api.common.v1.type.Location location = 5; + frequenz.api.common.v1.Location location = 5; // The current status of the microgrid. MicrogridStatus status = 6; diff --git a/proto/frequenz/api/common/v1/microgrid/sensors/sensors.proto b/proto/frequenz/api/common/v1/microgrid/sensors/sensors.proto index f17aadf4..976b330e 100644 --- a/proto/frequenz/api/common/v1/microgrid/sensors/sensors.proto +++ b/proto/frequenz/api/common/v1/microgrid/sensors/sensors.proto @@ -10,37 +10,36 @@ syntax = "proto3"; package frequenz.api.common.v1.microgrid.sensors; -import "frequenz/api/common/v1/metrics/metrics.proto"; +import "frequenz/api/common/v1/metrics/metric_sample.proto"; import "frequenz/api/common/v1/microgrid/lifetime.proto"; import "google/protobuf/timestamp.proto"; -// Enum to represent the various states that a sensor can be in. -// This enum is unified across all sensor categories for consistency. -enum SensorStateCode { - // Default value when the sensor state is not explicitly set. - // This is the zero value of the enum. - SENSOR_STATE_CODE_UNSPECIFIED = 0; +// Enumerated sensor categories. +enum SensorCategory { + // Unspecified + SENSOR_CATEGORY_UNSPECIFIED = 0; - // The sensor is up and running. - SENSOR_STATE_CODE_OK = 1; + // Thermometer (temperature sensor) + SENSOR_CATEGORY_THERMOMETER = 1; - // The sensor is in an error state. - SENSOR_STATE_CODE_ERROR = 2; -} + // Hygrometer (humidity sensor) + SENSOR_CATEGORY_HYGROMETER = 2; -// A representation of all possible warnings and errors that can occur in -// sensors. -enum SensorDiagnosticCode { - // Default value. No specific error is specified. - SENSOR_DIAGNOSTIC_CODE_UNSPECIFIED = 0; + // Barometer (pressure sensor). + SENSOR_CATEGORY_BAROMETER = 3; - // The sensor is reporting an unknown or an undefined error, and the sender - // cannot parse the sensor error to any of the variants below. - SENSOR_DIAGNOSTIC_CODE_UNKNOWN = 1; + // Pyranometer (solar irradiance sensor). + SENSOR_CATEGORY_PYRANOMETER = 4; - // Error indicating an internal error within the sensor. - SENSOR_DIAGNOSTIC_CODE_INTERNAL = 2; + // Anemometer (wind velocity and direction sensor). + SENSOR_CATEGORY_ANEMOMETER = 5; + + // Accelerometers (acceleration sensor). + SENSOR_CATEGORY_ACCELEROMETER = 6; + + // General sensors, which do not fall in any of the above categories + SENSOR_CATEGORY_GENERAL = 7; } // A sensor that measures a physical metric in the microgrid's surrounding @@ -55,6 +54,9 @@ message Sensor { // An optional name for the sensor. string name = 3; + // The category of the sensor. + SensorCategory category = 4; + // The sensor manufacturer. string manufacturer = 5; @@ -65,124 +67,147 @@ message Sensor { frequenz.api.common.v1.microgrid.Lifetime operational_lifetime = 7; } -// Represents an error or warning condition reported by a microgrid sensor. -// -// This message extends a standardized error code with contextual information -// useful for diagnostics, such as subsystem names, measured values, or -// vendor-specific insights. -// -// !!! example "Typical Sensor Error" -// ```json -// { -// "diagnosticCode": -// "SENSOR_DIAGNOSTIC_CODE_INTERNAL", -// "vendorErrorCode": "2003", -// "message": "Temperature sensor 3 reported 61.5°C (limit: 60°C)" -// } -// ``` -// !!! note "Vendor-Specific Codes" -// When available, `vendor_error_code` will reflect manufacturer-defined -// error identifiers, typically exposed via Modbus or similar interfaces. -// These codes are vendor- and firmware-specific and must be interpreted -// using the vendor's official documentation. -message SensorDiagnostic { - // A standardized error code representing the category of the issue. - SensorDiagnosticCode diagnostic_code = 1; - - // Optional vendor-provided diagnostic code for the error, for vendor-specific - // insights or more granular diagnostics. - optional string vendor_diagnostic_code = 2; - - // Optional human-readable message providing additional context. - string message = 3; -} +// Enumrated sensor metrics. +enum SensorMetric { + // Unspecified. + SENSOR_METRIC_UNSPECIFIED = 0; -// Representation of a sensor state and errors. -message SensorStateSnapshot { - // The UTC time when the state was originally captured. - google.protobuf.Timestamp origin_time = 1; + // Temperature. + // In Celsius (°C). + SENSOR_METRIC_TEMPERATURE = 1; - // List of states of the microgrid sensor. - // - // !!! note - // This list is treated as a set, and therefore its members will be unique, - // i.e., no state will exist twice in this list. - // - // !!! note - // If the state is `SENSOR_STATE_CODE_ERROR`, the sensor is in an error - // state. In such cases, the `errors` field will be populated with the - // list of errors. - repeated SensorStateCode states = 2; + // Humidity + // In percentage (%). + SENSOR_METRIC_HUMIDITY = 2; - // List of warnings for the microgrid sensor. - // - // !!! note - // This list is treated as a set, and therefore its members will be unique, - // i.e., no state will exist twice in this list. - // - // !!! note - // This list is expected to have warnings if and only if the sensor is - // reporting warnings. - repeated SensorDiagnostic warnings = 3; + // Pressure + // In Pascal (Pa). + SENSOR_METRIC_PRESSURE = 3; - // List of errors for the microgrid sensor. - // - // !!! note - // This list is treated as a set, and therefore its members will be unique, - // i.e., no state will exist twice in this list. + // Irradiance / Radiation flux + // In watts per square meter (W / m^2). + SENSOR_METRIC_IRRADIANCE = 4; + + // Velocity + // In meters per second (m / s). + SENSOR_METRIC_VELOCITY = 5; + + // Acceleration. + // In meters per second per second (m / s^2) + SENSOR_METRIC_ACCELERATION = 6; + + // Metric to represent angles, for metrics like direction. + // In angles with respect to the (magnetic) North (°). + SENSOR_METRIC_ANGLE = 7; + + // Dew point. + // The temperature at which the air becomes saturated with water vapor. // - // !!! note - // This list is expected to have errors if and only if the sensor is in - // an error state. - repeated SensorDiagnostic errors = 4; + // In Celsius (°C). + SENSOR_METRIC_DEW_POINT = 8; } -// SensorTelemetry message aggregates multiple metrics, operational states, and +// SensorData message aggregates multiple metrics, operational states, and // errors, related to a specific microgrid sensor. // // !!! example // Example output of a component data message: // ``` -// { +// { // sensor_id: 13, // metric_samples: [ // /* list of metrics for multiple timestamps */ // { -// sample_time: "2023-10-01T00:00:00Z", +// sampled_at: "2023-10-01T00:00:00Z", // metric: "METRIC_SENSOR_TEMPERATURE", // value: metric_value_variant: {simple_metric: {value: 23.5}, -// bounds: {} -// connection: {} // }, // { -// sample_time: "2023-10-01T00:00:00Z", +// sampled_at: "2023-10-01T00:00:00Z", // metric: "METRIC_SENSOR_RELATIVE_HUMIDITY", // value: metric_value_variant: {simple_metric: {value: 23.5}, -// bounds: {} -// connection: "humidity_sensor_1" // } // ], // states: [ // { -// sample_time: "2023-10-01T00:00:00Z", +// sampled_at: "2023-10-01T00:00:00Z", // states: [], // errors: [], // }, // ] -// } -// ``` -message SensorTelemetry { +// +// } +// ``` +message SensorData { // The ID of the microgrid sensors. uint64 sensor_id = 1; // List of measurements for a metric of the specific microgrid sensor. + repeated SensorMetricSample metric_samples = 2; + + // List of states of a specific microgrid sensor. + repeated SensorState states = 3; +} + +// Representation of a sensor state and errors. +message SensorState { + // The time at which the state was sampled. + google.protobuf.Timestamp sampled_at = 1; + + // List of states of the microgrid sensor. // - // Note that these metric samples will not necessarily contain bounds, since - // bounds are required for control operations, which are not applicable to - // sensors. - repeated frequenz.api.common.v1.metrics.MetricSample metric_samples = 2; + // !!! note + // The list will contain unique members. No state will exist twice in + // this list. + repeated SensorStateCode states = 2; - // List of state snapshots of a specific microgrid sensor. - repeated SensorStateSnapshot state_snapshots = 3; + // List of errors for the microgrid sensor. + // + // !!! note + // This list is expected to have errors if and only if the sensor is in + // an error state. + // + // !!! note + // The list will contain unique members. No error will exist twice in + // this list. + repeated SensorErrorCode errors = 4; } +// Enum to represent the various states that a sensor can be in. +// This enum is unified across all sensor categories for consistency. +enum SensorStateCode { + // Default value when the sensor state is not explicitly set. + // This is the zero value of the enum. + SENSOR_STATE_CODE_UNSPECIFIED = 0; + + // The sensor is up and running. + SENSOR_STATE_CODE_ON = 1; + + // The sensor is in an error state. + SENSOR_STATE_CODE_ERROR = 2; +} + +// A representation of all possible errors that can occur in sensors. +enum SensorErrorCode { + // Default value. No specific error is specified. + SENSOR_ERROR_CODE_UNSPECIFIED = 0; + + // The sensor is reporting an unknown or an undefined error, and the sender + // cannot parse the sensor error to any of the variants below. + SENSOR_ERROR_CODE_UNKNOWN = 1; + + // Error indicating an internal error within the sensor. + SENSOR_ERROR_CODE_INTERNAL = 2; +} + +// Representation of a sampled sensor metric along with its value. +message SensorMetricSample { + // The UTC timestamp of when the metric was sampled. + google.protobuf.Timestamp sampled_at = 1; + + // The metric that was sampled. + frequenz.api.common.v1.metrics.Metric metric = 2; + + // The value of the sampled metric. + frequenz.api.common.v1.metrics.MetricValueVariant value = 3; +} diff --git a/proto/frequenz/api/common/v1/type/decimal.proto b/proto/frequenz/api/common/v1/types/decimal.proto similarity index 95% rename from proto/frequenz/api/common/v1/type/decimal.proto rename to proto/frequenz/api/common/v1/types/decimal.proto index 4c69f7a0..455f926b 100644 --- a/proto/frequenz/api/common/v1/type/decimal.proto +++ b/proto/frequenz/api/common/v1/types/decimal.proto @@ -7,7 +7,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.type; +package frequenz.api.common.v1.types; // protolint:disable MAX_LINE_LENGTH // (the link is too long) diff --git a/proto/frequenz/api/common/v1alpha7/grid/delivery_area.proto b/proto/frequenz/api/common/v1alpha7/grid/delivery_area.proto new file mode 100644 index 00000000..82d85474 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/grid/delivery_area.proto @@ -0,0 +1,62 @@ +// Frequenz definitions of grids as entities participating in trading. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.grid; + +// CodeType specifies the type of identification code used for uniquely +// identifying various entities such as delivery areas, market participants, and +// grid components within the energy market. This enumeration aims to offer +// compatibility across different jurisdictional standards. +// +// !!! note "Understanding Code Types" +// Different regions or countries may have their own standards for uniquely +// identifying various entities within the energy market. For example, in +// Europe, the Energy Identification Code (EIC) is commonly used for this +// purpose. +// +// !!! info "Extensibility" +// New code types can be added to this enum to accommodate additional +// regional standards, enhancing the API's adaptability. +// +// !!! caution "Validation Required" +// The chosen code type should correspond correctly with the `code` field in +// the relevant message objects, such as `DeliveryArea` or `Counterparty`. +// Failure to match the code type with the correct code could lead to +// processing errors. +// +enum EnergyMarketCodeType { + // Unspecified type. This value is a placeholder and should not be used. + ENERGY_MARKET_CODE_TYPE_UNSPECIFIED = 0; + + // European Energy Identification Code Standard. + ENERGY_MARKET_CODE_TYPE_EUROPE_EIC = 1; + + // North American Electric Reliability Corporation identifiers. + ENERGY_MARKET_CODE_TYPE_US_NERC = 2; +} + +// DeliveryArea represents the geographical or administrative region, usually +// defined and maintained by a Transmission System Operator (TSO), where +// electricity deliveries for a contract occur. +// +// The concept is important to energy trading as it delineates the agreed-upon +// delivery location. Delivery areas can have different codes based on the// +// jurisdiction in which they operate. +// +// !!! note "Jurisdictional Differences" +// This is typically represented by specific codes according to local +// jurisdiction. In Europe, this is represented by an EIC +// (Energy Identification Code). +message DeliveryArea { + // Code representing the unique identifier for the delivery area. + string code = 1; + + // Type of code used for identifying the delivery area itself. + EnergyMarketCodeType code_type = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/grid/delivery_duration.proto b/proto/frequenz/api/common/v1alpha7/grid/delivery_duration.proto new file mode 100644 index 00000000..d86143e1 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/grid/delivery_duration.proto @@ -0,0 +1,61 @@ +// Frequenz definitions of the time increment used for electricity +// deliveries and trading. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.grid; + +import "google/protobuf/timestamp.proto"; + +// DeliveryDuration represents the time increment, in minutes, +// used for electricity deliveries and trading. These durations +// serve as the basis for defining the delivery period in contracts, +// and they dictate how energy is scheduled and delivered to meet +// contractual obligations. +// +// !!! note "Compatibility Constraints" +// Not all delivery durations are universally +// compatible with all delivery areas or markets. +// +enum DeliveryDuration { + // Default value, indicates that the duration is unspecified. + DELIVERY_DURATION_UNSPECIFIED = 0; + + // 5-minute duration + DELIVERY_DURATION_5 = 1; + + // 15-minute contract duration. + DELIVERY_DURATION_15 = 2; + + // 30-minute contract duration. + DELIVERY_DURATION_30 = 3; + + // 1-hour contract duration. + DELIVERY_DURATION_60 = 4; +} + +// DeliveryPeriod represents the time period during which the contract +// is delivered. It is defined by a start timestamp and a duration. +message DeliveryPeriod { + // Start UTC timestamp represents the beginning of the delivery period. + // This timestamp is inclusive, meaning that the delivery period starts + // from this point in time. + // + // !!! note + // Delivery period start time constraints: + // - 5-minute durations must start at times that are multiples of + // 5 minutes past the hour. + // - 15-minute durations must start at :00, :15, :30, or + // :45 past the hour. + // - 30-minute durations must start at :00 or :30 past the hour. + // - 60-minute durations must start at :00 past the hour. + google.protobuf.Timestamp start = 1; + + // The length of the delivery period. + DeliveryDuration duration = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/market/energy.proto b/proto/frequenz/api/common/v1alpha7/market/energy.proto new file mode 100644 index 00000000..0390bbfb --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/market/energy.proto @@ -0,0 +1,24 @@ +// Frequenz definitions of energy. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.market; + +import "frequenz/api/common/v1alpha7/type/decimal.proto"; + +// Represents a single unit of electricity. +// +// !!! note +// The unit of energy is denominated in MWh, which is a unit of energy +// representing total output over a period.(Megawatt-hours). This differs +// from MW (Megawatts), a unit of power representing the rate of energy +// production or consumption. +message Energy { + // Energy unit in Megawatthours (MWh). + frequenz.api.common.v1alpha7.type.Decimal mwh = 1; +} diff --git a/proto/frequenz/api/common/v1alpha7/market/power.proto b/proto/frequenz/api/common/v1alpha7/market/power.proto new file mode 100644 index 00000000..7047970a --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/market/power.proto @@ -0,0 +1,30 @@ +// Frequenz definitions of power. +// +// Copyright 2024 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.market; + +import "frequenz/api/common/v1alpha7/type/decimal.proto"; + +// Represents a single unit of power. +// +// !!! note +// The power unit is denominated in MW (Megawatts), which is a unit of +// power representing the rate of energy production or consumption at any +// given moment. This differs from MWh (Megawatt-hours), which measures +// the total amount of energy delivered or consumed over a period. +// +// Example: +// A power plant running at 10 MW for 1 hour generates 10 MWh of energy. +// +// This message standardizes the representation of power in MW across all +// market applications. +message Power { + // Power amount in Megawatts (MW). + frequenz.api.common.v1alpha7.type.Decimal mw = 1; +} diff --git a/proto/frequenz/api/common/v1alpha7/market/price.proto b/proto/frequenz/api/common/v1alpha7/market/price.proto new file mode 100644 index 00000000..f4269eb8 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/market/price.proto @@ -0,0 +1,53 @@ +// Frequenz definitions of price for electricity trading. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.market; + +import "frequenz/api/common/v1alpha7/type/decimal.proto"; + +// Represents a monetary price for electricity trading, including +// the amount and currency. The currency used should align with the +// delivery area's standard currency. +// +// !!! caution "Validation Required" +// It's essential to ensure that the currency aligns with the +// standard currency of the associated delivery area. Failure to +// do so may result in the API service rejecting the request due to currency +// mismatches. +// +// !!! info "Relation to Delivery Area" +// The currency specified is intrinsically related to the delivery area +// for the contract. Make sure the chosen currency is compatible with +// the delivery area's currency standards. +// +message Price { + // List of supported currencies. + // + // !!! info "Extensibility" + // New currencies can be added to this enum to support additional markets. + enum Currency { + CURRENCY_UNSPECIFIED = 0; + CURRENCY_USD = 1; + CURRENCY_CAD = 2; + CURRENCY_EUR = 3; + CURRENCY_GBP = 4; + CURRENCY_CHF = 5; + CURRENCY_CNY = 6; + CURRENCY_JPY = 7; + CURRENCY_AUD = 8; + CURRENCY_NZD = 9; + CURRENCY_SGD = 10; + } + + // The amount of the price. + frequenz.api.common.v1alpha7.type.Decimal amount = 1; + + // The currency in which the price is denominated. + Currency currency = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/metrics/bounds.proto b/proto/frequenz/api/common/v1alpha7/metrics/bounds.proto new file mode 100644 index 00000000..45c8c85f --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/metrics/bounds.proto @@ -0,0 +1,23 @@ +// Definitions for bounds. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.metrics; + +// A set of lower and upper bounds for any metric. +// The units of the bounds are always the same as the related metric. +message Bounds { + // The lower bound. + // If absent, there is no lower bound. + optional float lower = 1; + + // The upper bound. + // If absent, there is no upper bound. + optional float upper = 2; +} diff --git a/proto/frequenz/api/common/v1/metrics/metrics.proto b/proto/frequenz/api/common/v1alpha7/metrics/metrics.proto similarity index 99% rename from proto/frequenz/api/common/v1/metrics/metrics.proto rename to proto/frequenz/api/common/v1alpha7/metrics/metrics.proto index 41ffdbe4..5fa2e31f 100644 --- a/proto/frequenz/api/common/v1/metrics/metrics.proto +++ b/proto/frequenz/api/common/v1alpha7/metrics/metrics.proto @@ -8,9 +8,9 @@ syntax = "proto3"; -package frequenz.api.common.v1.metrics; +package frequenz.api.common.v1alpha7.metrics; -import "frequenz/api/common/v1/metrics/bounds.proto"; +import "frequenz/api/common/v1alpha7/metrics/bounds.proto"; import "google/protobuf/timestamp.proto"; diff --git a/proto/frequenz/api/common/v1/microgrid/communication_components/communication_components.proto b/proto/frequenz/api/common/v1alpha7/microgrid/communication_components/communication_components.proto similarity index 99% rename from proto/frequenz/api/common/v1/microgrid/communication_components/communication_components.proto rename to proto/frequenz/api/common/v1alpha7/microgrid/communication_components/communication_components.proto index 826c0f24..5593f71d 100644 --- a/proto/frequenz/api/common/v1/microgrid/communication_components/communication_components.proto +++ b/proto/frequenz/api/common/v1alpha7/microgrid/communication_components/communication_components.proto @@ -10,7 +10,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.communication_components; +package frequenz.api.common.v1alpha7.microgrid.communication_components; import "google/protobuf/timestamp.proto"; diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/battery.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/battery.proto new file mode 100644 index 00000000..d5a46c84 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/battery.proto @@ -0,0 +1,29 @@ +// Frequenz definitions for batteries. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.electrical_components; + +// Enumerated battery types. +enum BatteryType { + // Unspecified. + BATTERY_TYPE_UNSPECIFIED = 0; + + // Li-ion batteries. + BATTERY_TYPE_LI_ION = 1; + + // Sodium-ion batteries + BATTERY_TYPE_NA_ION = 2; +} + +// A representation of a battery. +message Battery { + // The battery type. + BatteryType type = 1; +} diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/electrical_components.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/electrical_components.proto similarity index 92% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/electrical_components.proto rename to proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/electrical_components.proto index 2cd13f81..7674a439 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/electrical_components.proto +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/electrical_components.proto @@ -6,21 +6,22 @@ // License: // MIT +// protolint:disable MAX_LINE_LENGTH syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1alpha7.microgrid.electrical_components; -import "frequenz/api/common/v1/metrics/bounds.proto"; -import "frequenz/api/common/v1/metrics/metrics.proto"; -import "frequenz/api/common/v1/microgrid/electrical_components/battery.proto"; +import "frequenz/api/common/v1alpha7/metrics/bounds.proto"; +import "frequenz/api/common/v1alpha7/metrics/metrics.proto"; +import "frequenz/api/common/v1alpha7/microgrid/electrical_components/battery.proto"; import - "frequenz/api/common/v1/microgrid/electrical_components/ev_charger.proto"; -import "frequenz/api/common/v1/microgrid/electrical_components/fuse.proto"; -import "frequenz/api/common/v1/microgrid/electrical_components/grid.proto"; -import "frequenz/api/common/v1/microgrid/electrical_components/inverter.proto"; + "frequenz/api/common/v1alpha7/microgrid/electrical_components/ev_charger.proto"; +import "frequenz/api/common/v1alpha7/microgrid/electrical_components/fuse.proto"; +import "frequenz/api/common/v1alpha7/microgrid/electrical_components/grid.proto"; +import "frequenz/api/common/v1alpha7/microgrid/electrical_components/inverter.proto"; import - "frequenz/api/common/v1/microgrid/electrical_components/transformer.proto"; -import "frequenz/api/common/v1/microgrid/lifetime.proto"; + "frequenz/api/common/v1alpha7/microgrid/electrical_components/transformer.proto"; +import "frequenz/api/common/v1alpha7/microgrid/lifetime.proto"; import "google/protobuf/timestamp.proto"; @@ -359,28 +360,28 @@ enum ElectricalComponentDiagnosticCode { // for a component. message MetricConfigBounds { // Metric type the config bounds are for - frequenz.api.common.v1.metrics.Metric metric = 1; + frequenz.api.common.v1alpha7.metrics.Metric metric = 1; // The set of bounds for the specified metric. // // This contains the lower and upper bounds for said metric. // Sources these may be derived from include the component configuration, // manufacturers limits, and limits of other devices. - frequenz.api.common.v1.metrics.Bounds config_bounds = 2; + frequenz.api.common.v1alpha7.metrics.Bounds config_bounds = 2; } // Metadata specific to a microgrid component. message ElectricalComponentCategorySpecificInfo { oneof kind { - frequenz.api.common.v1.microgrid.electrical_components.Battery battery = 1; - frequenz.api.common.v1.microgrid.electrical_components.EvCharger + frequenz.api.common.v1alpha7.microgrid.electrical_components.Battery battery = 1; + frequenz.api.common.v1alpha7.microgrid.electrical_components.EvCharger ev_charger = 2; - frequenz.api.common.v1.microgrid.electrical_components.Fuse fuse = 3; - frequenz.api.common.v1.microgrid.electrical_components.GridConnectionPoint + frequenz.api.common.v1alpha7.microgrid.electrical_components.Fuse fuse = 3; + frequenz.api.common.v1alpha7.microgrid.electrical_components.GridConnectionPoint grid_connection_point = 4; - frequenz.api.common.v1.microgrid.electrical_components.Inverter + frequenz.api.common.v1alpha7.microgrid.electrical_components.Inverter inverter = 5; - frequenz.api.common.v1.microgrid.electrical_components.VoltageTransformer + frequenz.api.common.v1alpha7.microgrid.electrical_components.VoltageTransformer voltage_transformer = 6; } } @@ -409,7 +410,7 @@ message ElectricalComponent { string model_name = 7; // The operational lifetime of the component. - frequenz.api.common.v1.microgrid.Lifetime operational_lifetime = 8; + frequenz.api.common.v1alpha7.microgrid.Lifetime operational_lifetime = 8; // List of rated bounds present for the component identified by Metric. repeated MetricConfigBounds metric_config_bounds = 9; @@ -449,7 +450,7 @@ message ElectricalComponentConnection { uint64 destination_component_id = 2; // The operational lifetime of the connection. - frequenz.api.common.v1.microgrid.Lifetime operational_lifetime = 3; + frequenz.api.common.v1alpha7.microgrid.Lifetime operational_lifetime = 3; } // Represents an error or warning condition reported by a microgrid electrical @@ -578,7 +579,7 @@ message ElectricalComponentTelemetry { uint64 component_id = 1; // List of measurements for a metric of the specific microgrid component. - repeated frequenz.api.common.v1.metrics.MetricSample metric_samples = 2; + repeated frequenz.api.common.v1alpha7.metrics.MetricSample metric_samples = 2; // List of state snapshots of a specific microgrid component. repeated ElectricalComponentStateSnapshot state_snapshots = 3; diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/ev_charger.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/ev_charger.proto new file mode 100644 index 00000000..9f5e7e7f --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/ev_charger.proto @@ -0,0 +1,32 @@ +// Frequenz definitions for EV chargers. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.electrical_components; + +// Enumerated EV charger types. +enum EvChargerType { + // Default type. + EV_CHARGER_TYPE_UNSPECIFIED = 0; + + // The EV charging station supports AC charging only. + EV_CHARGER_TYPE_AC = 1; + + // The EV charging station supports DC charging only. + EV_CHARGER_TYPE_DC = 2; + + // The EV charging station supports both AC and DC. + EV_CHARGER_TYPE_HYBRID = 3; +} + +// A representation of an EV chaging station. +message EvCharger { + // The EV charger type. + EvChargerType type = 1; +} diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/fuse.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/fuse.proto new file mode 100644 index 00000000..f3e17db8 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/fuse.proto @@ -0,0 +1,26 @@ +// Frequenz definitions for electrical fuses. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.electrical_components; + +// A representation of a fuse. +// The fuse component represents a fuse in the microgrid. It is used to protect +// components from overcurrents. +message Fuse { + // The rated current of the fuse in amperes. + // This is the maximum current that the fuse can withstand for a long time. + // This limit applies to currents both flowing in or out of each of the 3 + // phases individually. + // + // In other words, a current _i_ A at one of the phases of the node must + // comply with the following constraint: + // `-rated_fuse_current <= i <= rated_fuse_current` + uint32 rated_current = 1; +} diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/grid.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/grid.proto new file mode 100644 index 00000000..c17be5d8 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/grid.proto @@ -0,0 +1,46 @@ +// Frequenz definitions for grid connection points. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.electrical_components; + +// A representation of a grid connection point. This is the point where a +// microgrid connects to the grid. +// +// The terms "Grid Connection Point" and "Point of Common Coupling" (PCC) are +// commonly used in the context. +// +// While both terms describe a connection point to the grid, the +// `GridConnectionPoint` is specifically the physical connection point of the +// generation facility to the grid, often concerned with the technical and +// ownership aspects of the connection. +// +// In contrast, the PCC is is more specific in terms of electrical engineering. +// It refers to the point where a customer's local electrical system (such as a +// microgrid) connects to the utility distribution grid in such a way that it +// can affect other customers’ systems connected to the same network. It is the +// point where the grid and customer's electrical systems interface and where +// issues like power quality and supply regulations are assessed. +// +// The term `GridConnectionPoint` is used to make it clear that what is referred +// to here is the physical connection point of the local facility to the grid. +// Note that this may also be the PCC in some cases. +message GridConnectionPoint { + // This refers to the maximum amount of electrical current, in amperes, that a + // fuse at the grid connection point is designed to safely carry under normal + // operating conditions. + // + // This limit applies to currents both flowing in or out of each of the 3 + // phases individually. + // + // In other words, a current _i_ A at one of the phases of the grid connection + // point must comply with the following constraint: + // `-rated_fuse_current <= i <= rated_fuse_current` + uint32 rated_fuse_current = 1; +} diff --git a/proto/frequenz/api/common/v1/microgrid/electrical_components/inverter.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/inverter.proto similarity index 89% rename from proto/frequenz/api/common/v1/microgrid/electrical_components/inverter.proto rename to proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/inverter.proto index 9d049969..9e2ddf3d 100644 --- a/proto/frequenz/api/common/v1/microgrid/electrical_components/inverter.proto +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/inverter.proto @@ -8,7 +8,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.microgrid.electrical_components; +package frequenz.api.common.v1alpha7.microgrid.electrical_components; // Enumerated inverter types. enum InverterType { diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/transformer.proto b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/transformer.proto new file mode 100644 index 00000000..c06f0d90 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/electrical_components/transformer.proto @@ -0,0 +1,28 @@ +// Frequenz definitions for transformers. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.electrical_components; + +// A representation of a voltage transformer. +// Voltage transformers are used to step up or step down the voltage, keeping +// the power somewhat constant by increasing or decreasing the current. +// If voltage is stepped up, current is stepped down, and vice versa. +// Note that voltage transformers have efficiency losses, so the output power +// is always less than the input power. +message VoltageTransformer { + // The primary voltage of the transformer. + // This is the input voltage that is stepped up or down. + float primary = 1; + + // The secondary voltage of the transformer. + // This is the output voltage that is the result of stepping the primary + // voltage up or down. + float secondary = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/lifetime.proto b/proto/frequenz/api/common/v1alpha7/microgrid/lifetime.proto new file mode 100644 index 00000000..6119f069 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/lifetime.proto @@ -0,0 +1,41 @@ +// Frequenz definition of entity lifetimes, based upon start and end timestamps. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid; + +import "google/protobuf/timestamp.proto"; + +// Lifetime captures the timestamps indicating the active operational period of +// a microgrid asset, such as a component, connection, sensor, or any other +// entity with a limited operational lifetime. +// +// It is normally used to track the historical evolution of assets, and it +// determines the validity period for the asset's data. +// +// If the `start_timestamp` is not set, the asset is considered to be in +// operation since the beginning of the system's operational history. +// +// If the `end_timestamp` is not set, the asset is considered to be in +// operation indefinitely into the future. +// +// If the Lifetime message is completely missing, it means both timestamps are +// not set, which means the asset is considered to be in operation since the +// beginning of the system's operational history and indefinitely into the +// future. +message Lifetime { + // The timestamp when the asset became operationally active. + // If not set, the asset is considered to be in operation since the beginning + // of the system's operational history. + google.protobuf.Timestamp start_timestamp = 1; + + // Optional timestamp when the asset's operational activity ceased. + // If not set, the asset is considered to be in operation indefinitely into + // the future. + google.protobuf.Timestamp end_timestamp = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/microgrid.proto b/proto/frequenz/api/common/v1alpha7/microgrid/microgrid.proto new file mode 100644 index 00000000..33f7e03a --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/microgrid.proto @@ -0,0 +1,88 @@ +// Frequenz microgrid definition. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid; + +import "frequenz/api/common/v1alpha7/grid/delivery_area.proto"; +import "frequenz/api/common/v1alpha7/type/location.proto"; + +import "google/protobuf/timestamp.proto"; + +// MicrogridStatus defines the possible statuses for a microgrid. +enum MicrogridStatus { + // The status is unspecified. This should not be used. + MICROGRID_STATUS_UNSPECIFIED = 0; + + // The microgrid is active. + MICROGRID_STATUS_ACTIVE = 1; + + // The microgrid is inactive. + MICROGRID_STATUS_INACTIVE = 2; +} + +// Microgrid contains details of a specific microgrid. A microgrid is a +// localized grouping of electricity generation, energy storage, and loads that +// normally operates connected to a traditional centralized grid. Each microgrid +// has a unique identifier and is associated with an enterprise account. A key +// feature is that it has a physical location and is situated in a delivery +// area. +// +// !!! info "Key Concepts" +// - `Physical Location`: Geographical coordinates specify the exact +// physical location of the microgrid. +// - `Delivery Area`: Each microgrid is part of a broader delivery area, +// which is crucial for energy trading and compliance. +// +message Microgrid { + // Unique identifier of the microgrid. + uint64 id = 1; + + // Unique identifier linking this microgrid to its parent enterprise account. + uint64 enterprise_id = 2; + + // Name of the microgrid. + string name = 3; + + // The delivery area where the microgrid is located, as identified by a + // specific code. + // + // If a microgrid is not connected to the grid (it is an island) it does not + // belong to any delivery area and this field will be missing, but it could + // be missing for other reasons as well. + frequenz.api.common.v1alpha7.grid.DeliveryArea delivery_area = 4; + + // Physical location of the microgrid, in geographical co-ordinates. + // + // If the location is not known, this field will be missing. + frequenz.api.common.v1alpha7.type.Location location = 5; + + // The current status of the microgrid. + MicrogridStatus status = 6; + + // The UTC timestamp indicating when the microgrid was initially created. + google.protobuf.Timestamp create_timestamp = 7; +} + +// A message to link component IDs with their respective microgrid ID. +message MicrogridComponentIDs { + // The ID of the microgrid. + uint64 microgrid_id = 1; + + // List of component IDs belonging to this microgrid. + repeated uint64 component_ids = 2; +} + +/// A message to link sensor IDs with their respective microgrid ID. +message MicrogridSensorIDs { + // The ID of the microgrid. + uint64 microgrid_id = 1; + + // List of sensor IDs belonging to this microgrid. + repeated uint64 sensor_ids = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/microgrid/sensors/sensors.proto b/proto/frequenz/api/common/v1alpha7/microgrid/sensors/sensors.proto new file mode 100644 index 00000000..cba1fb4c --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/microgrid/sensors/sensors.proto @@ -0,0 +1,188 @@ +// Frequenz microgrid sensor definitions. +// +// Copyright: +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// License: +// MIT + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.microgrid.sensors; + +import "frequenz/api/common/v1alpha7/metrics/metrics.proto"; +import "frequenz/api/common/v1alpha7/microgrid/lifetime.proto"; + +import "google/protobuf/timestamp.proto"; + +// Enum to represent the various states that a sensor can be in. +// This enum is unified across all sensor categories for consistency. +enum SensorStateCode { + // Default value when the sensor state is not explicitly set. + // This is the zero value of the enum. + SENSOR_STATE_CODE_UNSPECIFIED = 0; + + // The sensor is up and running. + SENSOR_STATE_CODE_OK = 1; + + // The sensor is in an error state. + SENSOR_STATE_CODE_ERROR = 2; +} + +// A representation of all possible warnings and errors that can occur in +// sensors. +enum SensorDiagnosticCode { + // Default value. No specific error is specified. + SENSOR_DIAGNOSTIC_CODE_UNSPECIFIED = 0; + + // The sensor is reporting an unknown or an undefined error, and the sender + // cannot parse the sensor error to any of the variants below. + SENSOR_DIAGNOSTIC_CODE_UNKNOWN = 1; + + // Error indicating an internal error within the sensor. + SENSOR_DIAGNOSTIC_CODE_INTERNAL = 2; +} + +// A sensor that measures a physical metric in the microgrid's surrounding +// environment. +message Sensor { + // A unique identifier for the sensor. + uint64 id = 1; + + // Unique identifier of the parent microgrid_id. + uint64 microgrid_id = 2; + + // An optional name for the sensor. + string name = 3; + + // The sensor manufacturer. + string manufacturer = 5; + + // The model name of the sensor. + string model_name = 6; + + // The operational lifetime of the sensor. + frequenz.api.common.v1alpha7.microgrid.Lifetime operational_lifetime = 7; +} + +// Represents an error or warning condition reported by a microgrid sensor. +// +// This message extends a standardized error code with contextual information +// useful for diagnostics, such as subsystem names, measured values, or +// vendor-specific insights. +// +// !!! example "Typical Sensor Error" +// ```json +// { +// "diagnosticCode": +// "SENSOR_DIAGNOSTIC_CODE_INTERNAL", +// "vendorErrorCode": "2003", +// "message": "Temperature sensor 3 reported 61.5°C (limit: 60°C)" +// } +// ``` +// !!! note "Vendor-Specific Codes" +// When available, `vendor_error_code` will reflect manufacturer-defined +// error identifiers, typically exposed via Modbus or similar interfaces. +// These codes are vendor- and firmware-specific and must be interpreted +// using the vendor's official documentation. +message SensorDiagnostic { + // A standardized error code representing the category of the issue. + SensorDiagnosticCode diagnostic_code = 1; + + // Optional vendor-provided diagnostic code for the error, for vendor-specific + // insights or more granular diagnostics. + optional string vendor_diagnostic_code = 2; + + // Optional human-readable message providing additional context. + string message = 3; +} + +// Representation of a sensor state and errors. +message SensorStateSnapshot { + // The UTC time when the state was originally captured. + google.protobuf.Timestamp origin_time = 1; + + // List of states of the microgrid sensor. + // + // !!! note + // This list is treated as a set, and therefore its members will be unique, + // i.e., no state will exist twice in this list. + // + // !!! note + // If the state is `SENSOR_STATE_CODE_ERROR`, the sensor is in an error + // state. In such cases, the `errors` field will be populated with the + // list of errors. + repeated SensorStateCode states = 2; + + // List of warnings for the microgrid sensor. + // + // !!! note + // This list is treated as a set, and therefore its members will be unique, + // i.e., no state will exist twice in this list. + // + // !!! note + // This list is expected to have warnings if and only if the sensor is + // reporting warnings. + repeated SensorDiagnostic warnings = 3; + + // List of errors for the microgrid sensor. + // + // !!! note + // This list is treated as a set, and therefore its members will be unique, + // i.e., no state will exist twice in this list. + // + // !!! note + // This list is expected to have errors if and only if the sensor is in + // an error state. + repeated SensorDiagnostic errors = 4; +} + +// SensorTelemetry message aggregates multiple metrics, operational states, and +// errors, related to a specific microgrid sensor. +// +// !!! example +// Example output of a component data message: +// ``` +// { +// sensor_id: 13, +// metric_samples: [ +// /* list of metrics for multiple timestamps */ +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "METRIC_SENSOR_TEMPERATURE", +// value: metric_value_variant: {simple_metric: {value: 23.5}, +// bounds: {} +// connection: {} +// }, +// { +// sample_time: "2023-10-01T00:00:00Z", +// metric: "METRIC_SENSOR_RELATIVE_HUMIDITY", +// value: metric_value_variant: {simple_metric: {value: 23.5}, +// bounds: {} +// connection: "humidity_sensor_1" +// } +// ], +// states: [ +// { +// sample_time: "2023-10-01T00:00:00Z", +// states: [], +// errors: [], +// }, +// ] +// } +// ``` +message SensorTelemetry { + // The ID of the microgrid sensors. + uint64 sensor_id = 1; + + // List of measurements for a metric of the specific microgrid sensor. + // + // Note that these metric samples will not necessarily contain bounds, since + // bounds are required for control operations, which are not applicable to + // sensors. + repeated frequenz.api.common.v1alpha7.metrics.MetricSample metric_samples = 2; + + // List of state snapshots of a specific microgrid sensor. + repeated SensorStateSnapshot state_snapshots = 3; +} + diff --git a/proto/frequenz/api/common/v1alpha7/pagination/pagination_info.proto b/proto/frequenz/api/common/v1alpha7/pagination/pagination_info.proto new file mode 100644 index 00000000..e7a588ca --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/pagination/pagination_info.proto @@ -0,0 +1,27 @@ +// Parameters for pagination. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.pagination; + +// A message providing metadata about paginated list results. +// The PaginationInfo message delivers metadata concerning the paginated list +// results and should be appended to the response message of a list request. The +// total_items field must be set to the total count of items that adhere to the +// filter criteria defined in the request. The next_page_token field should be +// populated with the token to be used in the subsequent request to fetch the +// next page of results. If there are no additional results, the next_page_token +// field should be omitted. +message PaginationInfo { + // The total number of items that match the filter criteria defined in the + // request. + uint32 total_items = 1; + + // Token for retrieving the next set of results. + optional string next_page_token = 2; +} diff --git a/proto/frequenz/api/common/v1alpha7/pagination/pagination_params.proto b/proto/frequenz/api/common/v1alpha7/pagination/pagination_params.proto new file mode 100644 index 00000000..b780fbd5 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/pagination/pagination_params.proto @@ -0,0 +1,31 @@ +// Parameters for pagination. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.pagination; + +// A message defining parameters for paginating list requests. +// It can be appended to a request message to specify the desired page of +// results and the maximum number of results per page. +message PaginationParams { + oneof params { + // The maximum number of results to return in a single page. The service may + // return fewer results than requested. If unspecified, the service may + // choose a reasonable default. + // May only be specified in the first request. + uint32 page_size = 1; + + // A token identifying a page of results to return. This should be the value + // of the `next_page_token` field in the previous response's PaginationInfo. + // For the first request, this field should be omitted. + // + // To avoid keeping remembering the page_size across requests, service + // implementations may choose to encode the page_size in the page_token. + string page_token = 2; + } +} diff --git a/proto/frequenz/api/common/v1/streaming/event.proto b/proto/frequenz/api/common/v1alpha7/streaming/event.proto similarity index 92% rename from proto/frequenz/api/common/v1/streaming/event.proto rename to proto/frequenz/api/common/v1alpha7/streaming/event.proto index 8f420a24..6b7af11e 100644 --- a/proto/frequenz/api/common/v1/streaming/event.proto +++ b/proto/frequenz/api/common/v1alpha7/streaming/event.proto @@ -7,7 +7,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.streaming; +package frequenz.api.common.v1alpha7.streaming; // This enum message is used to inform receivers of events what kind of // event they just received diff --git a/proto/frequenz/api/common/v1alpha7/type/decimal.proto b/proto/frequenz/api/common/v1alpha7/type/decimal.proto new file mode 100644 index 00000000..e2a18215 --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/type/decimal.proto @@ -0,0 +1,25 @@ +// An arbitrary precision real number. +// +// Copyright 2024 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.type; + +// protolint:disable MAX_LINE_LENGTH +// (the link is too long) + +// An arbitrary precision real number. +// +// This message is based (and compatible) with Google's `google.type.Decimal` +// present in: https://github.com/googleapis/googleapis/ +// You should read the documentation there and follow all the guidelines (which +// are many, so please go and read the docs in: +// https://github.com/googleapis/googleapis/blob/master/google/type/decimal.proto) +message Decimal { + // The string representation of the `Decimal` value. + string value = 1; +} diff --git a/proto/frequenz/api/common/v1/type/interval.proto b/proto/frequenz/api/common/v1alpha7/type/interval.proto similarity index 95% rename from proto/frequenz/api/common/v1/type/interval.proto rename to proto/frequenz/api/common/v1alpha7/type/interval.proto index e0669316..daadb8d5 100644 --- a/proto/frequenz/api/common/v1/type/interval.proto +++ b/proto/frequenz/api/common/v1alpha7/type/interval.proto @@ -7,7 +7,7 @@ syntax = "proto3"; -package frequenz.api.common.v1.type; +package frequenz.api.common.v1alpha7.type; import "google/protobuf/timestamp.proto"; diff --git a/proto/frequenz/api/common/v1alpha7/type/location.proto b/proto/frequenz/api/common/v1alpha7/type/location.proto new file mode 100644 index 00000000..b267be5c --- /dev/null +++ b/proto/frequenz/api/common/v1alpha7/type/location.proto @@ -0,0 +1,22 @@ +// Geographical co-ordinates of a place. +// +// Copyright 2023 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1alpha7.type; + +// A pair of geographical co-ordinates, representing the location of a place. +message Location { + // Latitude ranges from -90 (South) to 90 (North) + float latitude = 1; + + // Longitude ranges from -180 (West) to 180 (East) + float longitude = 2; + + // Country ISO 3166-1 Alpha 2 + string country_code = 3; +} diff --git a/py/frequenz/api/common/__init__.py b/py/frequenz/api/common/__init__.py index e423855c..6e2c2a7c 100644 --- a/py/frequenz/api/common/__init__.py +++ b/py/frequenz/api/common/__init__.py @@ -1,7 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz common gRPC API and bindings. - -TODO(cookiecutter): Add a more descriptive module description. -""" +"""Frequenz common gRPC API and bindings.""" diff --git a/py/frequenz/api/common/metrics/__init__.py b/py/frequenz/api/common/metrics/__init__.py index 8301a69d..88181a4e 100644 --- a/py/frequenz/api/common/metrics/__init__.py +++ b/py/frequenz/api/common/metrics/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz Common API definitions for metrics.""" +"""Metrics bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/__init__.py b/py/frequenz/api/common/v1/__init__.py index 6e2c2a7c..2d5b78dc 100644 --- a/py/frequenz/api/common/v1/__init__.py +++ b/py/frequenz/api/common/v1/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz common gRPC API and bindings.""" +"""Frequenz common gRPC API and bindings for v1.""" diff --git a/py/frequenz/api/common/v1/grid/__init__.py b/py/frequenz/api/common/v1/grid/__init__.py index e69de29b..f778f7c3 100644 --- a/py/frequenz/api/common/v1/grid/__init__.py +++ b/py/frequenz/api/common/v1/grid/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2023 Frequenz Energy-as-a-Service GmbH + +"""Grid bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/market/__init__.py b/py/frequenz/api/common/v1/market/__init__.py index 6e2c2a7c..c78a7842 100644 --- a/py/frequenz/api/common/v1/market/__init__.py +++ b/py/frequenz/api/common/v1/market/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz common gRPC API and bindings.""" +"""Market bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/metrics/__init__.py b/py/frequenz/api/common/v1/metrics/__init__.py index 8301a69d..88181a4e 100644 --- a/py/frequenz/api/common/v1/metrics/__init__.py +++ b/py/frequenz/api/common/v1/metrics/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz Common API definitions for metrics.""" +"""Metrics bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/microgrid/__init__.py b/py/frequenz/api/common/v1/microgrid/__init__.py index e69de29b..110a2a37 100644 --- a/py/frequenz/api/common/v1/microgrid/__init__.py +++ b/py/frequenz/api/common/v1/microgrid/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2023 Frequenz Energy-as-a-Service GmbH + +"""Microgrid bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/microgrid/communication_components/__init__.py b/py/frequenz/api/common/v1/microgrid/communication_components/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/py/frequenz/api/common/v1/microgrid/components/__init__.py b/py/frequenz/api/common/v1/microgrid/components/__init__.py new file mode 100644 index 00000000..390b3405 --- /dev/null +++ b/py/frequenz/api/common/v1/microgrid/components/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2023 Frequenz Energy-as-a-Service GmbH + +"""Components bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/microgrid/electrical_components/__init__.py b/py/frequenz/api/common/v1/microgrid/electrical_components/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/py/frequenz/api/common/v1/microgrid/sensors/__init__.py b/py/frequenz/api/common/v1/microgrid/sensors/__init__.py index e69de29b..988cff47 100644 --- a/py/frequenz/api/common/v1/microgrid/sensors/__init__.py +++ b/py/frequenz/api/common/v1/microgrid/sensors/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2023 Frequenz Energy-as-a-Service GmbH + +"""Sensors bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/pagination/__init__.py b/py/frequenz/api/common/v1/pagination/__init__.py index 6e2c2a7c..1f73775e 100644 --- a/py/frequenz/api/common/v1/pagination/__init__.py +++ b/py/frequenz/api/common/v1/pagination/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz common gRPC API and bindings.""" +"""Pagination bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1/type/__init__.py b/py/frequenz/api/common/v1/type/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/py/frequenz/api/common/v1/streaming/__init__.py b/py/frequenz/api/common/v1/types/__init__.py similarity index 57% rename from py/frequenz/api/common/v1/streaming/__init__.py rename to py/frequenz/api/common/v1/types/__init__.py index 6e2c2a7c..fcde7c31 100644 --- a/py/frequenz/api/common/v1/streaming/__init__.py +++ b/py/frequenz/api/common/v1/types/__init__.py @@ -1,4 +1,4 @@ # License: MIT # Copyright © 2023 Frequenz Energy-as-a-Service GmbH -"""Frequenz common gRPC API and bindings.""" +"""Types bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/__init__.py b/py/frequenz/api/common/v1alpha7/__init__.py new file mode 100644 index 00000000..79fee0df --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Frequenz common gRPC API and bindings for v1alpha7.""" diff --git a/py/frequenz/api/common/v1alpha7/grid/__init__.py b/py/frequenz/api/common/v1alpha7/grid/__init__.py new file mode 100644 index 00000000..a0dfa523 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/grid/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Grid bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/market/__init__.py b/py/frequenz/api/common/v1alpha7/market/__init__.py new file mode 100644 index 00000000..6d45a2a4 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/market/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Market bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/metrics/__init__.py b/py/frequenz/api/common/v1alpha7/metrics/__init__.py new file mode 100644 index 00000000..56e22094 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/metrics/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Metrics bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/microgrid/__init__.py b/py/frequenz/api/common/v1alpha7/microgrid/__init__.py new file mode 100644 index 00000000..a75185d9 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/microgrid/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Microgrid bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/microgrid/communication_components/__init__.py b/py/frequenz/api/common/v1alpha7/microgrid/communication_components/__init__.py new file mode 100644 index 00000000..4d39d2c7 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/microgrid/communication_components/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Communication components bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/microgrid/electrical_components/__init__.py b/py/frequenz/api/common/v1alpha7/microgrid/electrical_components/__init__.py new file mode 100644 index 00000000..43af498b --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/microgrid/electrical_components/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Electrical components bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/microgrid/sensors/__init__.py b/py/frequenz/api/common/v1alpha7/microgrid/sensors/__init__.py new file mode 100644 index 00000000..097be901 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/microgrid/sensors/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Sensors bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/pagination/__init__.py b/py/frequenz/api/common/v1alpha7/pagination/__init__.py new file mode 100644 index 00000000..391b10d5 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/pagination/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Pagination bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/streaming/__init__.py b/py/frequenz/api/common/v1alpha7/streaming/__init__.py new file mode 100644 index 00000000..6a5e405d --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/streaming/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Streaming bindings for Frequenz common gRPC API.""" diff --git a/py/frequenz/api/common/v1alpha7/type/__init__.py b/py/frequenz/api/common/v1alpha7/type/__init__.py new file mode 100644 index 00000000..03c0e913 --- /dev/null +++ b/py/frequenz/api/common/v1alpha7/type/__init__.py @@ -0,0 +1,4 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Type bindings for Frequenz common gRPC API.""" diff --git a/pytests/test_common.py b/pytests/test_common_v1.py similarity index 65% rename from pytests/test_common.py rename to pytests/test_common_v1.py index e2ffadea..5e6d0258 100644 --- a/pytests/test_common.py +++ b/pytests/test_common_v1.py @@ -15,12 +15,12 @@ def test_package_import() -> None: def test_module_import_decimal() -> None: """Test that the modules can be imported.""" # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.type import decimal_pb2 + from frequenz.api.common.v1.types import decimal_pb2 assert decimal_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.type import decimal_pb2_grpc + from frequenz.api.common.v1.types import decimal_pb2_grpc assert decimal_pb2_grpc is not None @@ -38,17 +38,17 @@ def test_module_import_metrics_bounds() -> None: assert bounds_pb2_grpc is not None -def test_module_import_metrics_metrics() -> None: +def test_module_import_metrics_metric_sample() -> None: """Test that the modules can be imported.""" # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.metrics import metrics_pb2 + from frequenz.api.common.v1.metrics import metric_sample_pb2 - assert metrics_pb2 is not None + assert metric_sample_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.metrics import metrics_pb2_grpc + from frequenz.api.common.v1.metrics import metric_sample_pb2_grpc - assert metrics_pb2_grpc is not None + assert metric_sample_pb2_grpc is not None def test_module_import_grid() -> None: @@ -103,121 +103,93 @@ def test_module_import_microgrid_lifetime() -> None: assert lifetime_pb2_grpc is not None -def test_module_import_microgrid_electrical_components() -> None: +def test_module_import_microgrid_components() -> None: """Test that the modules can be imported.""" # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid import electrical_components + from frequenz.api.common.v1.microgrid import components - assert electrical_components is not None + assert components is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import battery_pb2 + from frequenz.api.common.v1.microgrid.components import battery_pb2 assert battery_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import battery_pb2_grpc + from frequenz.api.common.v1.microgrid.components import battery_pb2_grpc assert battery_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import ( - electrical_components_pb2, - ) + from frequenz.api.common.v1.microgrid.components import components_pb2 - assert electrical_components_pb2 is not None + assert components_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import ( - electrical_components_pb2_grpc, - ) + from frequenz.api.common.v1.microgrid.components import components_pb2_grpc - assert electrical_components_pb2_grpc is not None + assert components_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import ev_charger_pb2 + from frequenz.api.common.v1.microgrid.components import ev_charger_pb2 assert ev_charger_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import ( - ev_charger_pb2_grpc, - ) + from frequenz.api.common.v1.microgrid.components import ev_charger_pb2_grpc assert ev_charger_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import fuse_pb2 + from frequenz.api.common.v1.microgrid.components import fuse_pb2 assert fuse_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import fuse_pb2_grpc + from frequenz.api.common.v1.microgrid.components import fuse_pb2_grpc assert fuse_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import grid_pb2 + from frequenz.api.common.v1.microgrid.components import grid_pb2 assert grid_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import grid_pb2_grpc + from frequenz.api.common.v1.microgrid.components import grid_pb2_grpc assert grid_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import inverter_pb2 + from frequenz.api.common.v1.microgrid.components import inverter_pb2 assert inverter_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import inverter_pb2_grpc + from frequenz.api.common.v1.microgrid.components import inverter_pb2_grpc assert inverter_pb2_grpc is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import transformer_pb2 + from frequenz.api.common.v1.microgrid.components import transformer_pb2 assert transformer_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid.electrical_components import ( - transformer_pb2_grpc, - ) + from frequenz.api.common.v1.microgrid.components import transformer_pb2_grpc assert transformer_pb2_grpc is not None -def test_module_import_microgrid_communication_components() -> None: - """Test that the modules can be imported.""" - # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.microgrid import communication_components - - assert communication_components is not None - - from frequenz.api.common.v1.microgrid.communication_components import ( - communication_components_pb2, - ) - - assert communication_components_pb2 is not None - - from frequenz.api.common.v1.microgrid.communication_components import ( - communication_components_pb2_grpc, - ) - - assert communication_components_pb2_grpc is not None - - def test_module_import_location() -> None: """Test that the modules can be imported.""" # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.type import location_pb2 + from frequenz.api.common.v1 import location_pb2 assert location_pb2 is not None # pylint: disable=import-outside-toplevel - from frequenz.api.common.v1.type import location_pb2_grpc + from frequenz.api.common.v1 import location_pb2_grpc assert location_pb2_grpc is not None diff --git a/pytests/test_common_v1alpha7.py b/pytests/test_common_v1alpha7.py new file mode 100644 index 00000000..c6414405 --- /dev/null +++ b/pytests/test_common_v1alpha7.py @@ -0,0 +1,264 @@ +# License: MIT +# Copyright © 2023 Frequenz Energy-as-a-Service GmbH + +"""Tests for the frequenz.api.common package.""" + + +def test_package_import() -> None: + """Test that the package can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common import v1alpha7 + + assert v1alpha7 is not None + + +def test_module_import_decimal() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.type import decimal_pb2 + + assert decimal_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.type import decimal_pb2_grpc + + assert decimal_pb2_grpc is not None + + +def test_module_import_metrics_bounds() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.metrics import bounds_pb2 + + assert bounds_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.metrics import bounds_pb2_grpc + + assert bounds_pb2_grpc is not None + + +def test_module_import_metrics_metrics() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.metrics import metrics_pb2 + + assert metrics_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.metrics import metrics_pb2_grpc + + assert metrics_pb2_grpc is not None + + +def test_module_import_grid() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7 import grid + + assert grid is not None + + +def test_module_import_grid_delivery_area() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.grid import delivery_area_pb2 + + assert delivery_area_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.grid import delivery_area_pb2_grpc + + assert delivery_area_pb2_grpc is not None + + +def test_module_import_microgrid() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7 import microgrid + + assert microgrid is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import microgrid_pb2 + + assert microgrid_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import microgrid_pb2_grpc + + assert microgrid_pb2_grpc is not None + + +def test_module_import_microgrid_lifetime() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import lifetime_pb2 + + assert lifetime_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import lifetime_pb2_grpc + + assert lifetime_pb2_grpc is not None + + +def test_module_import_microgrid_electrical_components() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import electrical_components + + assert electrical_components is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import battery_pb2 + + assert battery_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + battery_pb2_grpc, + ) + + assert battery_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + electrical_components_pb2, + ) + + assert electrical_components_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + electrical_components_pb2_grpc, + ) + + assert electrical_components_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + ev_charger_pb2, + ) + + assert ev_charger_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + ev_charger_pb2_grpc, + ) + + assert ev_charger_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import fuse_pb2 + + assert fuse_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + fuse_pb2_grpc, + ) + + assert fuse_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import grid_pb2 + + assert grid_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + grid_pb2_grpc, + ) + + assert grid_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + inverter_pb2, + ) + + assert inverter_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + inverter_pb2_grpc, + ) + + assert inverter_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + transformer_pb2, + ) + + assert transformer_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid.electrical_components import ( + transformer_pb2_grpc, + ) + + assert transformer_pb2_grpc is not None + + +def test_module_import_microgrid_communication_components() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.microgrid import communication_components + + assert communication_components is not None + + from frequenz.api.common.v1alpha7.microgrid.communication_components import ( + communication_components_pb2, + ) + + assert communication_components_pb2 is not None + + from frequenz.api.common.v1alpha7.microgrid.communication_components import ( + communication_components_pb2_grpc, + ) + + assert communication_components_pb2_grpc is not None + + +def test_module_import_location() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.type import location_pb2 + + assert location_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.type import location_pb2_grpc + + assert location_pb2_grpc is not None + + +def test_module_import_pagination() -> None: + """Test that the modules can be imported.""" + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7 import pagination + + assert pagination is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.pagination import pagination_info_pb2 + + assert pagination_info_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.pagination import pagination_info_pb2_grpc + + assert pagination_info_pb2_grpc is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.pagination import pagination_params_pb2 + + assert pagination_params_pb2 is not None + + # pylint: disable=import-outside-toplevel + from frequenz.api.common.v1alpha7.pagination import pagination_params_pb2_grpc + + assert pagination_params_pb2_grpc is not None