Releases: frequenz-floss/frequenz-client-microgrid-python
v0.18.2
Frequenz Microgrid API Client Release Notes
Summary
This release reintroduces sensor support that was temporarily removed in the v0.18.0 release. The new sensor API has been redesigned to fit the updated component and metrics model introduced in v0.18.0.
New Features
-
New
sensormodule (frequenz.client.microgrid.sensor) with sensor related types. -
New
MicrogridApiClientmethodslist_sensors(): fetch sensor metadata.receive_sensor_telemetry_stream(): stream sensor telemetry data.
Example:
import asyncio
from frequenz.client.microgrid import MicrogridApiClient
from frequenz.client.microgrid.metrics import Metric
URL = "grpc://[::1]:62060"
async def main() -> None:
print(f"Connecting to {URL}...")
async with MicrogridApiClient(URL) as client:
print("Listing available sensors...")
sensors = list(await client.list_sensors())
if not sensors:
print("No sensors found.")
return
print(f"Found {len(sensors)}: {sensors}.")
print()
sensor = sensors[0]
print(f"Streaming telemetry from sensor {sensor.id} ({sensor.name})...")
telemetry_stream = client.receive_sensor_telemetry_stream(
sensors[0].id, list(Metric)
)
async for telemetry in telemetry_stream:
print(f"\tReceived: {telemetry}")
asyncio.run(main())Upgrading (from v0.9)
Sensor support restored with new API
Sensor support that was removed in v0.18.0 is now back, but with a redesigned API that aligns with the v0.18.0 component and metrics model.
list_sensors()
The method name remains the same, but the signature and return type have changed:
# Old v0.9.1 API
sensors: Iterable[Sensor] = await client.list_sensors()
# New v0.18.2 API (same method name, different types)
from frequenz.client.common.microgrid.sensors import SensorId
from frequenz.client.microgrid.sensor import Sensor
sensors: Iterable[Sensor] = await client.list_sensors()
# You can also filter by sensor IDs
sensors = await client.list_sensors(sensors=[SensorId(1), SensorId(2)])The Sensor class now provides a new attribute microgrid_id: MicrogridId and the identity property now returns a tuple (SensorId, MicrogridId) instead of just SensorId.
stream_sensor_data() → receive_sensor_telemetry_stream()
The streaming method has been renamed and its return type changed:
# Old v0.9.1 API
from frequenz.client.microgrid.sensor import SensorDataSamples, SensorMetric
receiver: Receiver[SensorDataSamples] = client.stream_sensor_data(
sensor=SensorId(1),
metrics=[SensorMetric.TEMPERATURE, SensorMetric.HUMIDITY], # optional
)
async for samples in receiver:
# samples.metric_samples, samples.state_sample, etc.
...
# New v0.18.2 API
from frequenz.client.microgrid.sensor import SensorTelemetry
from frequenz.client.microgrid.metrics import Metric
receiver: Receiver[SensorTelemetry] = client.receive_sensor_telemetry_stream(
sensor=SensorId(1),
metrics=[Metric.SENSOR_TEMPERATURE, Metric.AC_VOLTAGE], # required
)
async for telemetry in receiver:
# telemetry.sensor_id: SensorId
# telemetry.metric_samples: Sequence[MetricSample]
# telemetry.state_snapshots: Sequence[SensorStateSnapshot]
for sample in telemetry.metric_samples:
print(f"{sample.metric}: {sample.value} at {sample.sampled_at}")
...Key differences:
- Method renamed:
stream_sensor_data()→receive_sensor_telemetry_stream() - Metrics parameter is now required: You must specify which metrics to stream. The old API allowed
Noneto stream all metrics. - Uses unified
Metricenum: The oldSensorMetricenum is removed. Usefrequenz.client.microgrid.metrics.Metricinstead. - Return type changed:
SensorDataSamples→SensorTelemetry - State samples changed:
SensorStateSample→SensorStateSnapshotwith different structure (see below)
Sensor state types
The sensor state types have been redesigned:
| Old v0.9.1 type | New v0.18.2 type |
|---|---|
SensorMetric |
Removed — use Metric |
SensorStateCode |
SensorStateCode (different values) |
SensorErrorCode |
SensorDiagnosticCode |
SensorStateSample |
SensorStateSnapshot |
SensorMetricSample |
MetricSample |
SensorDataSamples |
SensorTelemetry |
The new SensorStateSnapshot structure:
@dataclass(frozen=True, kw_only=True)
class SensorStateSnapshot:
origin_time: datetime # was `sampled_at`
states: Set[SensorStateCode | int] # was `frozenset`
warnings: Sequence[SensorDiagnostic] # new
errors: Sequence[SensorDiagnostic] # replaces error codesThe new SensorDiagnostic provides richer error/warning information:
@dataclass(frozen=True, kw_only=True)
class SensorDiagnostic:
diagnostic_code: SensorDiagnosticCode | int
message: str | None
vendor_diagnostic_code: str | NoneImport changes
Update your imports for sensor types:
# Old v0.9.1
from frequenz.client.microgrid.sensor import (
Sensor,
SensorDataSamples,
SensorErrorCode,
SensorMetric,
SensorMetricSample,
SensorStateCode,
SensorStateSample,
)
# New v0.18.2
from frequenz.client.microgrid.sensor import (
Sensor,
SensorDiagnostic,
SensorDiagnosticCode,
SensorStateCode,
SensorStateSnapshot,
SensorTelemetry,
)
from frequenz.client.microgrid.metrics import Metric, MetricSample
from frequenz.client.common.microgrid.sensors import SensorIdWhat's Changed
Full Changelog: v0.18.1...v0.18.2
v0.18.1
Frequenz Microgrid API Client Release Notes
Summary
This release adds a new WindTurbine component type.
Upgrading
- If you are using
matchand doing exhaustive matching on theComponenttypes, you will getmypyerrors and will need to handle the newWindTurbinetype.
New Features
- Add
WindTurbinecomponent type.
What's Changed
- Bump pytest-asyncio from 1.2.0 to 1.3.0 by @dependabot[bot] in #222
- Add WindTurbine by @nhatcher-frequenz in #223
- Bump actions/checkout from 5 to 6 by @dependabot[bot] in #213
- Bump the patch group with 4 updates by @dependabot[bot] in #214
- Bump types-protobuf from 6.32.1.20250918 to 6.32.1.20251105 by @dependabot[bot] in #218
- Bump frequenz-floss/gh-action-nox from 1.0.1 to 1.1.0 in the compatible group by @dependabot[bot] in #212
- Bump mkdocstrings[python] from 0.30.1 to 1.0.0 by @dependabot[bot] in #217
- Bump isort from 6.1.0 to 7.0.0 by @dependabot[bot] in #206
- Bump pydoclint from 0.7.6 to 0.8.3 by @dependabot[bot] in #219
- Bump pytest from 8.4.2 to 9.0.1 by @dependabot[bot] in #220
- Update release notes for the v0.18.1 release by @llucax in #225
- Bump the minor group with 7 updates by @dependabot[bot] in #215
- Bump the patch group with 2 updates by @dependabot[bot] in #226
- Bump mkdocs-gen-files from 0.5.0 to 0.6.0 by @dependabot[bot] in #216
New Contributors
- @nhatcher-frequenz made their first contribution in #223
Full Changelog: v0.18.0...v0.18.1
v0.19.0
Frequenz Microgrid API Client Release Notes
Warning
This release was supposed to be v0.18.1, please don't use it. Use v0.18.1 instead.
v0.18.0
Frequenz Microgrid API Client Release Notes
Summary
This release is a major breaking change. The client now targets the Microgrid API specification version 0.18.x and the v1 namespace in frequenz-api-common. Both upstream projects introduce large structural and naming changes to components, metrics, and telemetry, and this client has been refactored accordingly.
Existing code written for frequenz-client-microgrid v0.9.1 will not work without changes. Upgrading will typically require:
- Bumping dependencies to the new API and common libraries.
- Updating imports for components, metrics, and IDs.
- Migrating from the old ad-hoc component and sensor APIs to the new component/metrics model.
- Adapting to the new power-control and bounds APIs.
For a full overview of upstream changes, consult the Microgrid API releases and Common API releases.
Upgrading
The following notes are aimed at users upgrading from frequenz-client-microgrid v0.9.1.
Dependencies and imports
-
Dependencies:
frequenz-api-microgridis now required at>= 0.18.0, < 0.19.0.frequenz-api-commonis now required at>= 0.8.0, < 1.0.0and uses thev1namespace.frequenz-client-commonis now required at>= 0.3.6, < 0.4.0and provides ID and helper types used throughout the client.
Make sure you pin compatible versions in your own project when upgrading.
-
IDs and common types:
IDs come from
frequenz.client.common(this was already true inv0.9.1, but they are now used more consistently):from frequenz.client.common.microgrid import MicrogridId from frequenz.client.common.microgrid.components import ComponentId
-
Components and metrics:
The old component and data types (
Component,ComponentCategory,BatteryData,InverterData,ComponentState*, etc.) that used to live directly underfrequenz.client.microgridhave been replaced with a richer component and metrics model:from frequenz.client.microgrid import MicrogridApiClient from frequenz.client.microgrid import component, metrics # Example component types from frequenz.client.microgrid.component import ( Component, ComponentCategory, ComponentConnection, ComponentDataSamples, ComponentStateSample, GridConnectionPoint, Inverter, Battery, ) # Metrics and bounds from frequenz.client.microgrid.metrics import Metric, Bounds, MetricSample
Update your imports to use these new modules instead of the removed legacy types.
Metadata: metadata() → get_microgrid_info()
The old metadata() method has been replaced by get_microgrid_info() which returns a richer MicrogridInfo object.
Listing components and connections
In v0.9.1 you would often use:
components = await client.components()
connections = await client.connections(starts={component_id}, ends=set())Now:
-
List components:
components = await client.list_components( components=[ComponentId(1), ComponentId(2)], categories=[ComponentCategory.INVERTER, ComponentCategory.BATTERY], )
Notes:
componentsmay containComponentIdinstances orComponentobjects.categoriesmay containComponentCategoryenum values or raw integer category IDs.- Filters across
componentsandcategoriesare combined withAND; values inside each list are combined withOR.
-
List connections:
connections = await client.list_connections( sources=[ComponentId(1)], destinations=[ComponentId(2)], )
Notes:
sourcesanddestinationsacceptComponentIdorComponentinstances.- Filters across
sourcesanddestinationsare combined withAND; values inside each list are combined withOR. - Connections now also use
.sourceand.destinationterminology instead of.startand.end.
Sensors: list_sensors(), stream_sensor_data() → removed (temporary)
The old list_sensors() and stream_sensor_data() method has no direct equivalent. It will be reintroduced in a future release once sensor abstractions are reworked to fit the new component and metrics model.
Power control: set_power() / set_reactive_power() → set_component_power_active() / set_component_power_reactive()
In v0.9.1 you would typically set power using methods like:
await client.set_power(component_id, power_w)
await client.set_reactive_power(component_id, reactive_power_var)These methods have been replaced with lifetime-aware, metric-aligned calls:
# Active power in watts
expiry = await client.set_component_power_active(
component=ComponentId(1),
power_w=1_000.0,
request_lifetime=timedelta(seconds=30),
)
# Reactive power in volt-ampere reactive (var)
expiry = await client.set_component_power_reactive(
component=ComponentId(1),
power_var=500.0,
request_lifetime=timedelta(seconds=30),
)- Both methods accept either
ComponentIdorComponentinstances.
Bounds: set_bounds() → add_component_bounds()
In v0.9.1, power bounds were earlier set using methods like set_bounds(component_id, lower, upper).
Now the new API reflects the v0.18 metrics semantics: bounds are attached to metrics and transported as part of telemetry samples. Use add_component_bounds() together with Metric and Bounds:
await client.add_component_bounds(
component=ComponentId(1),
target=Metric.ACTIVE_POWER,
bounds=[Bounds(lower=-1_000.0, upper=1_000.0)],
)Notes:
- Bounds are now metric-specific: you must specify a
Metricwhen adding bounds. - Bounds are represented as at most two ranges, matching
frequenz-api-commonv1(Boundsmay contain up to two inclusive ranges).
Streaming telemetry: *_data() → receive_component_data_samples_stream()
The streaming model changed significantly.
In v0.9.1, you would use:
receiver = await client.meter_data(component_id)
async for sample in receiver:
# sample is a MeterData instance
...Now, telemetry is integrated around components and metrics using receive_component_data_samples_stream() and ComponentDataSamples:
receiver: Receiver[ComponentDataSamples] = (
await client.receive_component_data_samples_stream(
component=ComponentId(1),
metrics=[Metric.ACTIVE_POWER, Metric.REACTIVE_POWER],
)
)
async for samples in receiver:
# Each `samples` corresponds to a single component at a single timestamp.
# Metric values and bounds are attached per metric.The upstream Microgrid API v0.18 changes how samples are structured; important points from the upstream migration notes (see frequenz-api-microgrid discussion #278):
- Rated bounds moved into component metadata; telemetry samples now carry operational bounds per metric.
- Old
component_boundsandsystem_{inclusion,exclusion}_boundsare unified undersamples.metric[x].bounds. - Older voltage metrics like
VOLTAGE_PHASE_Amap toAC_VOLTAGE_PHASE_A_Nand similar; review metric names infrequenz.client.microgrid.metrics.Metricwhen porting code. - All metrics for a given component at a given time share the same
sampled_attimestamp. - At most one
ComponentStateis included perComponentData.
When migrating:
- Prefer requesting only the metrics you actually consume.
- Use the new bounds representation instead of any previously maintained client-side bounds fields.
- Replace sensor-centric streams with component-centric streams; each telemetry message now contains all requested metrics for a component.
New Features
- Add
get_microgrid_info()returning a richMicrogridInfodataclass with ID, enterprise, location, delivery area, status, and timestamps. - Add a metrics model under
frequenz.client.microgrid.metricsincluding theMetricenum,Bounds, andMetricSample/AggregatedMetricValue. - Add high-level methods on
MicrogridApiClientfor listing components and connections, adding component bounds, receiving component data samples streams, and controlling active/reactive power with lifetimes.
Bug Fixes
- Restore missing
Metricenum members to match the upstream common API definitions. - Remove an artificial timeout from the gRPC telemetry stream to avoid spurious cancellations under normal operation.
- Align error handling and validation with the updated API behavior (for example, validating lifetimes and power ranges before sending control requests).
What's Changed
- Initial upgrade to the API v0.17.x by @llucax in #94
- Add gRPC calls to control components by @llucax in #158
- Implement
ListComponentsby @llucax in #165 - Implement
ListConnectionsby @llucax in #167 - Clear release notes by @llucax in #177
- Rename objects returned by calls to
responseinternally by @llucax in #179 - Implement
ReceiveComponentDataStreamRequestby @llucax in #178 - Bump the patch group with 3 updates by @dependabot[bot] in #185
- Bump types-markdown from 3.8.0.20250708 to 3.8.0.20250809 by @dependabot[bot] in #187
- Bump mkdocstrings-python from 1.16.12 to 1.18.2 in the mkdocstrings grou...
v0.9.1
Frequenz Microgrid API Client Release Notes
Summary
This release removes the timezonefinder dependency to significantly reduce package size by 66M+ and enable ARM platform support.
Warning
This is a breaking change shipped in a patch release because this feature has no known users.
Upgrading
The Location.timezone field no longer performs automatic timezone lookup from latitude/longitude coordinates.
# Automatic timezone lookup (no longer works)
location = Location(latitude=52.52, longitude=13.405)
print(location.timezone) # Previously: ZoneInfo('Europe/Berlin'), now NoneIf you need timezone lookup from coordinates, install timezonefinder separately and implement manual lookup:
# Install: pip install timezonefinder
from timezonefinder import TimezoneFinder
from zoneinfo import ZoneInfo
from frequenz.client.microgrid import Location
tf = TimezoneFinder()
tz_name = tf.timezone_at(lat=52.52, lng=13.405)
timezone = ZoneInfo(tz_name) if tz_name else None
location = Location(latitude=52.52, longitude=13.405, timezone=timezone)What's Changed
- Clear release notes by @llucax in #157
- Bump the minor group with 2 updates by @dependabot[bot] in #163
- Bump the patch group with 5 updates by @dependabot[bot] in #162
- Bump pytest-asyncio from 0.26.0 to 1.0.0 by @dependabot[bot] in #164
- Remove timezonefinder dependency by @Copilot in #168
- Bump mkdocs-material from 9.6.14 to 9.6.16 in the patch group by @dependabot[bot] in #169
- Bump mypy from 1.16.1 to 1.17.1 in the minor group by @dependabot[bot] in #170
- Bump types-markdown from 3.8.0.20250415 to 3.8.0.20250708 by @dependabot[bot] in #172
- Bump pytest-asyncio from 1.0.0 to 1.1.0 by @dependabot[bot] in #174
- Bump mkdocstrings[python] from 0.29.1 to 0.30.0 in the mkdocstrings group by @dependabot[bot] in #171
- Bump async-solipsism from 0.7 to 0.8 by @dependabot[bot] in #175
- Bump types-protobuf from 6.30.2.20250516 to 6.30.2.20250703 by @dependabot[bot] in #173
- Bump the compatible group with 2 updates by @dependabot[bot] in #176
New Contributors
- @Copilot made their first contribution in #168
Full Changelog: v0.9.0...v0.9.1
v0.9.0
Frequenz Microgrid API Client Release Notes
Summary
This is a small release to allow for easier interoperability between different APIs.
Upgrading
-
Some minimum dependency versions are bumped, so you might need to update your dependencies as well.
-
The IDs (
MicrogridId,ComponentId,SensorId) are now imported fromfrequenz-client-common. Please add it to your dependencies if you haven't already, then you can replace your imports:from frequenz.client.microgrid import MicrogridId->from frequenz.client.common.microgrid import MicrogridIdfrom frequenz.client.microgrid import ComponentId->from frequenz.client.common.microgrid.components import ComponentIdfrom frequenz.client.microgrid import SensorId->from frequenz.client.common.microgrid.sensors import SensorId
What's Changed
- Clear release notes by @llucax in #150
- Allow base-client to be updated to 0.11.0 by @Marenz in #151
- Bump types-protobuf from 5.29.1.20250403 to 6.30.2.20250516 by @dependabot in #154
- Bump the patch group with 6 updates by @dependabot in #152
- Bump the minor group with 2 updates by @dependabot in #153
- Use IDs from frequenz-client-common by @llucax in #156
Full Changelog: v0.8.0...v0.9.0
v0.8.0
Frequenz Microgrid API Client Release Notes
Summary
This release introduces sensors support and adds official support for Python 3.12. It also includes some bug fixes.
Upgrading
- Some minimum versions of dependencies have been bumped to support Python 3.12. You might also need to bump these dependencies in your project.
- The ID classes (
MicrogridId,ComponentId, etc.) were moved to thefrequenz.client.microgrid.idmodule. They will be moved again, to frequenz-client-common in a near future.
New Features
- The
MicrogridApiClientcan now list sensor retrieving their metadata (list_sensors()) and can stream sensor data (stream_sensor_data()).
Bug Fixes
- When retrieving the microgrid metadata using
metadata(), if the location was empty in the protobuf message, a wrong location with long=0, lat=0 was used. Now the location will be properly set toNonein that case. - The client now does some missing cleanup (stopping background tasks) when disconnecting (and when used as a context manager).
What's Changed
- Exclude repo-config from dependabot grouping by @llucax in #125
- Update protobuf requirement from <6,>=4.21.6 to >=4.21.6,<7 by @dependabot in #129
- Bump setuptools from 75.8.2 to 78.1.0 by @dependabot in #130
- Bump the required group with 6 updates by @dependabot in #126
- Bump types-protobuf from 5.29.1.20250208 to 5.29.1.20250315 by @dependabot in #128
- Bump types-markdown from 3.7.0.20241204 to 3.7.0.20250322 by @dependabot in #127
- Clear release notes by @llucax in #124
- Update to repo-config v0.13 by @llucax in #132
- Bump the patch group with 2 updates by @dependabot in #133
- Bump pydoclint from 0.6.2 to 0.6.4 by @dependabot in #135
- Bump flake8 from 7.1.2 to 7.2.0 in the minor group by @dependabot in #134
- Bump grpc-stubs from 1.53.0.5 to 1.53.0.6 by @dependabot in #142
- Bump types-protobuf from 5.29.1.20250315 to 5.29.1.20250403 by @dependabot in #141
- Bump pydoclint from 0.6.4 to 0.6.6 by @dependabot in #139
- Bump setuptools from 78.1.0 to 80.1.0 by @dependabot in #140
- Bump the patch group with 4 updates by @dependabot in #137
- Bump the minor group across 1 directory with 5 updates by @dependabot in #143
- Fix cleanup and missing location metadata by @llucax in #145
- Add sensors listing and data streaming by @llucax in #146
- Fix sensor data streaming without metrics filter by @llucax in #148
- Prepare release notes for release v0.8.0 by @llucax in #149
Full Changelog: v0.7.0...v0.8.0
v0.7.0
Frequenz Microgrid API Client Release Notes
Upgrading
-
Now component and microgrid IDs are wrapped in new classes:
ComponentIdandMicrogridIdrespectively.These classes provide type safety and prevent accidental errors by:
- Making it impossible to mix up microgrid and component IDs (equality comparisons between different ID types always return false).
- Preventing accidental math operations on IDs.
- Providing clear string representations for debugging (MID42, CID42).
- Ensuring proper hash behavior in collections.
To migrate you just need to wrap your
intIDs with the appropriate class:0->ComponentId(0)/MicrogridId(0).
What's Changed
- Clear release notes by @shsms in #117
- Bump nox from 2024.10.9 to 2025.2.9 by @dependabot in #119
- Bump types-protobuf from 5.29.1.20241207 to 5.29.1.20250208 by @dependabot in #120
- Bump the required group across 1 directory with 12 updates by @dependabot in #121
- Add ID wrapper classes by @llucax in #122
- Prepare for release v0.7.0 by @llucax in #123
Full Changelog: v0.6.1...v0.7.0
v0.6.1
Frequenz Microgrid API Client Release Notes
Upgrading
- Widen
frequenz-client-basedependency to allowv0.9.0.
What's Changed
- Clear release notes by @llucax in #102
- Bump setuptools-scm[toml] from 7.1.0 to 8.1.0 by @dependabot in #105
- Bump setuptools from 68.1.0 to 75.6.0 by @dependabot in #104
- Bump the required group across 1 directory with 6 updates by @dependabot in #106
- Bump types-markdown from 3.7.0.20240822 to 3.7.0.20241204 by @dependabot in #108
- Bump the required group across 1 directory with 7 updates by @dependabot in #109
- Bump black from 24.10.0 to 25.1.0 by @dependabot in #111
- Bump the required group across 1 directory with 7 updates by @dependabot in #114
- Revert "Enable autorefs plugin option to resolve closest references" by @llucax in #115
- Bump isort from 5.13.2 to 6.0.0 by @dependabot in #112
- Widen
frequenz-client-basedependency to allowv0.9.0by @shsms in #116
Full Changelog: v0.6.0...v0.6.1
v0.6.0
Frequenz Microgrid API Client Release Notes
Upgrading
-
ApiClient:- The class was renamed to
MicrogridApiClient. - The
apiattribute was renamed tostub. - The constructor parameter
channel_optionswas renamed tochannels_defaultsto match the name used inBaseApiClient. - The constructor now accepts a
connectparameter, which isTrueby default. If set toFalse, the client will not connect to the server upon instantiation. You can connect later by calling theconnect()method.
- The class was renamed to
- The
frequenz-client-basedependency was bumped to v0.8.0.
New Features
- The client now inherits from
frequenz.client.base.BaseApiClient, so it provides a few new features, likedisconnect()ing or using it as a context manager. Please refer to theBaseApiClientdocumentation for more information on these features. - The client now supports setting reactive power for components through the new
set_reactive_powermethod.
What's Changed
- Clear release notes by @llucax in #87
- Inherit from
BaseApiClientby @llucax in #88 - Use
call_stub_method()to call stub methods by @llucax in #89 - Remove duplicated
show_symbol_type_tockey inmkdocs.ymlby @llucax in #90 - Bump mkdocstrings dependencies by @llucax in #91
- Bump the required group with 5 updates by @dependabot in #92
- Bump the required group with 7 updates by @dependabot in #95
- Bump types-protobuf from 4.21.0.7 to 5.28.3.20241030 by @dependabot in #97
- Add the
set_reactive_powermethod by @shsms in #99 - Update the
client-basedependency to v0.8.0 by @llucax in #100 - Prepare for the v0.6.0 release by @llucax in #101
Full Changelog: v0.5.1...v0.6.0