Repository navigation
Archive 1.1.8 Design Documentation
This page describes the Home Assistant 2025.12 / integration 1.1.8 design. It is kept for historical reference and for users still running the
mainbranch (v1.1.8) or an older release.👉 For the current design, see the Architecture Design Document and the Software Design Document (integration 1.2.x, branch
HA2026_09_dev, Home Assistant 2026.9+).Back to the Documentation home.
The Austria Smartmeter Integration is a custom component for Home Assistant designed to retrieve energy data (consumption and production) from Austrian grid operators via their official web portals. It acts as a bridge between the proprietary APIs of the grid operators (e.g., Wiener Netze, Netz NÖ) and the Home Assistant state machine.
The integration follows the standard Home Assistant architecture for polling integrations (Cloud Polling).
-
Config Flow (
config_flow.py): Handles user input, authentication (username/password), and creates the Config Entry. -
DataUpdateCoordinator (
coordinator.py): The central brain. It polls the API at a defined interval (default: 6h), handles authentication renewal, and stores the latest data blob in memory. -
API Clients (
api/): Independent Python classes that abstract the specific REST/JSON logic of each provider (Wiener Netze, Netz NÖ, etc.). -
Entities (
sensor.py): The actual sensors seen by the user. They subscribe to the Coordinator and extract specific values (OBIS codes, stats, diagnostics) from the central data blob.
- Cloud Polling: Since no local interface is available for these meters without hardware dongles, we poll the cloud backend.
- Graceful Degradation: If specific statistics (e.g., "Yesterday's consumption") are missing, the main sensors (Total counter) must still work.
- Strict Typing: We enforce units (Wh) to ensure Home Assistant's long-term statistics and Energy Dashboard work correctly.
-
Provider Agnostic Core: The core logic (Sensor, Coordinator) is generic. Provider specifics are encapsulated strictly within
api/client_*.py.
custom_components/asm/
├── __init__.py # Component setup & platform loading
├── config_flow.py # UI for adding the integration
├── const.py # Global constants (OBIS codes, URLs)
├── coordinator.py # Central data fetching logic
├── manifest.json # HA metadata
├── sensor.py # Entity definitions (Sensors, Diagnostics)
└── api/
├── base.py # Abstract Base Class for Clients
├── client.py # Factory to get specific clients
├── client_wn.py # Wiener Netze Implementation
├── client_noe.py # Netz NÖ Implementation
└── constants.py # API-specific constants
-
Base Class:
SmartmeterClient(inbase.py) defines the interface that all providers must implement:login()-
zaehlpunkte()(Fetch meters/contracts) -
historical_data()(Fetch OBIS readings) -
consumptions()(Fetch daily statistics)
-
Wiener Netze Client (
client_wn.py): Uses a complex OAuth2/OpenID Connect flow withlxmlto scrape the login form and retrieve Access Tokens & API Keys (B2B/B2C).
-
Polling Strategy: Runs
_async_update_dataevery 6 hours (configurable via Options Flow). - Data Structure: The coordinator builds a normalized data dictionary for all meters:
{
"AT001000...": {
"info": { "...": "Static meter details (Address, IDs)" },
"readings": [ "List of OBIS data objects (1.8.0, 2.8.0)" ],
"stats": { "...": "Daily statistics (Yesterday, etc.)" }
}
}-
Error Handling: Catches
SmartmeterLoginErrorto trigger a re-auth flow if credentials change or expire.
We implement three types of entities:
-
AustriaSmartMeterSensor(Main):- Represents specific OBIS codes (e.g., 1.8.0 for Consumption).
-
Logic: Searches the
readingslist for its specific OBIS code. -
Unit: Strictly set to
Wh(UnitOfEnergy.WATT_HOUR). -
State Class:
TOTAL_INCREASING(crucial for correct HA Energy Dashboard calculations).
-
AustriaSmartMeterDiagnostic:- Category:
DIAGNOSTIC. - Displays static data: Address, Customer ID, Market Readiness, Facility Type.
- Does not affect the Energy Dashboard.
- Category:
-
AustriaSmartMeterStatistic:- Displays pre-calculated values provided by the API (e.g., "Consumption Yesterday").
- Useful for quick insights without doing math in HA / Templates.
1. Setup Flow:
- User enters credentials in the UI.
-
config_flowcallsclient.login()->client.zaehlpunkte()to verify access. - If successful, a Config Entry is saved containing
provider,username, andpassword.
2. Update Loop:
- Coordinator wakes up (Timer).
- Checks token validity -> calls
client.login()if expired. - Fetches
zaehlpunkte(Contracts). - Fetches
consumptions(Daily Stats). - Iterates over all meters -> fetches
historical_data(Readings). - Merges everything into the central data dictionary.
- Sensors update their state from this dictionary.
To add support for a new provider (e.g., Graz, Salzburg):
- Create a new file
api/client_newprovider.py. - Inherit from
SmartmeterClient. - Implement the abstract methods (
login,zaehlpunkte,historical_data). - Register the new client in
api/client.pyinside theget_client()factory method. - Add the provider constant in
const.py.
The full 1.1.8 extension guide is preserved at Extend the Austria Smartmeter integration to support a new energy provider. The current guide is Adding a New Provider.
-
Unit Handling: The API often returns inconsistent units or missing unit fields. The sensor logic forces
Whif the OBIS code is a known energy code (1.8.0/2.8.0) to prevent database corruption in Home Assistant. - API Keys: Wiener Netze uses dynamic API keys (B2B/B2C) fetched during login from a config JSON. Hardcoding them is avoided to prevent breakage on API updates.
These were fixed on the 1.2.x line and are documented here so that readers of the archived design understand why the current documents differ.
| Defect | Impact |
|---|---|
Netz NÖ login endpoint misspelled (Authenticaton) |
Setup always failed for Netz NÖ (issue #1). |
Netz NÖ reading response shape wrong (consumptionRecords vs. a list of peakDemandTimes/meteredValues) |
Netz NÖ consumption was never parsed. |
is_login_expired() hardcoded to False for Netz NÖ |
Stale cookies were never refreshed. |
All OBIS readings forced to TOTAL_INCREASING
|
A per-day consumption value would have produced invalid long-term statistics. |
OptionsFlow constructed with a config entry |
Deprecated in modern Home Assistant. |
hass.data[DOMAIN][entry_id] |
Replaced by entry.runtime_data. |
| No brand images, no diagnostics | UI showed a placeholder; support had no data dump. |
🟢 Current — 1.2.x
(branch HA2026_09_dev, HA 2026.9+)
🗄️ Archived — 1.1.8
(branch main)
🔗 Links