Python client for fetching consumption data from the Brunata Munich user portal
(nutzerportal.brunata-muenchen.de). Intended as a basis for a Home Assistant integration.
Early/experimental project. The Munich instance uses SAP OData (UI5 frontend).
- Login:
NP_REG_LOGON_SRV_01(CredentialSetvia$batch) - Data:
NP_APPLAUNCHER_SRV,NP_DASHBOARD_SRV(e.g. monthly values)
This is an unofficial, independent open-source project and is not affiliated with BRUNATA-METRONA or BRUdirekt.
Use of this client may be subject to the portal's terms of service and applicable law. You are responsible for complying with them.
Use only with your own account / proper authorization, do not share credentials, and avoid aggressive polling.
Trademarks and product names (e.g. BRUdirekt, BRUNATA-METRONA) belong to their respective owners.
poetry installCreate a .env in the project root (it will not be committed due to .gitignore):
BRUNATA_USERNAME=you@example.com
BRUNATA_PASSWORD=your-password
BRUNATA_BASE_URL=https://nutzerportal.brunata-muenchen.de
BRUNATA_SAP_CLIENT=201Test login:
poetry run brunata loginDump account + available periods/cost types (warning: may contain personal data):
poetry run brunata dump-pages --output-dir .brunata-dumpFetch consumption data:
poetry run brunata readings --kind heating
poetry run brunata readings --kind hot_waterFetch consumption data for all cost types (e.g. HZ01, HZ02, ... / WW01, WW02, ...):
poetry run brunata readings-all --kind heating
poetry run brunata readings-all --kind hot_waterFetch meter readings (cumulative index):
poetry run brunata meterFetch "current consumption" (as shown in the dashboard):
poetry run brunata current --kind heating
poetry run brunata current --kind hot_waterFetch building/national consumption comparison (kWh/m²):
poetry run brunata comparisonFetch forecast and year-over-year comparison:
poetry run brunata forecastFetch room-level consumption breakdown:
poetry run brunata roomsThe client is async and suitable for Home Assistant's DataUpdateCoordinator patterns:
from brunata_api import BrunataClient, ReadingKind
async def fetch():
async with BrunataClient(
base_url="https://nutzerportal.brunata-muenchen.de",
username="...",
password="...",
sap_client="201",
) as client:
await client.login()
heating = await client.get_readings(ReadingKind.heating)
hot_water = await client.get_readings(ReadingKind.hot_water)
return heating, hot_waterKey methods:
BrunataClient.login()BrunataClient.get_account()BrunataClient.get_periods()– list of dashboard periods (start/end); use to see which year a value belongs toBrunataClient.get_supported_cost_types()BrunataClient.get_readings(...)BrunataClient.get_monthly_consumption(cost_type=..., in_kwh=..., period_index=...)BrunataClient.get_monthly_consumptions(kind, in_kwh=..., period_index=...)BrunataClient.get_meter_readings(period_index=...)(allHZ..andWW.., keyed bycost_type)BrunataClient.get_current_consumption(kind, period_index=...)(YTD for the selected period)BrunataClient.get_consumption_comparison(period_index=...)– building/national average (kWh/m²) per cost typeBrunataClient.get_consumption_forecast(period_index=...)– forecast, previous year, difference per cost typeBrunataClient.get_room_consumption(period_index=...)– room-level breakdown per cost type
Periods and yearly reset: The portal exposes data per dashboard period (usually one per calendar year). Cumulative values (meter reading, “current consumption”) are per period and typically reset when a new year starts. Default is period_index=0 (first period, often the current year). Use get_periods() to list periods and period_index to request a specific one (e.g. period_index=1 for the previous year). Integrations (e.g. Home Assistant) can use this to show “2024 total” vs “2025 YTD” or to handle the reset (e.g. new sensor per year or state_class per period).
poetry run ruff check src tests
poetry run pytestpoetry build
poetry publish --build