Skip to main content

Async Python library to connect to a Fronius Wattpilot Wallbox

Project description

wattpilot-api

CI PyPI version Python versions codecov License: MIT Ask DeepWiki

Async Python library for Fronius Wattpilot Wallbox devices.

Connects to Wattpilot EV chargers over WebSocket using a reverse-engineered API (the same protocol used by the official Wattpilot.Solar mobile app). Provides real-time property synchronization, an MQTT bridge, Home Assistant discovery, and an interactive CLI shell.

Features

  • Fully async — built on asyncio and websockets, compatible with Home Assistant
  • All Wattpilot hardware — supports standard (V2) and Flex models via PBKDF2 and bcrypt authentication
  • 388+ properties — access every charger property in real time
  • MQTT bridge — publish properties and subscribe to commands via aiomqtt
  • Home Assistant discovery — automatic entity creation with proper device classes
  • Interactive shell — async CLI with TAB completion via prompt_toolkit
  • Type-safe — full type hints, mypy --strict, PEP 561 py.typed marker
  • 100% test coverage — 241 unit tests + 18 integration tests

Requirements

  • Python 3.12+
  • Local network access to a Fronius Wattpilot charger

Installation

pip install wattpilot-api

For development:

pip install -e ".[dev]"

Quick Start

As a library

import asyncio
from wattpilot_api import Wattpilot, LoadMode

async def main():
    async with Wattpilot("192.168.1.100", "your_password") as wp:
        # Read properties
        print(f"Serial: {wp.serial}")
        print(f"Firmware: {wp.firmware}")
        print(f"Power: {wp.power:.2f} kW")
        print(f"Amperage: {wp.amp} A")
        print(f"Car connected: {wp.car_connected}")
        print(f"Mode: {LoadMode(wp.mode).name}")

        # Set charging amperage
        await wp.set_power(16)

        # Set charging mode
        await wp.set_mode(LoadMode.ECO)

        # Register a callback for property changes
        def on_change(name, value):
            print(f"{name} = {value}")

        unsub = wp.on_property_change(on_change)

        # Access all 388+ raw properties
        for key, value in sorted(wp.all_properties.items()):
            print(f"  {key} = {value}")

        unsub()  # unsubscribe when done

asyncio.run(main())

Interactive shell

export WATTPILOT_HOST=192.168.1.100
export WATTPILOT_PASSWORD=your_password
wattpilotshell

With MQTT and Home Assistant

export WATTPILOT_HOST=192.168.1.100
export WATTPILOT_PASSWORD=your_password
export MQTT_ENABLED=true
export MQTT_HOST=your_mqtt_broker
export HA_ENABLED=true
wattpilotshell

Supported Hardware

Device Auth Status
Wattpilot Home (V2) PBKDF2 Tested
Wattpilot Home FLEX 11 C6 bcrypt Supported
Wattpilot Home FLEX 22kW bcrypt Supported
Wattpilot (cloud via Fronius API) PBKDF2 Supported

Authentication is auto-detected:

  1. If the authRequired message includes a hash field, that algorithm is used
  2. Otherwise, if devicetype is wattpilot_flex, bcrypt is used
  3. Otherwise, PBKDF2 is used (default)

API Reference

Wattpilot Client

from wattpilot_api import Wattpilot

# Constructor
wp = Wattpilot(
    host="192.168.1.100",
    password="your_password",
    serial=None,           # auto-detected from device
    cloud=False,           # True for Fronius cloud connection
    connect_timeout=30.0,  # seconds
    init_timeout=30.0,     # seconds
)

# Connect / disconnect
await wp.connect()
await wp.disconnect()

# Or use as async context manager
async with Wattpilot("192.168.1.100", "password") as wp:
    ...

Properties

Property Type Description
wp.connected bool Connection status
wp.serial str Device serial number
wp.name str Device name
wp.manufacturer str Manufacturer ("fronius")
wp.device_type str Device type ("wattpilot_V2", "wattpilot_flex")
wp.version str Firmware version
wp.amp int Current amperage setting
wp.mode int Charging mode (3=Default, 4=Eco, 5=NextTrip)
wp.car_connected int Car status (1=No car, 2=Charging, 3=Ready, 4=Complete)
wp.allow_charging bool Whether charging is allowed
wp.voltage1/2/3 float Phase voltages
wp.amps1/2/3 float Phase currents
wp.power1/2/3 float Phase power (kW)
wp.power float Total power (kW)
wp.frequency float Grid frequency (Hz)
wp.energy_counter_since_start float Session energy (Wh)
wp.energy_counter_total float Lifetime energy (Wh)
wp.error_state int Error code
wp.cable_type int Cable capacity (A)
wp.cable_lock int Lock mode
wp.access_state int Access state
wp.phases list Phase configuration
wp.all_properties dict All 388+ raw properties

Commands

await wp.set_power(16)                    # Set amperage (6-32)
await wp.set_mode(LoadMode.ECO)           # Set charging mode
await wp.set_property("fna", "MyCharger") # Set any writable property

Callbacks

# Sync or async callbacks supported
unsub = wp.on_property_change(lambda name, value: print(f"{name}={value}"))
unsub()  # unsubscribe

unsub = wp.on_message(lambda msg: print(msg["type"]))
unsub()

Enums

from wattpilot_api import LoadMode, CarStatus, ErrorState, AccessState, CableLockMode

LoadMode(wp.mode)           # LoadMode.DEFAULT / ECO / NEXTTRIP
CarStatus(wp.car_connected) # CarStatus.NO_CAR / CHARGING / READY / COMPLETE

Exceptions

from wattpilot_api import WattpilotError, AuthenticationError, ConnectionError

try:
    await wp.connect()
except AuthenticationError:
    print("Wrong password")
except ConnectionError:
    print("Cannot reach device")

MQTT Bridge

The MqttBridge class publishes property changes to MQTT and subscribes to set commands.

from wattpilot_api import Wattpilot, MqttBridge, MqttConfig
from wattpilot_api.definition import load_api_definition

api_def = load_api_definition()
config = MqttConfig(host="localhost", port=1883)

async with Wattpilot("192.168.1.100", "password") as wp:
    bridge = MqttBridge(wp, config, api_def)
    await bridge.start()
    # ... bridge publishes property changes to MQTT
    await bridge.stop()

Home Assistant Discovery

from wattpilot_api import HomeAssistantDiscovery, HaConfig

ha = HomeAssistantDiscovery(wp, bridge, HaConfig(enabled=True), api_def)
await ha.discover_all()
await ha.publish_initial_values()

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests (100% coverage required)
pytest --cov=wattpilot_api --cov-report=term-missing --cov-fail-under=100

# Run integration tests against a real device
WATTPILOT_HOST=192.168.1.100 WATTPILOT_PASSWORD=password pytest -m integration -v

# Lint and type check
ruff check src/ tests/
mypy src/wattpilot_api/

# Pre-commit (runs ruff, ruff-format, mypy)
pre-commit run --all-files

Project Structure

src/wattpilot_api/
├── __init__.py          # Public API exports
├── client.py            # Async WebSocket client
├── auth.py              # PBKDF2 + bcrypt authentication
├── models.py            # Enums and dataclasses
├── exceptions.py        # Exception hierarchy
├── definition.py        # YAML property metadata loader
├── mqtt.py              # Async MQTT bridge
├── discovery.py         # Home Assistant MQTT discovery
├── shell.py             # Async CLI shell
├── py.typed             # PEP 561 marker
└── resources/
    └── wattpilot.yaml   # Property definitions (3300+ lines)

API Sources

The WebSocket API has been reverse-engineered from multiple sources:

Changelog

See CHANGELOG.md for version history, migration guide, and upstream issue fixes.

License

MIT License — see LICENSE for details.

Disclaimer

This project uses a reverse-engineered API and is not officially supported by Fronius. Use at your own risk.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wattpilot_api-1.4.0.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wattpilot_api-1.4.0-py3-none-any.whl (47.4 kB view details)

Uploaded Python 3

File details

Details for the file wattpilot_api-1.4.0.tar.gz.

File metadata

  • Download URL: wattpilot_api-1.4.0.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wattpilot_api-1.4.0.tar.gz
Algorithm Hash digest
SHA256 9c17409ed35e2b63f7ba990255cd19a2530cf2c5383c924832485ec6671bbd21
MD5 bbc3401c1335997dc26e628f4acd472e
BLAKE2b-256 e5776968475c5eafe88c3c90349263700421cc37877414bd15143b8c475b9118

See more details on using hashes here.

Provenance

The following attestation bundles were made for wattpilot_api-1.4.0.tar.gz:

Publisher: publish.yml on ruaan-deysel/wattpilot-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wattpilot_api-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: wattpilot_api-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 47.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wattpilot_api-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9d42747f9c8e53f4dc07dad93edc9e396dbd578b6a67291ea58ce0f1dcdf2eb9
MD5 b931edff8b89e3c714411b2811971ac9
BLAKE2b-256 184b4e9d1f334f49756bb584c80706ae39e7004ba3da24806ea0afe908d5a58e

See more details on using hashes here.

Provenance

The following attestation bundles were made for wattpilot_api-1.4.0-py3-none-any.whl:

Publisher: publish.yml on ruaan-deysel/wattpilot-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page