pybragerone.models.catalog

Implementation of live asset catalog parsing from BragerOne web app.

This module provides classes and utilities for parsing and managing live assets from the BragerOne web application, including:

  • LiveAssetsCatalog: Main entry point for fetching and parsing assets

  • AssetRef, AssetIndex: Data structures for tracking asset references

  • ParamMap: Data structures for menu routes and parameter mappings

  • TranslationConfig: Configuration for available translations

Classes

AssetIndex(assets_by_basename, ...)

Index of assets parsed from index-*.js file.

AssetRef(url, base, hash[, etag, last_modified])

Reference to a versioned asset from the BragerOne catalog.

LiveAssetsCatalog(api[, logger, ...])

Main entry point: fetches index-<hash>.js, parses router (module.menu-<hash>.js).

ParamMap(key, group, paths, component_type, ...)

Represents a parameter mapping in the BragerOne system.

TranslationConfig(translations, ...)

Configuration of available translations.

class pybragerone.models.catalog.AssetIndex(assets_by_basename: dict[str, list[~pybragerone.models.catalog.AssetRef]]=<factory>, menu_map: dict[int, str]=<factory>, inline_param_candidates: list[tuple[int, int]]=<factory>, index_bytes: bytes = b'')[source]

Bases: object

Index of assets parsed from index-*.js file.

Variables:
  • assets_by_basename – Full list of assets declared in index-*.js (exact basenames, no normalization). Maps basename strings to lists of AssetRef objects.

  • menu_map – Mapping from deviceMenu integers to BASENAME strings (e.g., module.menu-<hash>.js).

  • inline_param_candidates – List of (start_byte, end_byte) tuples indicating potential inline parameter maps detected within index-*.js.

  • index_bytes – Raw bytes of the index file for potential inline parsing.

Parameters:
assets_by_basename: dict[str, list[AssetRef]]
find_asset_for_basename(basename: str)[source]

Find an asset reference by its basename.

Parameters:

basename (str) – The basename of the asset to search for.

Returns:

AssetRef | None – The last asset reference found for the given basename, or None if no asset is found. When multiple assets share the same basename, returns the last one (typically the newest hash).

Return type:

AssetRef | None

Note

Uses an alpha heuristic that assumes the last asset in the list is the most recent version when multiple assets share the same basename.

find_asset_for_full_name(full_name: str)[source]

Find an asset reference by its full name with hash (e.g., ‘module.menu-Dbo_n32n’).

Parameters:

full_name (str) – The full name of the asset with hash to search for.

Returns:

AssetRef | None – The asset reference if found, or None if not found.

Return type:

AssetRef | None

index_bytes: bytes
inline_param_candidates: list[tuple[int, int]]
menu_map: dict[int, str]
class pybragerone.models.catalog.AssetRef(url: str, base: str, hash: str, etag: str | None = None, last_modified: str | None = None)[source]

Bases: object

Reference to a versioned asset from the BragerOne catalog.

Variables:
  • url – The full URL to the asset file.

  • base – The base name without hash (e.g., ‘module.menu’ from ‘module.menu-BNvCCsxi’).

  • hash – The hash identifier for this version (e.g., ‘BNvCCsxi’).

  • etag – Optional ETag from HTTP headers for cache validation.

  • last_modified – Optional last modified timestamp from HTTP headers.

Parameters:
  • url (str)

  • base (str)

  • hash (str)

  • etag (str | None)

  • last_modified (str | None)

base: str
etag: str | None
hash: str
last_modified: str | None
url: str
class pybragerone.models.catalog.LiveAssetsCatalog(api: pybragerone.api.BragerOneApiClient, logger: Logger | None = None, visibility_strategy: str = 'independent', schemas_enabled: bool = False, request_timeout: float = 8.0, concurrency: int = 8)[source]

Bases: object

Main entry point: fetches index-<hash>.js, parses router (module.menu-<hash>.js).

Only loads necessary parameter map files (based on router tokens).

Parameters:
PARAM_CALL_RE = re.compile('\\b[A-Za-z_$][\\w$]*\\([^,]*?,\\s*([\'"])(?P<tok>[^\'"]+)\\1\\)')
async get_i18n(lang: str, namespace: str)[source]

Get i18n mapping for a given language and namespace.

Parses the index file for dynamic language imports in the format: “../../resources/languages/{lang}/{namespace}.json”:()=>d(()=>import(“./file-hash.js”),[]).then(e=>e.default)

Then fetches and parses the corresponding asset file.

Parameters:
  • lang (str) – Language code (e.g., ‘en’, ‘pl’).

  • namespace (str) – Namespace (e.g., ‘parameters’, ‘units’).

Returns:

dict[str, Any] – Dictionary with translation mappings, or empty dict if not found.

Return type:

dict[str, Any]

get_menu_debug_info(device_menu: int)[source]

Get debug information about cached menu.

Return type:

dict[str, Any]

Parameters:

device_menu (int)

async get_module_menu(device_menu: int, permissions: Iterable[str] | None = None, *, debug_mode: bool = False)[source]

Get processed menu using the unified MenuManager pipeline.

Return type:

MenuResult

Parameters:
async get_param_mapping(tokens: Iterable[str])[source]

Retrieve parameter mappings for the given tokens.

This method attempts to resolve parameter mappings for each provided token through a two-stage resolution process:

  1. First, it searches for a dedicated asset file named BASENAME-<hash>.js where BASENAME exactly matches the token.

  2. If no asset is found, and there is exactly one unresolved token with exactly one inline parameter candidate in the index, it attempts to use the inline parameter map from the index-*.js file as a fallback.

  3. Any tokens that cannot be resolved through either method are omitted from the results.

Parameters:

tokens (Iterable[str]) – An iterable of token strings to resolve into parameter mappings.

Returns:

dict[str, ParamMap] – A dictionary mapping successfully resolved token strings to their corresponding ParamMap objects. Only tokens that were successfully resolved are included in the returned dictionary.

Return type:

dict[str, ParamMap]

Note

The method performs asset fetching concurrently using asyncio.gather for improved performance. Failed fetches are logged but do not raise exceptions.

get_raw_menu(device_menu: int)[source]

Get raw unprocessed menu data for debugging.

Return type:

RawMenuData

Parameters:

device_menu (int)

async get_unit_descriptor(unit_code: Any)[source]

Return unit descriptor for raw unit code from index-defined transform table.

The BragerOne frontend keeps canonical unit behavior in an index-scoped table (text/options/value/valuePrepare). This helper exposes that table entry by raw unit code so runtime consumers can apply the same mappings/transforms.

Return type:

dict[str, Any] | None

Parameters:

unit_code (Any)

async list_language_config()[source]

Get translation configuration from assets.

Parses the index-*.js file to extract language configuration by structural patterns. The configuration object contains translations array and defaultTranslation field.

Return type:

TranslationConfig | None

async list_symbols_for_permissions(device_menu: int, permissions: Iterable[str])[source]

List symbols visible for given permissions.

This is a convenient shortcut that fetches the menu for device_menu and returns tokens visible for the provided permissions. The schemas hook remains OFF.

Parameters:
  • device_menu (int) – The device menu identifier.

  • permissions (Iterable[str]) – An iterable of permission strings to check visibility against.

Returns:

set[str] – A set of token strings that are visible for the given permissions.

Return type:

set[str]

async refresh_index(index_url: str)[source]

Fetches index-<hash>.js and builds full asset index.

  • assets_by_basename (exact BASENAME → [AssetRef])

  • menu_map: int -> BASENAME(module.menu-<hash>.js), if present in index

  • inline_param_candidates: list of (start,end) large objects in index that look like param-maps

Return type:

None

Parameters:

index_url (str)

class pybragerone.models.catalog.ParamMap(key: str, group: str | None, paths: dict[str, list[dict[str, Any]]], component_type: str | None, units: str | int | float | dict[str, Any] | list[Any] | None, limits: dict[str, Any] | None, status_flags: list[dict[str, Any]], status_conditions: dict[str, list[dict[str, Any]]] | None, command_rules: list[dict[str, Any]], origin: str, raw: dict[str, Any])[source]

Bases: object

Represents a parameter mapping in the BragerOne system.

This class encapsulates the mapping between parameter identifiers and their metadata, including paths, units, limits, and status flags. It serves as a structured representation of parameter configurations retrieved from the router.

Variables:
  • key – The unique parameter identifier token from the router. Examples: “URUCHOMIENIE_KOTLA”, “PARAM_66”.

  • group – Optional parameter group identifier. Example: “P6”.

  • paths – Dictionary mapping path types to their respective path lists. Entries are normalized lists of dictionaries describing pool/index/use metadata for value/unit/status/command/min/max channels.

  • component_type – Optional type of the UI component associated with this parameter.

  • units – Optional measurement unit identifier. May be a localized string, numeric code, or mapping used for enumerations; resolution happens via the units i18n catalog where possible.

  • limits – Optional dictionary containing parameter limit definitions and constraints.

  • status_flags – List of dictionaries defining various status flags and their meanings.

  • origin – Source of the parameter map definition. Format: “asset:<url>” for external sources or “inline:index” for inline definitions.

  • raw – The raw, unprocessed parameter map dictionary. Preserved for future use in internationalization (i18n) and logging purposes.

Parameters:

Example

>>> param_map = ParamMap()
>>> param_map.key = "PARAM_66"
>>> param_map.group = "P6"
>>> param_map.paths = {"v": ["status", "value"], "u": ["status", "unit"]}
command_rules: list[dict[str, Any]]
component_type: str | None
group: str | None
key: str
limits: dict[str, Any] | None
origin: str
paths: dict[str, list[dict[str, Any]]]
raw: dict[str, Any]
status_conditions: dict[str, list[dict[str, Any]]] | None
status_flags: list[dict[str, Any]]
units: str | int | float | dict[str, Any] | list[Any] | None
class pybragerone.models.catalog.TranslationConfig(translations: list[dict[str, Any]], default_translation: str)[source]

Bases: object

Configuration of available translations.

Parameters:
default_translation: str
translations: list[dict[str, Any]]