Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
5afc64d
Add `Temperature` quantity
christianparpart Jul 7, 2023
0e5efed
Add ComponentMetricId.TEMPERATURE_MAX and the ability to retrieve thi…
christianparpart Jul 7, 2023
09932bd
Add TemperatureMetrics to timeseries.battery_pool
christianparpart Jul 7, 2023
9dfb5a6
Add BatteryPool.temperature metrics receiver
christianparpart Jul 7, 2023
eca91fb
Nice error message for empty buffer and new test case
jack-herrmann Jul 17, 2023
b9ea7f1
Bump mkdocs-material from 9.1.18 to 9.1.19
dependabot[bot] Jul 19, 2023
ac70fde
Bump mkdocs-material from 9.1.18 to 9.1.19 (#521)
Marenz Jul 19, 2023
c5af86b
Bump polars from 0.18.7 to 0.18.8
dependabot[bot] Jul 21, 2023
46d8630
Bump polars from 0.18.7 to 0.18.8 (#526)
Marenz Jul 21, 2023
da6a5ce
Add capability to multiply quantities with percentage
Marenz Jul 13, 2023
0c50e4b
Add capability to multiply quantities with percentage (#512)
Marenz Jul 21, 2023
1043360
Implement dunder iadd, isub, imul methods for Quantity
shsms Jul 21, 2023
74481c1
Implement dunder iadd, isub, imul methods for Quantity (#527)
shsms Jul 21, 2023
68a7360
Bump types-protobuf from 4.23.0.1 to 4.23.0.2
dependabot[bot] Jul 24, 2023
2472817
Bump types-protobuf from 4.23.0.1 to 4.23.0.2 (#528)
matthias-wende-frequenz Jul 24, 2023
207d96a
Add token type CONSTANT
matthias-wende-frequenz Jul 18, 2023
7dc5283
Support constants in arithmetic FormulaEngine operations
matthias-wende-frequenz Jul 18, 2023
d47c657
Add test for composing formulas with constants
matthias-wende-frequenz Jul 20, 2023
dcc4b30
Add failing tests for formula composition
matthias-wende-frequenz Jul 24, 2023
674ac1a
Move formula evaluator to separate file
matthias-wende-frequenz Jul 24, 2023
fdb8a51
Update release notes
matthias-wende-frequenz Jul 21, 2023
520406f
Add constant to FormulaEngine arithmetic (#525)
matthias-wende-frequenz Jul 24, 2023
4009eec
Remove support for hashing of `Quantity` objects
shsms Jul 24, 2023
247c081
Document internal representation of `Quantity` objects as `float`s
shsms Jul 24, 2023
ee43f49
Add `isclose()` method for `Quantity` objects
shsms Jul 24, 2023
bc37e7c
Add RELEASE_NOTES entries
shsms Jul 25, 2023
8c9bcae
Quantity improvements (#533)
shsms Jul 26, 2023
6d4f2ad
Rewrite component data wrapper classes to not redefine data fields
shsms Jul 10, 2023
0efb86a
Allow MockMicrogrid battery chains without meters
shsms Jul 5, 2023
4803deb
Update logical meter grid power test to use a battery without a meter
shsms Jul 5, 2023
7990567
Update PowerDistributingActor constructor test to use MockMicrogrid
shsms Jul 5, 2023
ccb9e29
Expose internal mock_client to users of MockMicrogrid
shsms Jul 5, 2023
691d6a5
Use constant BATTERY_ID instead of hardcoded number
shsms Jul 10, 2023
1c8f58b
Update PowerDistributingActor tests to use MockMicrogrid
shsms Jul 6, 2023
018e176
Remove hardcoded component graph and fixtures
shsms Jul 10, 2023
82d5834
Check that minimum blocking duration is not greater than the maximum
shsms Jul 11, 2023
478b82b
Ensure component data is stale after receiving a timer event
shsms Jul 18, 2023
d38764e
Add recovery tests for BatteryStatusTracker
shsms Jul 18, 2023
72178a2
Add BatteryStatus tests to ensure it recovers automatically after iss…
shsms Jul 26, 2023
6f79353
Nice error message for empty buffer and new test case (#517)
matthias-wende-frequenz Jul 26, 2023
6885e32
Bump pylint from 2.17.4 to 2.17.5
dependabot[bot] Jul 27, 2023
bb9fcfb
Bump pylint from 2.17.4 to 2.17.5 (#539)
llucax Jul 27, 2023
3f2b5ee
Update to repo-config v0.4.0
llucax Jul 27, 2023
6a50238
Update to repo-config v0.4.0 (#540)
llucax Jul 27, 2023
5d32be8
Bump mkdocs-material from 9.1.19 to 9.1.21
dependabot[bot] Jul 28, 2023
64a33ce
Bump mkdocs-material from 9.1.19 to 9.1.21 (#549)
Marenz Jul 28, 2023
3f414ed
Merge draft implementation from christianparpart
shsms Jul 28, 2023
ada7a61
Add tests for the `Temperature` quantity
shsms Jul 28, 2023
25cd074
Rename `temperature_max` fields to `temperature`
shsms Jul 26, 2023
3ae0941
Replace `TemperatureMetrics` with `Sample[Temperature]`
shsms Jul 26, 2023
f10dfc6
Add tests for `battery_pool.temperature`
shsms Jul 28, 2023
f9cc2ab
Bump polars from 0.18.8 to 0.18.9
dependabot[bot] Jul 31, 2023
84ade2f
Bump polars from 0.18.8 to 0.18.9 (#553)
daniel-zullo-frequenz Jul 31, 2023
80ac74e
Bump polars from 0.18.9 to 0.18.11
dependabot[bot] Aug 1, 2023
5deb7d1
Bump polars from 0.18.9 to 0.18.11 (#554)
llucax Aug 1, 2023
1cd226b
Remove dunder iadd, isub and imul methods for Quantity
llucax Aug 1, 2023
361bcb0
Add zero() constructor for Quantities
llucax Jul 26, 2023
228700a
Update RELEASE_NOTES.md
shsms Aug 1, 2023
82084a6
Add zero() constructor for Quantities (#535)
llucax Aug 1, 2023
18036e4
Update src/frequenz/sdk/microgrid/component/_component_data.py
shsms Aug 1, 2023
759228e
Merge remote-tracking branch 'origin/v0.x.x' into battery-pool-temp
shsms Aug 1, 2023
3eae96b
Temperature streaming from the BatteryPool (#552)
shsms Aug 1, 2023
2a240fe
Update battery pool SoC calculation
matthias-wende-frequenz Aug 1, 2023
83888c5
Update release notes
matthias-wende-frequenz Aug 2, 2023
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
32 changes: 30 additions & 2 deletions .cookiecutter-replay.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"cookiecutter": {
"Introduction": "]\n\nWelcome to repo-config Cookiecutter template!\n\nThis template will help you to create a new repository for your project. You will be asked to provide some information about your project.\n\nHere is an explanation of what each variable is for and will be used for:\n\n* `type`: The type of repository. It must be chosen from the list.\n\n* `name`: The name of the project. This will be used to build defaults for\n other inputs, such as `title`, `python_package`, etc. It should be one word,\n using only alphanumeric characters (and starting with a letter). It can\n include also `_` and `-` which will be handled differently when building\n other variables from it (replaced by spaces in titles for example).\n\n* `description`: A short description of the project. It will be used as the\n description in the `README.md`, `pyproject.toml`, `mkdocs.yml`, etc.\n\n* `title`: A human-readable name or title for the project. It will be used in\n the `README.md`, `CONTRIBUTING.md`, and other files to refer to the project,\n as well as the site title in `mkdocs.yml`.\n\n* `keywords`: A comma-separated list of keywords that will be used in the\n `pyproject.toml` file. If left untouched, it will use only some predefined\n keywords. If anything else is entered, it will be **added** to the default\n keywords.\n\n* `github_org`: The GitHub handle of the organization where the project will\n reside. This will be used to generate links to the project on GitHub.\n\n* `license`: Currently, only two options are provided: `MIT`, which should be\n used for open-source projects, and `Proprietary`, which should be used for\n closed-source projects. This will be added to file headers and used as the\n license in `pyproject.toml`.\n\n* `author_name`, `author_email`: The name and email address of the author of\n the project. They will be used in the copyright notice in file headers and\n as the author in `pyproject.toml`.\n\n* `python_package`: The Python package in which this project will reside. All\n files provided by this project should be located in this package. This needs\n to be a list of valid Python identifiers separated by dots. The source file\n structure will be derived from this. For example, `frequenz.actor.example`\n will generate files in `src/frequenz/actor/example`.\n\n* `pypi_package_name`: The name of the PyPI/wheel/distribution package. This\n should be consistent with the `python_package`, usually replacing `.` with\n `-`. For example, `frequenz-actor-example`.\n\n* `github_repo_name`: The handle of the GitHub repository where the project\n will reside. This will be used to generate links to the project on GitHub and\n as the top-level directory name.\n\n* `default_codeowners`: A space-separated list of GitHub teams (`@org/team`) or\n users (`@user`) that will be the default code owners for this project. This\n will be used to build the `CODEOWNERS` file. Please refer to the [code owners\n documentation] for more details on the valid syntax.\n\n[code owners documentation]: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners\n\n\n[Please press any key to continue",
"type": "lib",
"name": "sdk",
"description": "A development kit to interact with the Frequenz development platform",
Expand All @@ -15,14 +16,41 @@
"default_codeowners": "@frequenz-floss/python-sdk-team",
"_extensions": [
"jinja2_time.TimeExtension",
"local_extensions.as_identifier",
"local_extensions.default_codeowners",
"local_extensions.github_repo_name",
"local_extensions.introduction",
"local_extensions.keywords",
"local_extensions.pypi_package_name",
"local_extensions.python_package",
"local_extensions.src_path",
"local_extensions.title"
],
"_template": "gh:frequenz-floss/frequenz-repo-config-python"
"_template": "gh:frequenz-floss/frequenz-repo-config-python",
},
"_cookiecutter": {
"Introduction": "{{cookiecutter | introduction}}",
"type": [
"actor",
"api",
"app",
"lib",
"model"
],
"name": null,
"description": null,
"title": "{{cookiecutter | title}}",
"keywords": "(comma separated: 'frequenz', <type> and <name> are included automatically)",
"github_org": "frequenz-floss",
"license": [
"MIT",
"Proprietary"
],
"author_name": "Frequenz Energy-as-a-Service GmbH",
"author_email": "[email protected]",
"python_package": "{{cookiecutter | python_package}}",
"pypi_package_name": "{{cookiecutter | pypi_package_name}}",
"github_repo_name": "{{cookiecutter | github_repo_name}}",
"default_codeowners": "(like @some-org/some-team; defaults to a team based on the repo type)"
}
}
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
python -m pip install -e .[dev-noxfile]

- name: Run nox
# To speed things up a bit we use the speciall ci_checks_max session
# To speed things up a bit we use the special ci_checks_max session
# that uses the same venv to run multiple linting sessions
run: nox -e ci_checks_max pytest_min
timeout-minutes: 10
Expand Down
14 changes: 12 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,25 @@
<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->

- `Channels` has been upgraded to version 0.16.0, for information on how to upgrade visit https://github.com/frequenz-floss/frequenz-channels-python/releases/tag/v0.16.0
- `Quantity` objects are no longer hashable. This is because of the pitfalls of hashing `float` values.

## New Features

- Add quantity class `Frequency` for frequency values.
- Add `abs()` support for quantities.
- Quantities

* Add `abs()`.
* Add a `isclose()` method on quantities to compare them to other values of the same type. Because `Quantity` types are just wrappers around `float`s, direct comparison might not always be desirable.
* Add `zero()` constructor (which returns a singleton) to easily get a zero value.
* Add multiplication by `Percentage` types.
* Add a new quantity class `Frequency` for frequency values.

- `FormulaEngine` arithmetics now supports scalar multiplication with floats and addition with Quantities
- Add a new method for streaming average temperature values for the battery pool.

## Bug Fixes

- Fix formatting issue for `Quantity` objects with zero values.
- Fix formatting isuse for `Quantity` when the base value is float.inf or float.nan.
- Fix clamping to 100% for the battery pool SoC scaling calculation.

<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
13 changes: 10 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ theme:
repo: fontawesome/brands/github
custom_dir: docs/overrides
features:
- content.code.annotate
- content.code.copy
- navigation.instant
- navigation.tabs
- navigation.top
Expand Down Expand Up @@ -62,16 +64,20 @@ markdown_extensions:
- admonition
- attr_list
- pymdownx.details
- pymdownx.superfences
- pymdownx.tasklist
- pymdownx.tabbed
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.keys
- pymdownx.snippets:
check_paths: true
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: "!!python/name:pymdownx.superfences.fence_code_format"
- pymdownx.tabbed
- pymdownx.tasklist
- toc:
permalink: "¤"

Expand All @@ -97,6 +103,7 @@ plugins:
show_root_members_full_path: true
show_source: true
import:
# See https://mkdocstrings.github.io/python/usage/#import for details
- https://docs.python.org/3/objects.inv
- https://frequenz-floss.github.io/frequenz-channels-python/v0.14/objects.inv
- https://grpc.github.io/grpc/python/objects.inv
Expand Down
20 changes: 10 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
requires = [
"setuptools == 67.7.2",
"setuptools_scm[toml] == 7.1.0",
"frequenz-repo-config[lib] == 0.3.0",
"frequenz-repo-config[lib] == 0.4.0",
]
build-backend = "setuptools.build_meta"

Expand All @@ -14,7 +14,7 @@ name = "frequenz-sdk"
description = "A development kit to interact with the Frequenz development platform"
readme = "README.md"
license = { text = "MIT" }
keywords = ["frequenz", "sdk", "microgrid", "actor"]
keywords = ["frequenz", "python", "lib", "library", "sdk", "microgrid"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand Down Expand Up @@ -54,27 +54,27 @@ dev-docstrings = [
"darglint == 1.8.1",
"tomli == 2.0.1", # Needed by pydocstyle to read pyproject.toml
]
dev-examples = ["polars == 0.18.7"]
dev-examples = ["polars == 0.18.11"]
dev-formatting = ["black == 23.7.0", "isort == 5.12.0"]
dev-mkdocs = [
"mike == 1.1.2",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.0",
"mkdocs-material == 9.1.18",
"mkdocs-material == 9.1.21",
"mkdocs-section-index == 0.3.5",
"mkdocstrings[python] == 0.22.0",
"frequenz-repo-config[lib] == 0.3.0",
"frequenz-repo-config[lib] == 0.4.0",
]
dev-mypy = [
"mypy == 1.4.1",
"grpc-stubs == 1.24.12", # This dependency introduces breaking changes in patch releases
"types-protobuf == 4.23.0.1",
"types-protobuf == 4.23.0.2",
# For checking the noxfile, docs/ script, and tests
"frequenz-sdk[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = ["nox == 2023.4.22", "frequenz-repo-config[lib] == 0.3.0"]
dev-noxfile = ["nox == 2023.4.22", "frequenz-repo-config[lib] == 0.4.0"]
dev-pylint = [
"pylint == 2.17.4",
"pylint == 2.17.5",
# For checking the noxfile, docs/ script, and tests
"frequenz-sdk[dev-mkdocs,dev-noxfile,dev-pytest]",
]
Expand All @@ -86,7 +86,7 @@ dev-pytest = [
"async-solipsism == 0.5",
# For checking docstring code examples
"sybil == 5.0.3",
"pylint == 2.17.4",
"pylint == 2.17.5",
"frequenz-sdk[dev-examples]",
]
dev = [
Expand All @@ -107,7 +107,7 @@ include = '\.pyi?$'
[tool.isort]
profile = "black"
line_length = 88
src_paths = ["src", "examples", "tests"]
src_paths = ["benchmarks", "examples", "src", "tests"]

[tool.pylint.similarities]
ignore-comments = ['yes']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def get_channel_name(self) -> str:
ComponentMetricId.CAPACITY: lambda msg: msg.capacity,
ComponentMetricId.POWER_LOWER_BOUND: lambda msg: msg.power_lower_bound,
ComponentMetricId.POWER_UPPER_BOUND: lambda msg: msg.power_upper_bound,
ComponentMetricId.TEMPERATURE: lambda msg: msg.temperature,
}

_InverterDataMethods: Dict[ComponentMetricId, Callable[[InverterData], float]] = {
Expand Down
20 changes: 20 additions & 0 deletions src/frequenz/sdk/actor/power_distributing/_battery_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class _BlockingStatus:
max_duration_sec: float

def __post_init__(self) -> None:
assert self.min_duration_sec <= self.max_duration_sec, (
f"Minimum blocking duration ({self.min_duration_sec}) cannot be greater "
f"than maximum blocking duration ({self.max_duration_sec})"
)
self.last_blocking_duration_sec: float = self.min_duration_sec
self.blocked_until: Optional[datetime] = None

Expand Down Expand Up @@ -335,9 +339,25 @@ async def _run(
self._handle_status_set_power_result(selected.value)

elif selected_from(selected, battery_timer):
if (
datetime.now(tz=timezone.utc)
- self._battery.last_msg_timestamp
) < timedelta(seconds=self._max_data_age):
# This means that we have received data from the battery
# since the timer triggered, but the timer event arrived
# late, so we can ignore it.
continue
self._handle_status_battery_timer()

elif selected_from(selected, inverter_timer):
if (
datetime.now(tz=timezone.utc)
- self._inverter.last_msg_timestamp
) < timedelta(seconds=self._max_data_age):
# This means that we have received data from the inverter
# since the timer triggered, but the timer event arrived
# late, so we can ignore it.
continue
self._handle_status_inverter_timer()

else:
Expand Down
2 changes: 2 additions & 0 deletions src/frequenz/sdk/microgrid/component/_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,5 @@ class ComponentMetricId(Enum):

ACTIVE_POWER_LOWER_BOUND = "active_power_lower_bound"
ACTIVE_POWER_UPPER_BOUND = "active_power_upper_bound"

TEMPERATURE = "temperature"
6 changes: 3 additions & 3 deletions src/frequenz/sdk/microgrid/component/_component_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ class BatteryData(ComponentData):
This will be a positive number, or zero if no charging is possible.
"""

temperature_max: float
"""The maximum temperature of all the blocks in a battery, in Celcius (°C)."""
temperature: float
"""The (average) temperature reported by the battery, in Celcius (°C)."""

_relay_state: battery_pb.RelayState.ValueType
"""State of the battery relay."""
Expand Down Expand Up @@ -172,7 +172,7 @@ def from_proto(cls, raw: microgrid_pb.ComponentData) -> BatteryData:
capacity=raw.battery.properties.capacity,
power_lower_bound=raw.battery.data.dc.power.system_bounds.lower,
power_upper_bound=raw.battery.data.dc.power.system_bounds.upper,
temperature_max=raw.battery.data.temperature.max,
temperature=raw.battery.data.temperature.avg,
_relay_state=raw.battery.state.relay_state,
_component_state=raw.battery.state.component_state,
_errors=list(raw.battery.errors),
Expand Down
2 changes: 2 additions & 0 deletions src/frequenz/sdk/timeseries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
Percentage,
Power,
Quantity,
Temperature,
Voltage,
)
from ._resampling import ResamplerConfig
Expand All @@ -63,6 +64,7 @@
"Current",
"Energy",
"Power",
"Temperature",
"Voltage",
"Frequency",
"Percentage",
Expand Down
Loading