Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add component types #11

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ description = "Common code and utilities for Frequenz API clients"
readme = "README.md"
license = { text = "MIT" }
keywords = ["frequenz", "python", "lib", "library", "client-common"]
# TODO(cookiecutter): Remove and add more classifiers if appropriate
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand All @@ -26,17 +25,16 @@ classifiers = [
"Typing :: Typed",
]
requires-python = ">= 3.11, < 4"
# TODO(cookiecutter): Remove and add more dependencies if appropriate
dependencies = [
"typing-extensions >= 4.5.0, < 5",
"frequenz-api-common >= 0.5.4, < 6",
]
dynamic = ["version"]

[[project.authors]]
name = "Frequenz Energy-as-a-Service GmbH"
email = "floss@frequenz.com"

# TODO(cookiecutter): Remove and add more optional dependencies if appropriate
[project.optional-dependencies]
dev-flake8 = [
"flake8 == 6.1.0",
Expand Down
23 changes: 1 addition & 22 deletions src/frequenz/client/common/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,4 @@
# License: MIT
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH

"""Common code and utilities for Frequenz API clients.

TODO(cookiecutter): Add a more descriptive module description.
"""


# TODO(cookiecutter): Remove this function
def delete_me(*, blow_up: bool = False) -> bool:
"""Do stuff for demonstration purposes.

Args:
blow_up: If True, raise an exception.

Returns:
True if no exception was raised.

Raises:
RuntimeError: if blow_up is True.
"""
if blow_up:
raise RuntimeError("This function should be removed!")
return True
"""Common code and utilities for Frequenz API clients."""
4 changes: 4 additions & 0 deletions src/frequenz/client/common/microgrid/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# License: MIT
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH

"""Frequenz microgrid definition."""
67 changes: 67 additions & 0 deletions src/frequenz/client/common/microgrid/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# License: MIT
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH

"""Defines the components that can be used in a microgrid."""
from __future__ import annotations

from enum import Enum

# pylint: disable=no-name-in-module
from frequenz.api.common.v1.microgrid.components.components_pb2 import (
ComponentCategory as PBComponentCategory,
)

# pylint: enable=no-name-in-module


class ComponentCategory(Enum):
"""Possible types of microgrid component."""

UNSPECIFIED = PBComponentCategory.COMPONENT_CATEGORY_UNSPECIFIED
"""An unknown component category.

Useful for error handling, and marking unknown components in
a list of components with otherwise known categories.
"""

GRID = PBComponentCategory.COMPONENT_CATEGORY_GRID
"""The point where the local microgrid is connected to the grid."""

METER = PBComponentCategory.COMPONENT_CATEGORY_METER
"""A meter, for measuring electrical metrics, e.g., current, voltage, etc."""

INVERTER = PBComponentCategory.COMPONENT_CATEGORY_INVERTER
"""An electricity generator, with batteries or solar energy."""

BATTERY = PBComponentCategory.COMPONENT_CATEGORY_BATTERY
"""A storage system for electrical energy, used by inverters."""

EV_CHARGER = PBComponentCategory.COMPONENT_CATEGORY_EV_CHARGER
"""A station for charging electrical vehicles."""

CHP = PBComponentCategory.COMPONENT_CATEGORY_CHP
"""A heat and power combustion plant (CHP stands for combined heat and power)."""

@classmethod
def from_proto(
cls, component_category: PBComponentCategory.ValueType
) -> ComponentCategory:
"""Convert a protobuf ComponentCategory message to ComponentCategory enum.

Args:
component_category: protobuf enum to convert

Returns:
Enum value corresponding to the protobuf message.
"""
if not any(t.value == component_category for t in ComponentCategory):
return ComponentCategory.UNSPECIFIED
return cls(component_category)

def to_proto(self) -> PBComponentCategory.ValueType:
"""Convert a ComponentCategory enum to protobuf ComponentCategory message.

Returns:
Enum value corresponding to the protobuf message.
"""
return self.value
16 changes: 5 additions & 11 deletions tests/test_client_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH

"""Tests for the frequenz.client.common package."""
import pytest

from frequenz.client.common import delete_me
from frequenz.client.common.microgrid.components import ComponentCategory


def test_client_common_succeeds() -> None: # TODO(cookiecutter): Remove
"""Test that the delete_me function succeeds."""
assert delete_me() is True


def test_client_common_fails() -> None: # TODO(cookiecutter): Remove
"""Test that the delete_me function fails."""
with pytest.raises(RuntimeError, match="This function should be removed!"):
delete_me(blow_up=True)
def test_components() -> None:
"""Test the components."""
for category in ComponentCategory:
assert ComponentCategory.from_proto(category.to_proto()) == category
Loading