Cross-platform support for Blauberg Vento Expert Wi-Fi fans, built on Blauberg's openly available protocol document (B133-4-1EN-02). Development is assisted by AI language models.
| Package | Description |
|---|---|
ventocontrol/ |
PySide6 desktop GUI — macOS, Windows, Linux |
ventocontrol/simulator.py |
Software fan simulator for development without hardware |
webdashboard/ |
React + FastAPI web dashboard — same palette as the desktop GUI |
The UDP API library is the separately published
blauberg-vento PyPI package
(source); it is installed
automatically as a dependency of Arabella.
git clone https://github.com/BirgerKo/Arabella.git
cd Arabella
pip install -e ".[dev]" # API + test dependencies
pip install -e ".[gui]" # add PyQt6 for the desktop GUIfrom blauberg_vento import VentoClient
devices = VentoClient.discover()
client = VentoClient("192.168.1.50", "ABCD1234EFGH5678")
state = client.get_state()
print(state)
client.turn_on()
client.set_speed(2)The library can also be used standalone: pip install blauberg-vento.
All application entry points (ventocontrol, ventosim, pytest, etc.) are
installed inside the project's virtual environment. You must activate it once
per terminal session before running any of the commands below.
# From the Arabella project root:
source .venv/bin/activateFirst time only — create the virtual environment and install all dependencies:
python3 -m venv .venv source .venv/bin/activate pip install -e ".[dev,gui,web]" cd webdashboard/frontend && npm install && cd ../..
Once the environment is active your prompt will show (.venv) and all
commands below will work directly.
ventocontrolThe app opens on the Overview window; click a fan card to open that fan's control window. Closing the Overview closes every open fan window and exits the app.
ventosim --count 3pytestInstall the development tools with:
python -m pip install -e ".[dev]"Run the same checks used by CI:
python -m ruff check tests/test_protocol.py tests/test_protocol_invalid.py tests/test_transport.py
python -m ruff format --check .
python -m mypy .The default run excludes browser E2E tests because the synchronous Playwright plugin and pytest-asyncio cannot share one pytest event loop on Python 3.13. Run the browser tests separately:
pytest tests/webdashboard/e2e --browser chromiumBoth the desktop GUI and web dashboard provide full fan control parity with a clean two-level layout: daily controls on the main view, deeper settings in a "Details…" modal.
| Feature | Desktop GUI | Web Dashboard |
|---|---|---|
| Power on/off | ✓ | ✓ |
| Speed presets (1–3) | ✓ | ✓ |
| Operation mode (Ventilation / Heat Recovery / Supply) | ✓ | ✓ |
| Quick-scenario slots (Q1–Q3) | ✓ | ✓ |
| Connection / alarm status | ✓ | ✓ |
The per-fan window's power button follows the same colour rules as the Overview tiles — green when the fan is connected and all is OK, yellow on alarm or expired filter timer, grey while unconnected; the glow still shows the power state. When it is yellow, the details window states the reason ("Alarm" and/or "Filter timer expired") above the Humidity section. The fan name sits beside it with the Details button directly under the name. Fan switching happens from the Overview window, not from the per-fan window.
VentoControl opens on the Overview: the same portrait "mobile" format as the per-fan window, showing two live tiles per line, one per fan you have connected to before.
| Element | Content |
|---|---|
| Airflow icon | Green when the fan is reachable, grey when not, yellow on alarm or expired filter timer |
| Airflow arrows | Supply: air into the house · Ventilation: air out · Heat Recovery: both |
| Fan name | Truncated with an ellipsis when too long for the tile |
| Humidity | Printed just below the icon, e.g. "57% RH" |
| Time / date | The fan's internal RTC time above its date |
Clicking a tile opens that fan's control window (the serial number stays in the per-fan window's status bar). Right-clicking a tile offers Open…, Details… (opens the fan window and its Details dialog), Rename…, Scenario… (manage scenarios with this fan's quick-slots enabled), Sync Clock to PC (this fan only) and Remove from List. Tiles auto-refresh every 10 seconds and grey out when a fan is unreachable. The bottom bar keeps Refresh, Sync All Clocks to PC (sets every fan's clock from this computer's system time), and Connect New Fan… for discovery.
| Feature | Desktop GUI | Web Dashboard |
|---|---|---|
| Boost toggle | ✓ | ✓ |
| Humidity sensor (Off / On / Invert) + threshold | ✓ | ✓ |
| Real-time fan 1 / fan 2 RPM display | ✓ | ✓ |
| Weekly schedule enable / disable | ✓ | ✓ |
| Weekly schedule editor (8 day-groups × 4 periods) | ✓ | ✓ |
| Sync device RTC to system time | ✓ | ✓ |
| Scenario save / apply / manage | ✓ | ✓ |
| Add current fan to existing scenario | ✓ | ✓ |
| IP address shown on hover only | ✓ | ✓ |
pip install -e ".[web]" # FastAPI + uvicorn
cd webdashboard/frontend && npm install # React + Vite# Terminal 1 — API backend
python -m webdashboard
# Terminal 2 — Vite dev server (proxies /api and /ws to :8080)
cd webdashboard/frontend && npm run dev
# Open http://localhost:5173cd webdashboard/frontend && npm run build
python -m webdashboard
# Open http://localhost:8080pip install -e ".[dev,web]"
python -m playwright install chromium
python -m webdashboard & # start backend first
pytest tests/webdashboard/e2e/ --base-url http://localhost:8080The Python E2E fixtures start the simulator and dashboard automatically in their default simulator mode. Frontend Playwright tests run independently with:
cd webdashboard/frontend
npm install
npm testmake up # build images and start 3 virtual fans
make down # stop containers
make logs # follow container logsRequires Docker Desktop.
macOS users: also run sudo ./setup-loopback.sh once per reboot.