Async client for BragerOne: REST + Socket.IO, EventBus, ParamStore (dual-mode), HA-ready
Project description
Status: Stable | Python 3.13.2+ required
Python library for integrating with BragerOne-compatible cloud and realtime APIs.
Supported platforms:
BragerOne (default): one.brager.pl / io.brager.pl
TiSConnect: www.tisconnect.info / io.tisconnect.info
Features: - Async REST client (httpx, not aiohttp) - Realtime updates (python-socketio, namespace /ws) - Event bus for updates - ParamStore (lightweight, key→value with optional rich metadata via LiveAssetsCatalog) - CLI for diagnostics - Home Assistant ready
Installation
Stable (PyPI):
pip install pybragerone
Pre-release (TestPyPI):
pip install -i https://test.pypi.org/simple/ pybragerone
Optional extras:
pip install "pybragerone[cli]" # CLI with typer, rich, aiofiles pip install "pybragerone[keyring]" # Secure token storage with keyring
Development Dependencies
For building documentation with architectural diagrams:
# Ubuntu/Debian sudo apt-get install graphviz # macOS brew install graphviz # Windows (via Chocolatey) choco install graphviz
CLI usage
Run the CLI for guided login and WS session:
pybragerone-cli --email YOU@example.com --password "***"
Select platform (useful for TiSConnect installations):
pybragerone-cli --platform tisconnect --email YOU@example.com --password "***"
Examples
Basic login and device listing
Minimal async example showing login and listing objects/modules:
import asyncio
import os
from pybragerone.api import BragerOneApiClient
async def main() -> None:
email = os.getenv("PYBO_EMAIL", "user@example.com")
password = os.getenv("PYBO_PASSWORD", "password")
client = BragerOneApiClient()
try:
print(f"Logging in as {email}...")
await client.ensure_auth(email, password)
print("✓ Login successful")
objects = await client.get_objects()
print(f"Found {len(objects)} heating system(s)")
for obj in objects:
print(f"- {obj.name} (id={obj.id})")
modules = await client.get_modules(obj.id)
for m in modules:
devid = m.devid or f"id:{m.id}"
version = m.moduleVersion or (m.gateway.version if m.gateway else "unknown")
print(f" • {m.name} (devid={devid}, version={version})")
finally:
await client.close()
if __name__ == "__main__":
asyncio.run(main())
Real-time parameter monitoring
Subscribing to updates via BragerOneGateway and printing changes:
import asyncio
import os
from contextlib import suppress
from pybragerone import BragerOneGateway
async def main() -> None:
email = os.getenv("PYBO_EMAIL")
password = os.getenv("PYBO_PASSWORD")
object_id = int(os.getenv("PYBO_OBJECT_ID", "0"))
modules = [m.strip() for m in os.getenv("PYBO_MODULES", "").split(",") if m.strip()]
if not (email and password and object_id and modules):
print("Set PYBO_EMAIL, PYBO_PASSWORD, PYBO_OBJECT_ID, PYBO_MODULES")
return
gateway = await BragerOneGateway.from_credentials(
email=email,
password=password,
object_id=object_id,
modules=modules,
)
async def monitor() -> None:
async for ev in gateway.bus.subscribe():
if ev.value is None:
continue
key = f"{ev.pool}.{ev.chan}{ev.idx}"
print(f"{ev.devid:12} {key:15} = {ev.value}")
task: asyncio.Task[None] | None = None
try:
await gateway.start()
task = asyncio.create_task(monitor())
await asyncio.sleep(10) # demo run
finally:
if task is not None:
task.cancel()
with suppress(asyncio.CancelledError):
await task
await gateway.stop()
if __name__ == "__main__":
asyncio.run(main())
ParamStore lightweight mode
Attaching ParamStore to the EventBus and reading values:
import asyncio
import os
from contextlib import suppress
from pybragerone import BragerOneGateway
from pybragerone.models.param import ParamStore
async def main() -> None:
email = os.getenv("PYBO_EMAIL")
password = os.getenv("PYBO_PASSWORD")
object_id = int(os.getenv("PYBO_OBJECT_ID", "0"))
modules = [m.strip() for m in os.getenv("PYBO_MODULES", "").split(",") if m.strip()]
if not (email and password and object_id and modules):
print("Set PYBO_EMAIL, PYBO_PASSWORD, PYBO_OBJECT_ID, PYBO_MODULES")
return
gateway = await BragerOneGateway.from_credentials(
email=email,
password=password,
object_id=object_id,
modules=modules,
)
store = ParamStore()
task = asyncio.create_task(store.run_with_bus(gateway.bus))
try:
await gateway.start()
await asyncio.sleep(2)
params = store.flatten()
print(f"Total params: {len(params)}")
for k, v in list(params.items())[:10]:
print(f"{k:20} = {v}")
finally:
task.cancel()
with suppress(asyncio.CancelledError):
await task
await gateway.stop()
if __name__ == "__main__":
asyncio.run(main())
Documentation
Full documentation: https://marpi82.github.io/py-bragerone
Security
For information about security policies, vulnerability reporting, and known security exceptions, see SECURITY.md.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_bragerone-2026.4.4.tar.gz.
File metadata
- Download URL: py_bragerone-2026.4.4.tar.gz
- Upload date:
- Size: 91.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
727bbcec6601e23f0003df2205199f64a290a0e891872f51d6250c85df4148eb
|
|
| MD5 |
2f6cc3b0ae58e56e8fc051da32a4be09
|
|
| BLAKE2b-256 |
1f7cf224a9bb4caf8998271a175c1715f2c57dc9a1e8d81be308921e8bfe4492
|
Provenance
The following attestation bundles were made for py_bragerone-2026.4.4.tar.gz:
Publisher:
release.yml on marpi82/py-bragerone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_bragerone-2026.4.4.tar.gz -
Subject digest:
727bbcec6601e23f0003df2205199f64a290a0e891872f51d6250c85df4148eb - Sigstore transparency entry: 1272069537
- Sigstore integration time:
-
Permalink:
marpi82/py-bragerone@6f316a8b6ac07fa9b380cf830906108845751d03 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/marpi82
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f316a8b6ac07fa9b380cf830906108845751d03 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file py_bragerone-2026.4.4-py3-none-any.whl.
File metadata
- Download URL: py_bragerone-2026.4.4-py3-none-any.whl
- Upload date:
- Size: 98.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7518b33bce2476adb1b4365c1c3fcefad6265ae7636ec49c98b13c983a3969c7
|
|
| MD5 |
e759ff859fb35abe3ac0cdadf6c8ce7e
|
|
| BLAKE2b-256 |
3dcf0aa3ca4b0649fac40446ab43518025eb6f8569fd817bd537a807e6bfcd37
|
Provenance
The following attestation bundles were made for py_bragerone-2026.4.4-py3-none-any.whl:
Publisher:
release.yml on marpi82/py-bragerone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_bragerone-2026.4.4-py3-none-any.whl -
Subject digest:
7518b33bce2476adb1b4365c1c3fcefad6265ae7636ec49c98b13c983a3969c7 - Sigstore transparency entry: 1272069716
- Sigstore integration time:
-
Permalink:
marpi82/py-bragerone@6f316a8b6ac07fa9b380cf830906108845751d03 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/marpi82
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f316a8b6ac07fa9b380cf830906108845751d03 -
Trigger Event:
workflow_run
-
Statement type: