Metadata-Version: 2.4
Name: brunata-nutzerportal-api
Version: 0.2.0
Summary: Async client for BRUdirekt (Brunata) portal
License: MIT License
         
         Copyright (c) 2026 Felix Fricke
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
License-File: LICENSE
Keywords: brunata,brudirekt,home-assistant,meter,energy
Author: Felix Fricke
Requires-Python: >=3.11,<4.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Dist: httpx (>=0.28.1,<0.29.0)
Requires-Dist: pydantic (>=2.12.2,<3.0.0)
Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
Project-URL: Issues, https://github.com/fjfricke/brunata-api/issues
Project-URL: Repository, https://github.com/fjfricke/brunata-api
Description-Content-Type: text/markdown

# brunata-nutzerportal-api

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.

## Status

Early/experimental project. The Munich instance uses **SAP OData** (UI5 frontend).

- **Login**: `NP_REG_LOGON_SRV_01` (`CredentialSet` via `$batch`)
- **Data**: `NP_APPLAUNCHER_SRV`, `NP_DASHBOARD_SRV` (e.g. monthly values)

## Disclaimer

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.

## Installation (Poetry)

```bash
poetry install
```

## Configuration

Create a `.env` in the project root (it will not be committed due to `.gitignore`):

```env
BRUNATA_USERNAME=you@example.com
BRUNATA_PASSWORD=your-password
BRUNATA_BASE_URL=https://nutzerportal.brunata-muenchen.de
BRUNATA_SAP_CLIENT=201
```

## CLI

Test login:

```bash
poetry run brunata login
```

Dump account + available periods/cost types (warning: may contain personal data):

```bash
poetry run brunata dump-pages --output-dir .brunata-dump
```

Fetch consumption data:

```bash
poetry run brunata readings --kind heating
poetry run brunata readings --kind hot_water
```

Fetch consumption data for **all** cost types (e.g. `HZ01`, `HZ02`, ... / `WW01`, `WW02`, ...):

```bash
poetry run brunata readings-all --kind heating
poetry run brunata readings-all --kind hot_water
```

Fetch meter readings (cumulative index):

```bash
poetry run brunata meter
```

Fetch "current consumption" (as shown in the dashboard):

```bash
poetry run brunata current --kind heating
poetry run brunata current --kind hot_water
```

## Library usage (Home Assistant)

The client is async and suitable for Home Assistant's DataUpdateCoordinator patterns:

```python
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_water
```

Key methods:
- `BrunataClient.login()`
- `BrunataClient.get_account()`
- `BrunataClient.get_periods()` – list of dashboard periods (start/end); use to see which year a value belongs to
- `BrunataClient.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=...)` (all `HZ..` and `WW..`, keyed by `cost_type`)
- `BrunataClient.get_current_consumption(kind, period_index=...)` (YTD for the selected period)

**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).

## Development

```bash
poetry run ruff check src tests
poetry run pytest
```

## Packaging (optional)

```bash
poetry build
poetry publish --build
```


