Getting Started¶
pybragerone is an alpha-stage Python library for integrating with BragerOne. It provides an async REST client, a Socket.IO realtime client, an internal event bus, and a runtime-light ParamStore plus an optional asset-driven ParamResolver (via LiveAssetsCatalog) so you can build efficient automations and a clean Home Assistant integration.
See also
Core Components - Quick patterns cheat sheet
Architecture Overview - Detailed architecture documentation
API Reference - Full API reference
Highlights¶
REST (httpx): login, user & permissions, objects, modules,
modules.connect, snapshot endpoints (modules/parameters,modules/activity/quantity).Realtime (python-socketio): namespace
/ws; subscribes toapp:modules:parameters:listenandapp:modules:activity:quantity:listen.EventBus: in-process async fan-out of structured updates.
ParamStore: lightweight key→value view (e.g.
"P4.v1" -> 20.5) for runtime.ParamResolver: optional asset-driven resolution (i18n labels, units/enums, menu grouping, computed STATUS).
Online asset parsers: i18n translations, parameter mappings,
module.menufeatures.CLI: quick diagnostics, raw WS debug, and snapshot prime helpers.
HA-ready: designed so HA runtime relies on ParamStore; config flow uses asset catalog.
Architecture¶
The library consists of several key components working together:
BragerOne Cloud
- REST API (/v1/*) -----------------------> BragerOneApiClient (httpx)
- WebSocket (/socket.io) ---------------> RealtimeManager (Socket.IO)
|
v
BragerOneGateway (orchestration)
|
v
EventBus (pub/sub)
|
v
ParamStore (key→value)
Metadata (config flow only)
BragerOneApiClient -> LiveAssetsCatalog -> ParamResolver -> ParamStore (labels/units/enums)
Home Assistant usage
- Config Flow: uses ParamResolver + LiveAssetsCatalog-derived descriptors
- Runtime: uses ParamStore (lightweight mode)
Note
Data Flow:
REST API provides initial state and snapshots
WebSocket delivers real-time updates
Gateway orchestrates connection and subscriptions
EventBus broadcasts updates to all subscribers
ParamStore maintains current parameter values
Version & Python¶
Alpha: APIs may still evolve.
Python: 3.13.2+ (aligned with Home Assistant 2025).
Installation¶
Stable (PyPI, when published):
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
Quick Start (CLI)¶
Run the CLI for a guided session (object & module selection, WS link, prime):
pybragerone-cli --email YOU@example.com --password "***" --debug
Press Ctrl+C to stop. Use --raw-ws for raw payload logging.
Minimal Example – Lightweight (runtime)¶
import asyncio
from pybragerone import BragerOneGateway
from pybragerone.models.param import ParamStore
async def main() -> None:
gw = await BragerOneGateway.from_credentials(
email="you@example.com",
password="secret",
object_id=12345, # Your object ID
modules=["ABC123", "DEF456"], # Your module codes (devids)
)
pstore = ParamStore()
asyncio.create_task(pstore.run_with_bus(gw.bus))
async def printer():
async for upd in gw.bus.subscribe():
if upd.value is None:
continue
key = f"{upd.pool}.{upd.chan}{upd.idx}"
print(f"↺ {upd.devid} {key} = {upd.value}")
asyncio.create_task(printer())
await gw.start()
try:
await asyncio.sleep(60)
finally:
await gw.stop()
if __name__ == "__main__":
asyncio.run(main())
Advanced Example – With Rich Metadata (config flow)¶
import asyncio
from pybragerone import BragerOneApiClient, BragerOneGateway
from pybragerone.models import ParamResolver
from pybragerone.models.param import ParamStore
async def main() -> None:
# For config flow or when you need i18n/labels/enums
api = BragerOneApiClient()
await api.ensure_auth("you@example.com", "secret")
user = await api.get_user()
object_id = user.objects[0].id
modules_resp = await api.get_modules(object_id=object_id)
devids = [m.devid for m in modules_resp if m.devid]
pstore = ParamStore()
resolver = ParamResolver.from_api(api=api, store=pstore, lang="pl")
gw = BragerOneGateway(api=api, object_id=object_id, modules=devids)
asyncio.create_task(pstore.run_with_bus(gw.bus))
await gw.start()
try:
# Now you can use rich metadata methods
menu = await resolver.get_module_menu(device_menu=0, permissions=["param.edit"])
print(f"Available routes: {len(menu.routes)}")
desc = await resolver.describe_symbol("PARAM_0")
print(f"PARAM_0 → label={desc['label']} unit={desc['unit']} value={desc['value']}")
await asyncio.sleep(60)
finally:
await gw.stop()
await api.close()
if __name__ == "__main__":
asyncio.run(main())
Event Bus & Update Model¶
ParamUpdate carries atomic updates:
devid– device code (e.g."FTTCTBSLCE")pool– parameter group (P4,P5, …)chan– channel (v,s,u,n,x, …)idx– index within the poolvalue– parsed value (int/float/str/bool) orNonefor meta-only framesmeta– timestamps, storable flag, averages, etc.seq– monotonically increasing sequence assigned by the EventBus
Example of flattening parameters (gateway helper):
updates = gateway.flatten_parameters(payload)
for upd in updates:
print(f"{upd.devid} {upd.pool}.{upd.chan}{upd.idx} = {upd.value}")
ParamStore Details¶
ParamStore is intentionally runtime-light and focused on storing values. When you need asset-driven metadata (menu grouping, i18n labels/units/enums, computed STATUS), use ParamResolver (config flow / CLI).
Runtime: ParamStore + EventBus subscription (fast, minimal overhead)
Setup / Config Flow: ParamResolver + LiveAssetsCatalog (metadata, discovery)
Online Asset Parsers¶
pybragerone can resolve labels, units, and visibility rules directly from online assets via LiveAssetsCatalog:
i18n JSON: language packs (e.g.
.../resources/languages/pl/parameters.json)parameters bundles: e.g.
PARAM_0to map pools (P6.v0/s0/u0/...)module.menu: sections, required permission levels, and parameter visibility
Sessions are shared with the REST client, so fetching assets respects authentication and CORS.
Home Assistant Integration¶
Runtime: subscribe to the EventBus and source states from ParamStore (lightweight mode).
Config Flow: enumerate entities and their metadata via ParamResolver (asset-aware mode provides labels, units, enums).
Units mapping: a helper maps Brager unit codes (or i18n unit text) to HA canonical units (e.g.
°C→temperature,%→percentage).
Security Notes¶
Store and refresh the bearer token responsibly (e.g. OS keyring in real deployments).
Always pass
OriginandRefererheaders consistent with the official UI.Use TLS (HTTPS) for all requests; the realtime client upgrades via the engine automatically.
Troubleshooting¶
403 Forbidden on REST requests: - check
Authorization: Bearer <token>- ensure yourOriginandRefererheaders match the UI domainNo WS events after connecting: - verify
modules.connectsucceeded - re-check your namespace SID versus engine SID when passing tomodules.connectCORS preflight (OPTIONS): - required by the browser; not needed when calling from Python unless API enforces it
Development¶
Python 3.13.2+
Ruff as formatter and linter (
line-length = 100)mypy –strict with
pydantic.mypypluginType hints are shipped (
py.typed)
Common tasks:
ruff format
ruff check src/pybragerone --fix
mypy src/pybragerone --strict
Release flow (suggestion):
1. Bump version in pyproject
2. Tag & GitHub release
3. Build: python -m build
4. Publish: twine upload dist/* (or TestPyPI first)
Contributing¶
Issues and PRs are welcome. Please follow: - Conventional commits (optional but helpful) - Keep public methods fully typed & documented (Google docstrings) - Keep runtime lightweight; push heavy mapping to setup/config-time
License¶
MIT – see LICENSE.