This release is a pre-release and may not be stable for production use.
pybragerone
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 py-bragerone
Pre-release (PyPI, exact pin):
pip install "py-bragerone==2026.8.9rc1"
Optional extras:
pip install "py-bragerone[cli]" # CLI with typer, rich, aiofiles pip install "py-bragerone[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 (the password is prompted securely when omitted):
pybragerone-cli --email YOU@example.com
Select platform (useful for TiSConnect installations):
pybragerone-cli --platform tisconnect --email YOU@example.com
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.
This project uses property-based testing (Hypothesis) and an optional Atheris fuzz harness under fuzz/ for parser resilience.
Metadata
Release files for py-bragerone 2026.9.3rc4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| py_bragerone-2026.9.3rc4.tar.gz | 150.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| py_bragerone-2026.9.3rc4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 313.7 kB
Release files / py_bragerone-2026.9.3rc4.tar.gz
| Download URL | py_bragerone-2026.9.3rc4.tar.gz |
|---|---|
| Size | 150.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e83465ffce75104f16b4cd3c11261b0091a449a324449b68be1ff99cca9c7638
|
|
BLAKE2b-256 checksum How to use checksums |
1b34bcf7780df506df0fc474d01fb716ba337c567a689ef32672b020108e78c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / py_bragerone-2026.9.3rc4-py3-none-any.whl
| Download URL | py_bragerone-2026.9.3rc4-py3-none-any.whl |
|---|---|
| Size | 162.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a5a4bd6a660f0e416780f9676949b7abaa6691259ab07057b7ecf68f57e8bef
|
|
BLAKE2b-256 checksum How to use checksums |
1ace4ca0d1849438c6d829c218659eb5bd8611c42035d819782148d41a3b81a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logSecurity for py-bragerone 2026.9.3rc4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for py_bragerone-2026.9.3rc4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.