diff --git a/src/frequenz/client/common/microgrid/electrical_components/__init__.py b/src/frequenz/client/common/microgrid/electrical_components/__init__.py index d1e75c50..6bc0c0e3 100644 --- a/src/frequenz/client/common/microgrid/electrical_components/__init__.py +++ b/src/frequenz/client/common/microgrid/electrical_components/__init__.py @@ -45,6 +45,7 @@ UnspecifiedInverter, ) from ._meter import Meter +from ._operational_mode import ElectricalComponentOperationalMode from ._power_transformer import PowerTransformer from ._precharger import Precharger from ._problematic import ( @@ -79,6 +80,7 @@ "ElectricalComponentConnection", "ElectricalComponentDiagnosticCode", "ElectricalComponentId", + "ElectricalComponentOperationalMode", "ElectricalComponentStateCode", "ElectricalComponentTypes", "Electrolyzer", diff --git a/src/frequenz/client/common/microgrid/electrical_components/_electrical_component.py b/src/frequenz/client/common/microgrid/electrical_components/_electrical_component.py index a4cdd03f..1dbcc8fa 100644 --- a/src/frequenz/client/common/microgrid/electrical_components/_electrical_component.py +++ b/src/frequenz/client/common/microgrid/electrical_components/_electrical_component.py @@ -13,6 +13,7 @@ from .. import MicrogridId from ._category import ElectricalComponentCategory from ._ids import ElectricalComponentId +from ._operational_mode import ElectricalComponentOperationalMode @dataclasses.dataclass(frozen=True, kw_only=True) @@ -41,16 +42,25 @@ class ElectricalComponent: # pylint: disable=too-many-instance-attributes name: str | None = None """The name of this electrical component.""" - manufacturer: str | None = None - """The manufacturer of this electrical component.""" + model: str | None = None + """The model of this electrical component. - model_name: str | None = None - """The model name of this electrical component.""" + This includes both the manufacturer and the model name. + """ operational_lifetime: Lifetime = dataclasses.field(default_factory=Lifetime) """The operational lifetime of this electrical component.""" - rated_bounds: Mapping[Metric | int, Bounds] = dataclasses.field( + operational_mode: ElectricalComponentOperationalMode | int = ( + ElectricalComponentOperationalMode.UNSPECIFIED + ) + """The operational mode of this electrical component. + + This indicates whether the component is active and operational, and whether it + provides telemetry data, accepts control commands, or both. + """ + + metric_config_bounds: Mapping[Metric | int, Bounds] = dataclasses.field( default_factory=dict, # dict is not hashable, so we don't use this field to calculate the hash. This # shouldn't be a problem since it is very unlikely that two components with all @@ -58,7 +68,11 @@ class ElectricalComponent: # pylint: disable=too-many-instance-attributes # so hash collisions should be still very unlikely. hash=False, ) - """List of rated bounds present for the electrical component identified by Metric.""" + """The metric configuration bounds for this electrical component, keyed by metric. + + These bounds may be derived from the component configuration, manufacturer + limits, or limits of other devices. + """ category_specific_metadata: Mapping[str, Any] = dataclasses.field( default_factory=dict, diff --git a/src/frequenz/client/common/microgrid/electrical_components/_operational_mode.py b/src/frequenz/client/common/microgrid/electrical_components/_operational_mode.py new file mode 100644 index 00000000..d72bff80 --- /dev/null +++ b/src/frequenz/client/common/microgrid/electrical_components/_operational_mode.py @@ -0,0 +1,42 @@ +# License: MIT +# Copyright © 2026 Frequenz Energy-as-a-Service GmbH + +"""Electrical component operational modes.""" + +import enum + + +@enum.unique +class ElectricalComponentOperationalMode(enum.Enum): + """The operational mode of an electrical component. + + This indicates whether the component is active and operational, and whether it + provides telemetry data, accepts control commands, or both. + """ + + UNSPECIFIED = 0 + """Default value when the operational mode is not explicitly set.""" + + INACTIVE = 1 + """The component is inactive and not operational. + + It does not provide telemetry data, and it does not accept control commands. + """ + + TELEMETRY_ONLY = 2 + """The component is active and operational, providing telemetry data only. + + It does not accept control commands. + """ + + CONTROL_ONLY = 3 + """The component is active and operational, accepting control commands only. + + It does not provide telemetry data. + """ + + CONTROL_AND_TELEMETRY = 4 + """The component is active and operational. + + It provides telemetry data and accepts control commands. + """ diff --git a/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/__init__.py b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/__init__.py index 63ca4b58..8fb7f21d 100644 --- a/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/__init__.py +++ b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/__init__.py @@ -19,6 +19,10 @@ electrical_component_connection_from_proto, electrical_component_connection_from_proto_with_issues, ) +from ._operational_mode import ( + electrical_component_operational_mode_from_proto, + electrical_component_operational_mode_to_proto, +) from ._state_code import ( electrical_component_state_code_from_proto, electrical_component_state_code_to_proto, @@ -33,6 +37,8 @@ "electrical_component_diagnostic_code_to_proto", "electrical_component_from_proto", "electrical_component_from_proto_with_issues", + "electrical_component_operational_mode_from_proto", + "electrical_component_operational_mode_to_proto", "electrical_component_state_code_from_proto", "electrical_component_state_code_to_proto", ] diff --git a/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_electrical_component.py b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_electrical_component.py index 38dc777e..6d588999 100644 --- a/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_electrical_component.py +++ b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_electrical_component.py @@ -29,6 +29,7 @@ DcEvCharger, ElectricalComponentCategory, ElectricalComponentId, + ElectricalComponentOperationalMode, ElectricalComponentTypes, Electrolyzer, EvChargerType, @@ -55,6 +56,7 @@ UnspecifiedInverter, WindTurbine, ) +from ._operational_mode import electrical_component_operational_mode_from_proto _logger = logging.getLogger(__name__) @@ -104,15 +106,16 @@ class _ElectricalComponentBaseData(NamedTuple): component_id: ElectricalComponentId microgrid_id: MicrogridId name: str | None - manufacturer: str | None - model_name: str | None + model: str | None category: ElectricalComponentCategory | int lifetime: Lifetime - rated_bounds: dict[Metric | int, Bounds] + metric_config_bounds: dict[Metric | int, Bounds] category_specific_info: dict[str, Any] + operational_mode: ElectricalComponentOperationalMode | int category_mismatched: bool = False +# pylint: disable-next=too-many-locals def _electrical_component_base_from_proto_with_issues( message: electrical_components_pb2.ElectricalComponent, *, @@ -136,19 +139,19 @@ def _electrical_component_base_from_proto_with_issues( if name is None: minor_issues.append("name is empty") - manufacturer = message.manufacturer or None - if manufacturer is None: - minor_issues.append("manufacturer is empty") + model = message.model or None + if model is None: + minor_issues.append("model is empty") - model_name = message.model_name or None - if model_name is None: - minor_issues.append("model_name is empty") + operational_mode = electrical_component_operational_mode_from_proto( + message.operational_mode + ) lifetime = _get_operational_lifetime_from_proto( message, major_issues=major_issues, minor_issues=minor_issues ) - rated_bounds = _metric_config_bounds_from_proto( + metric_config_bounds = _metric_config_bounds_from_proto( message.metric_config_bounds, major_issues=major_issues, minor_issues=minor_issues, @@ -184,12 +187,12 @@ def _electrical_component_base_from_proto_with_issues( component_id, microgrid_id, name, - manufacturer, - model_name, + model, category, lifetime, - rated_bounds, + metric_config_bounds, category_specific_info, + operational_mode, category_mismatched, ) @@ -220,12 +223,12 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, category=base_data.category, operational_lifetime=base_data.lifetime, + operational_mode=base_data.operational_mode, category_specific_metadata=base_data.category_specific_info, - rated_bounds=base_data.rated_bounds, + metric_config_bounds=base_data.metric_config_bounds, ) match base_data.category: @@ -234,11 +237,11 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, category=base_data.category, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case ( ElectricalComponentCategory.UNSPECIFIED @@ -257,10 +260,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case ElectricalComponentCategory.BATTERY: battery_enum_to_class: dict[ @@ -281,10 +284,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case int(): major_issues.append(f"battery type {battery_type} is unrecognized") @@ -292,10 +295,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, type=battery_type, ) case unexpected_battery_type: @@ -328,10 +331,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case int(): major_issues.append( @@ -341,10 +344,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, type=ev_charger_type, ) case unexpected_ev_charger_type: @@ -358,10 +361,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, rated_fuse_current=rated_fuse_current, ) case ElectricalComponentCategory.INVERTER: @@ -392,10 +395,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case int(): major_issues.append( @@ -405,10 +408,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, type=inverter_type, ) case unexpected_inverter_type: @@ -418,10 +421,10 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, primary_voltage=message.category_specific_info.power_transformer.primary, secondary_voltage=message.category_specific_info.power_transformer.secondary, ) @@ -439,11 +442,11 @@ def electrical_component_from_proto_with_issues( id=base_data.component_id, microgrid_id=base_data.microgrid_id, name=base_data.name, - manufacturer=base_data.manufacturer, - model_name=base_data.model_name, + model=base_data.model, category=base_data.category.value, operational_lifetime=base_data.lifetime, - rated_bounds=base_data.rated_bounds, + operational_mode=base_data.operational_mode, + metric_config_bounds=base_data.metric_config_bounds, ) case unexpected_category: assert_never(unexpected_category) diff --git a/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_operational_mode.py b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_operational_mode.py new file mode 100644 index 00000000..49d8fac3 --- /dev/null +++ b/src/frequenz/client/common/microgrid/electrical_components/proto/v1alpha8/_operational_mode.py @@ -0,0 +1,42 @@ +# License: MIT +# Copyright © 2026 Frequenz Energy-as-a-Service GmbH + +"""Conversion of electrical component operational modes to/from protobuf v1alpha8.""" + +from frequenz.api.common.v1alpha8.microgrid.electrical_components import ( + electrical_components_pb2, +) + +from .....proto import enum_from_proto +from ... import ElectricalComponentOperationalMode + + +def electrical_component_operational_mode_from_proto( + message: electrical_components_pb2.ElectricalComponentOperationalMode.ValueType, +) -> ElectricalComponentOperationalMode | int: + """Convert a protobuf ElectricalComponentOperationalMode enum value to an enum member. + + Args: + message: A protobuf ElectricalComponentOperationalMode enum value. + + Returns: + The corresponding ElectricalComponentOperationalMode enum member, or the raw + `int` if the protobuf value is not recognized. + """ + return enum_from_proto(message, ElectricalComponentOperationalMode) + + +def electrical_component_operational_mode_to_proto( + operational_mode: ElectricalComponentOperationalMode, +) -> electrical_components_pb2.ElectricalComponentOperationalMode.ValueType: + """Convert an ElectricalComponentOperationalMode enum member to a protobuf enum value. + + Args: + operational_mode: An ElectricalComponentOperationalMode enum member. + + Returns: + The corresponding protobuf ElectricalComponentOperationalMode enum value. + """ + return electrical_components_pb2.ElectricalComponentOperationalMode.ValueType( + operational_mode.value + ) diff --git a/tests/microgrid/electrical_components/proto/v1alpha8/conftest.py b/tests/microgrid/electrical_components/proto/v1alpha8/conftest.py index 9bf76ac9..14852e80 100644 --- a/tests/microgrid/electrical_components/proto/v1alpha8/conftest.py +++ b/tests/microgrid/electrical_components/proto/v1alpha8/conftest.py @@ -19,6 +19,7 @@ ElectricalComponent, ElectricalComponentCategory, ElectricalComponentId, + ElectricalComponentOperationalMode, ) from frequenz.client.common.microgrid.electrical_components.proto.v1alpha8._electrical_component import ( # noqa: E501 _ElectricalComponentBaseData, @@ -33,8 +34,7 @@ DEFAULT_COMPONENT_ID = ElectricalComponentId(42) DEFAULT_MICROGRID_ID = MicrogridId(1) DEFAULT_NAME = "test_component" -DEFAULT_MANUFACTURER = "test_manufacturer" -DEFAULT_MODEL_NAME = "test_model" +DEFAULT_MODEL = "test_manufacturer test_model" @pytest.fixture @@ -58,12 +58,12 @@ def default_component_base_data( component_id=component_id, microgrid_id=microgrid_id, name=DEFAULT_NAME, - manufacturer=DEFAULT_MANUFACTURER, - model_name=DEFAULT_MODEL_NAME, + model=DEFAULT_MODEL, category=ElectricalComponentCategory.UNSPECIFIED, lifetime=DEFAULT_LIFETIME, - rated_bounds={Metric.AC_ENERGY_ACTIVE: Bounds(lower=0, upper=100)}, + metric_config_bounds={Metric.AC_ENERGY_ACTIVE: Bounds(lower=0, upper=100)}, category_specific_info={}, + operational_mode=ElectricalComponentOperationalMode.CONTROL_AND_TELEMETRY, category_mismatched=False, ) @@ -75,11 +75,11 @@ def assert_base_data( assert base_data.component_id == other.id assert base_data.microgrid_id == other.microgrid_id assert base_data.name == other.name - assert base_data.manufacturer == other.manufacturer - assert base_data.model_name == other.model_name + assert base_data.model == other.model assert base_data.category == other.category assert base_data.lifetime == other.operational_lifetime - assert base_data.rated_bounds == other.rated_bounds + assert base_data.operational_mode == other.operational_mode + assert base_data.metric_config_bounds == other.metric_config_bounds assert base_data.category_specific_info == other.category_specific_metadata @@ -91,13 +91,17 @@ def base_data_as_proto( id=int(base_data.component_id), microgrid_id=int(base_data.microgrid_id), name=base_data.name or "", - manufacturer=base_data.manufacturer or "", - model_name=base_data.model_name or "", + model=base_data.model or "", category=( base_data.category if isinstance(base_data.category, int) else int(base_data.category.value) # type: ignore[arg-type] ), + operational_mode=( + base_data.operational_mode + if isinstance(base_data.operational_mode, int) + else int(base_data.operational_mode.value) # type: ignore[arg-type] + ), ) if base_data.lifetime: lifetime_dict: dict[str, Timestamp] = {} @@ -110,8 +114,8 @@ def base_data_as_proto( base_data.lifetime.end_time ) proto.operational_lifetime.CopyFrom(lifetime_pb2.Lifetime(**lifetime_dict)) - if base_data.rated_bounds: - for metric, bounds in base_data.rated_bounds.items(): + if base_data.metric_config_bounds: + for metric, bounds in base_data.metric_config_bounds.items(): bounds_dict: dict[str, float] = {} if bounds.lower is not None: bounds_dict["lower"] = bounds.lower diff --git a/tests/microgrid/electrical_components/proto/v1alpha8/test_electrical_component_base.py b/tests/microgrid/electrical_components/proto/v1alpha8/test_electrical_component_base.py index 2a6fe8ab..5acae128 100644 --- a/tests/microgrid/electrical_components/proto/v1alpha8/test_electrical_component_base.py +++ b/tests/microgrid/electrical_components/proto/v1alpha8/test_electrical_component_base.py @@ -45,11 +45,9 @@ def test_missing_category_specific_info( minor_issues: list[str] = [] base_data = default_component_base_data._replace( name=None, - manufacturer=None, - model_name=None, category=ElectricalComponentCategory.UNSPECIFIED, lifetime=Lifetime(), - rated_bounds={}, + metric_config_bounds={}, category_specific_info={}, ) proto = base_data_as_proto(base_data) @@ -64,8 +62,6 @@ def test_missing_category_specific_info( assert sorted(minor_issues) == sorted( [ "name is empty", - "manufacturer is empty", - "model_name is empty", "missing operational lifetime, considering it always operational", ] ) diff --git a/tests/microgrid/electrical_components/proto/v1alpha8/test_operational_mode.py b/tests/microgrid/electrical_components/proto/v1alpha8/test_operational_mode.py new file mode 100644 index 00000000..1d741efd --- /dev/null +++ b/tests/microgrid/electrical_components/proto/v1alpha8/test_operational_mode.py @@ -0,0 +1,27 @@ +# License: MIT +# Copyright © 2026 Frequenz Energy-as-a-Service GmbH + +"""Tests for electrical component operational mode to/from protobuf v1alpha8 conversion.""" + +from frequenz.api.common.v1alpha8.microgrid.electrical_components import ( + electrical_components_pb2, +) + +from frequenz.client.common.microgrid.electrical_components import ( + ElectricalComponentOperationalMode, +) +from frequenz.client.common.microgrid.electrical_components.proto.v1alpha8 import ( + electrical_component_operational_mode_from_proto, + electrical_component_operational_mode_to_proto, +) +from frequenz.client.common.test.enum_parity import EnumParityTest + + +class TestElectricalComponentOperationalModeParity(EnumParityTest): + """Parity tests for the `ElectricalComponentOperationalMode` enum.""" + + python_enum = ElectricalComponentOperationalMode + proto_enum = electrical_components_pb2.ElectricalComponentOperationalMode + name_prefix = "ELECTRICAL_COMPONENT_OPERATIONAL_MODE_" + from_proto = staticmethod(electrical_component_operational_mode_from_proto) + to_proto = staticmethod(electrical_component_operational_mode_to_proto) diff --git a/tests/microgrid/electrical_components/test_battery.py b/tests/microgrid/electrical_components/test_battery.py index f692997b..4fdbea4b 100644 --- a/tests/microgrid/electrical_components/test_battery.py +++ b/tests/microgrid/electrical_components/test_battery.py @@ -50,8 +50,6 @@ def test_abstract_battery_cannot_be_instantiated( id=component_id, microgrid_id=microgrid_id, name="test_battery", - manufacturer="test_manufacturer", - model_name="test_model", type=BatteryType.LI_ION, ) @@ -83,15 +81,11 @@ def test_recognized_battery_types( id=component_id, microgrid_id=microgrid_id, name=case.name, - manufacturer="test_manufacturer", - model_name="test_model", ) assert battery.id == component_id assert battery.microgrid_id == microgrid_id assert battery.name == case.name - assert battery.manufacturer == "test_manufacturer" - assert battery.model_name == "test_model" assert battery.category == ElectricalComponentCategory.BATTERY assert battery.type == case.expected_type @@ -104,15 +98,11 @@ def test_unrecognized_battery_type( id=component_id, microgrid_id=microgrid_id, name="unrecognized_battery", - manufacturer="test_manufacturer", - model_name="test_model", type=999, ) assert battery.id == component_id assert battery.microgrid_id == microgrid_id assert battery.name == "unrecognized_battery" - assert battery.manufacturer == "test_manufacturer" - assert battery.model_name == "test_model" assert battery.category == ElectricalComponentCategory.BATTERY assert battery.type == 999 diff --git a/tests/microgrid/electrical_components/test_electrical_component_base.py b/tests/microgrid/electrical_components/test_electrical_component_base.py index 29ffc5f5..67d3e56c 100644 --- a/tests/microgrid/electrical_components/test_electrical_component_base.py +++ b/tests/microgrid/electrical_components/test_electrical_component_base.py @@ -15,6 +15,7 @@ ElectricalComponent, ElectricalComponentCategory, ElectricalComponentId, + ElectricalComponentOperationalMode, ) from frequenz.client.common.types import Lifetime @@ -48,17 +49,17 @@ def test_creation_with_defaults() -> None: ) assert component.name is None - assert component.manufacturer is None - assert component.model_name is None + assert component.model is None assert component.operational_lifetime == Lifetime() - assert component.rated_bounds == {} + assert component.operational_mode == ElectricalComponentOperationalMode.UNSPECIFIED + assert component.metric_config_bounds == {} assert component.category_specific_metadata == {} def test_creation_full() -> None: """Test electrical component creation with all attributes.""" bounds = Bounds(lower=-100.0, upper=100.0) - rated_bounds: dict[Metric | int, Bounds] = {Metric.AC_POWER_ACTIVE: bounds} + metric_config_bounds: dict[Metric | int, Bounds] = {Metric.AC_POWER_ACTIVE: bounds} metadata = {"key1": "value1", "key2": 42} component = _TestElectricalComponent( @@ -66,16 +67,14 @@ def test_creation_full() -> None: microgrid_id=MicrogridId(2), category=ElectricalComponentCategory.UNSPECIFIED, name="test-component", - manufacturer="Test Manufacturer", - model_name="Test Model", - rated_bounds=rated_bounds, + model="Test Manufacturer Test Model", + metric_config_bounds=metric_config_bounds, category_specific_metadata=metadata, ) assert component.name == "test-component" - assert component.manufacturer == "Test Manufacturer" - assert component.model_name == "Test Model" - assert component.rated_bounds == rated_bounds + assert component.model == "Test Manufacturer Test Model" + assert component.metric_config_bounds == metric_config_bounds assert component.category_specific_metadata == metadata @@ -146,9 +145,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=MicrogridId(1), category=ElectricalComponentCategory.UNSPECIFIED, name="test", - manufacturer="Test Mfg", - model_name="Model A", - rated_bounds={Metric.AC_POWER_ACTIVE: Bounds(lower=-100.0, upper=100.0)}, + metric_config_bounds={Metric.AC_POWER_ACTIVE: Bounds(lower=-100.0, upper=100.0)}, category_specific_metadata={"key": "value"}, ) @@ -157,9 +154,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=COMPONENT.microgrid_id, category=COMPONENT.category, name=COMPONENT.name, - manufacturer=COMPONENT.manufacturer, - model_name=COMPONENT.model_name, - rated_bounds={Metric.AC_POWER_ACTIVE: Bounds(lower=-200.0, upper=200.0)}, + metric_config_bounds={Metric.AC_POWER_ACTIVE: Bounds(lower=-200.0, upper=200.0)}, category_specific_metadata={"different": "metadata"}, ) @@ -168,9 +163,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=COMPONENT.microgrid_id, category=COMPONENT.category, name="different", - manufacturer=COMPONENT.manufacturer, - model_name=COMPONENT.model_name, - rated_bounds=COMPONENT.rated_bounds, + metric_config_bounds=COMPONENT.metric_config_bounds, category_specific_metadata=COMPONENT.category_specific_metadata, ) @@ -179,9 +172,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=COMPONENT.microgrid_id, category=COMPONENT.category, name=COMPONENT.name, - manufacturer=COMPONENT.manufacturer, - model_name=COMPONENT.model_name, - rated_bounds=COMPONENT.rated_bounds, + metric_config_bounds=COMPONENT.metric_config_bounds, category_specific_metadata=COMPONENT.category_specific_metadata, ) @@ -190,9 +181,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=MicrogridId(2), category=COMPONENT.category, name=COMPONENT.name, - manufacturer=COMPONENT.manufacturer, - model_name=COMPONENT.model_name, - rated_bounds=COMPONENT.rated_bounds, + metric_config_bounds=COMPONENT.metric_config_bounds, category_specific_metadata=COMPONENT.category_specific_metadata, ) @@ -201,9 +190,7 @@ def test_is_operational_now(mock_datetime: Mock) -> None: microgrid_id=MicrogridId(2), category=COMPONENT.category, name=COMPONENT.name, - manufacturer=COMPONENT.manufacturer, - model_name=COMPONENT.model_name, - rated_bounds=COMPONENT.rated_bounds, + metric_config_bounds=COMPONENT.metric_config_bounds, category_specific_metadata=COMPONENT.category_specific_metadata, ) diff --git a/tests/microgrid/electrical_components/test_ev_charger.py b/tests/microgrid/electrical_components/test_ev_charger.py index f9351909..ef30e68f 100644 --- a/tests/microgrid/electrical_components/test_ev_charger.py +++ b/tests/microgrid/electrical_components/test_ev_charger.py @@ -51,8 +51,6 @@ def test_abstract_ev_charger_cannot_be_instantiated( id=component_id, microgrid_id=microgrid_id, name="test_charger", - manufacturer="test_manufacturer", - model_name="test_model", type=EvChargerType.AC, ) @@ -85,15 +83,11 @@ def test_recognized_ev_charger_types( # Renamed from test_ev_charger_types id=component_id, microgrid_id=microgrid_id, name=case.name, - manufacturer="test_manufacturer", - model_name="test_model", ) assert charger.id == component_id assert charger.microgrid_id == microgrid_id assert charger.name == case.name - assert charger.manufacturer == "test_manufacturer" - assert charger.model_name == "test_model" assert charger.category == ElectricalComponentCategory.EV_CHARGER assert charger.type == case.expected_type @@ -106,15 +100,11 @@ def test_unrecognized_ev_charger_type( id=component_id, microgrid_id=microgrid_id, name="unrecognized_charger", - manufacturer="test_manufacturer", - model_name="test_model", type=999, # type is passed here for UnrecognizedEvCharger ) assert charger.id == component_id assert charger.microgrid_id == microgrid_id assert charger.name == "unrecognized_charger" - assert charger.manufacturer == "test_manufacturer" - assert charger.model_name == "test_model" assert charger.category == ElectricalComponentCategory.EV_CHARGER assert charger.type == 999 diff --git a/tests/microgrid/electrical_components/test_grid_connection_point.py b/tests/microgrid/electrical_components/test_grid_connection_point.py index ba4458fe..e5b02aad 100644 --- a/tests/microgrid/electrical_components/test_grid_connection_point.py +++ b/tests/microgrid/electrical_components/test_grid_connection_point.py @@ -36,16 +36,12 @@ def test_creation_ok( id=component_id, microgrid_id=microgrid_id, name="test_grid_point", - manufacturer="test_manufacturer", - model_name="test_model", rated_fuse_current=rated_fuse_current, ) assert grid_point.id == component_id assert grid_point.microgrid_id == microgrid_id assert grid_point.name == "test_grid_point" - assert grid_point.manufacturer == "test_manufacturer" - assert grid_point.model_name == "test_model" assert grid_point.category == ElectricalComponentCategory.GRID_CONNECTION_POINT assert grid_point.rated_fuse_current == rated_fuse_current @@ -61,7 +57,5 @@ def test_creation_invalid_rated_fuse_current( id=component_id, microgrid_id=microgrid_id, name="test_grid_point", - manufacturer="test_manufacturer", - model_name="test_model", rated_fuse_current=-1, ) diff --git a/tests/microgrid/electrical_components/test_inverter.py b/tests/microgrid/electrical_components/test_inverter.py index e36b22f8..0981c827 100644 --- a/tests/microgrid/electrical_components/test_inverter.py +++ b/tests/microgrid/electrical_components/test_inverter.py @@ -51,8 +51,6 @@ def test_abstract_inverter_cannot_be_instantiated( id=component_id, microgrid_id=microgrid_id, name="test_inverter", - manufacturer="test_manufacturer", - model_name="test_model", type=InverterType.BATTERY, ) @@ -85,15 +83,11 @@ def test_recognized_inverter_types( id=component_id, microgrid_id=microgrid_id, name=case.name, - manufacturer="test_manufacturer", - model_name="test_model", ) assert inverter.id == component_id assert inverter.microgrid_id == microgrid_id assert inverter.name == case.name - assert inverter.manufacturer == "test_manufacturer" - assert inverter.model_name == "test_model" assert inverter.category == ElectricalComponentCategory.INVERTER assert inverter.type == case.expected_type @@ -106,15 +100,11 @@ def test_unrecognized_inverter_type( id=component_id, microgrid_id=microgrid_id, name="unrecognized_inverter", - manufacturer="test_manufacturer", - model_name="test_model", type=999, # type is passed here for UnrecognizedInverter ) assert inverter.id == component_id assert inverter.microgrid_id == microgrid_id assert inverter.name == "unrecognized_inverter" - assert inverter.manufacturer == "test_manufacturer" - assert inverter.model_name == "test_model" assert inverter.category == ElectricalComponentCategory.INVERTER assert inverter.type == 999 diff --git a/tests/microgrid/electrical_components/test_power_transformer.py b/tests/microgrid/electrical_components/test_power_transformer.py index 2f3ee5f7..b524fb48 100644 --- a/tests/microgrid/electrical_components/test_power_transformer.py +++ b/tests/microgrid/electrical_components/test_power_transformer.py @@ -39,8 +39,6 @@ def test_creation_ok( id=component_id, microgrid_id=microgrid_id, name="test_power_transformer", - manufacturer="test_manufacturer", - model_name="test_model", primary_voltage=primary, secondary_voltage=secondary, ) @@ -48,8 +46,6 @@ def test_creation_ok( assert power_transformer.id == component_id assert power_transformer.microgrid_id == microgrid_id assert power_transformer.name == "test_power_transformer" - assert power_transformer.manufacturer == "test_manufacturer" - assert power_transformer.model_name == "test_model" assert power_transformer.category == ElectricalComponentCategory.POWER_TRANSFORMER assert power_transformer.primary_voltage == pytest.approx(primary) assert power_transformer.secondary_voltage == pytest.approx(secondary) diff --git a/tests/microgrid/electrical_components/test_problematic.py b/tests/microgrid/electrical_components/test_problematic.py index 76742e27..62fed103 100644 --- a/tests/microgrid/electrical_components/test_problematic.py +++ b/tests/microgrid/electrical_components/test_problematic.py @@ -39,8 +39,6 @@ def test_abstract_problematic_electrical_component_cannot_be_instantiated( id=component_id, microgrid_id=microgrid_id, name="test_problematic", - manufacturer="test_manufacturer", - model_name="test_model", category=ElectricalComponentCategory.UNSPECIFIED, ) @@ -53,15 +51,11 @@ def test_unspecified_component( id=component_id, microgrid_id=microgrid_id, name="unspecified_component", - manufacturer="test_manufacturer", - model_name="test_model", ) assert component.id == component_id assert component.microgrid_id == microgrid_id assert component.name == "unspecified_component" - assert component.manufacturer == "test_manufacturer" - assert component.model_name == "test_model" assert component.category == ElectricalComponentCategory.UNSPECIFIED @@ -74,16 +68,12 @@ def test_mismatched_category_component_with_known_category( id=component_id, microgrid_id=microgrid_id, name="mismatched_battery", - manufacturer="test_manufacturer", - model_name="test_model", category=expected_category, ) assert component.id == component_id assert component.microgrid_id == microgrid_id assert component.name == "mismatched_battery" - assert component.manufacturer == "test_manufacturer" - assert component.model_name == "test_model" assert component.category == expected_category @@ -96,16 +86,12 @@ def test_mismatched_category_component_with_unrecognized_category( id=component_id, microgrid_id=microgrid_id, name="mismatched_unrecognized", - manufacturer="test_manufacturer", - model_name="test_model", category=expected_category, ) assert component.id == component_id assert component.microgrid_id == microgrid_id assert component.name == "mismatched_unrecognized" - assert component.manufacturer == "test_manufacturer" - assert component.model_name == "test_model" assert component.category == expected_category @@ -117,14 +103,10 @@ def test_unrecognized_component_type( id=component_id, microgrid_id=microgrid_id, name="unrecognized_component", - manufacturer="test_manufacturer", - model_name="test_model", category=999, ) assert component.id == component_id assert component.microgrid_id == microgrid_id assert component.name == "unrecognized_component" - assert component.manufacturer == "test_manufacturer" - assert component.model_name == "test_model" assert component.category == 999 diff --git a/tests/microgrid/electrical_components/test_simple_components.py b/tests/microgrid/electrical_components/test_simple_components.py index 29217a4b..70668f8a 100644 --- a/tests/microgrid/electrical_components/test_simple_components.py +++ b/tests/microgrid/electrical_components/test_simple_components.py @@ -71,13 +71,9 @@ def test_init( id=component_id, microgrid_id=microgrid_id, name="test_component", - manufacturer="test_manufacturer", - model_name="test_model", ) assert component.id == component_id assert component.microgrid_id == microgrid_id assert component.name == "test_component" - assert component.manufacturer == "test_manufacturer" - assert component.model_name == "test_model" assert component.category == expected_category