Skip to main content

Python client for Liberty Global Horizon settop boxes

Project description

LG Horizon API Python Library

A Python library to interact with and control LG Horizon set-top boxes. This library provides functionalities for authentication, real-time device status monitoring via MQTT, and various control commands for your Horizon devices.

Features

  • Authentication: Supports authentication using username/password or a refresh token. The library automatically handles access token refreshing.
  • Device Management: Discover and manage multiple LG Horizon set-top boxes associated with your account.
  • Real-time Status: Monitor device status (online/running/standby) and current playback information (channel, show, VOD, recording, app) through MQTT.
  • Channel Information: Retrieve a list of available channels and profile-specific favorite channels.
  • Recording Management:
    • Get a list of all recordings.
    • Retrieve recordings for specific shows.
    • Check recording quota and usage.
  • Device Control: Send various commands to your set-top box:
    • Power on/off.
    • Play, pause, stop, rewind, fast forward.
    • Change channels (up/down, direct channel selection).
    • Record current program.
    • Set player position for VOD/recordings.
    • Display custom messages on the TV screen.
    • Send emulated remote control key presses.
  • Robustness: Includes automatic MQTT reconnection with exponential backoff and token refresh logic to maintain a stable connection.

Installation

pip install lghorizon-python # (Replace with actual package name if different)

Usage

Here's a basic example of how to use the library to connect to your LG Horizon devices and monitor their state:

First, create a secrets.json file in the root of your project with your LG Horizon credentials:

{
  "username": "your_username",
  "password": "your_password",
  "country": "nl" // e.g., "nl" for Netherlands, "be" for Belgium
}

Then, you can use the library as follows:

import asyncio
import json
import logging
import aiohttp

from lghorizon.lghorizon_api import LGHorizonApi
from lghorizon.lghorizon_models import LGHorizonAuth

_LOGGER = logging.getLogger(__name__)

async def main():
    logging.basicConfig(level=logging.INFO) # Set to DEBUG for more verbose output

    with open("secrets.json", encoding="utf-8") as f:
        secrets = json.load(f)
        username = secrets.get("username")
        password = secrets.get("password")
        country = secrets.get("country", "nl")

    async with aiohttp.ClientSession() as session:
        auth = LGHorizonAuth(session, country, username=username, password=password)
        api = LGHorizonApi(auth)

        async def device_state_changed_callback(device_id: str):
            device = devices[device_id]
            _LOGGER.info(
                f"Device {device.device_friendly_name} ({device.device_id}) state changed:\n"
                f"  State: {device.device_state.state.value}\n"
                f"  UI State: {device.device_state.ui_state_type.value}\n"
                f"  Source Type: {device.device_state.source_type.value}\n"
                f"  Channel: {device.device_state.channel_name or 'N/A'} ({device.device_state.channel_id or 'N/A'})\n"
                f"  Show: {device.device_state.show_title or 'N/A'}\n"
                f"  Episode: {device.device_state.episode_title or 'N/A'}\n"
                f"  Position: {device.device_state.position or 'N/A'} / {device.device_state.duration or 'N/A'}\n"
            )

        try:
            _LOGGER.info("Initializing LG Horizon API...")
            await api.initialize()
            devices = await api.get_devices()

            for device in devices.values():
                _LOGGER.info(f"Registering callback for device: {device.device_friendly_name}")
                await device.set_callback(device_state_changed_callback)

            _LOGGER.info("API initialized. Monitoring device states. Press Ctrl+C to exit.")
            # Keep the script running to receive MQTT updates
            while True:
                await asyncio.sleep(3600) # Sleep for a long time, MQTT callbacks will still fire

        except Exception as e:
            _LOGGER.error(f"An error occurred: {e}", exc_info=True)
        finally:
            _LOGGER.info("Disconnecting from LG Horizon API.")
            await api.disconnect()
            _LOGGER.info("Disconnected.")

if __name__ == "__main__":
    asyncio.run(main())

Authentication

The LGHorizonAuth class handles authentication. You can initialize it with a username and password, or directly with a refresh token if you have one. The library automatically refreshes access tokens as needed.

# Using username and password
auth = LGHorizonAuth(session, "nl", username="your_username", password="your_password")

# Using a refresh token (e.g., if you've saved it from a previous session)
# auth = LGHorizonAuth(session, "nl", refresh_token="your_refresh_token")

You can also set a callback to receive the updated refresh token when it's refreshed, allowing you to persist it for future sessions:

def token_updated_callback(new_refresh_token: str):
    print(f"New refresh token received: {new_refresh_token}")
    # Here you would typically save this new_refresh_token
    # to your secrets.json or other persistent storage.

# After initializing LGHorizonApi:
# api.set_token_refresh_callback(token_updated_callback)

Error Handling

The library defines custom exceptions for common error scenarios:

  • LGHorizonApiError: Base exception for all API-related errors.
  • LGHorizonApiConnectionError: Raised for network or connection issues.
  • LGHorizonApiUnauthorizedError: Raised when authentication fails (e.g., invalid credentials).
  • LGHorizonApiLockedError: A specific type of LGHorizonApiUnauthorizedError indicating a locked account.

These exceptions allow for more granular error handling in your application.

Development

To run the example script (main.py) from the repository:

  1. Clone this repository.
  2. Install dependencies: pip install -r requirements.txt (ensure requirements.txt is up-to-date).
  3. Create a secrets.json file as described in the Usage section.
  4. Run python main.py.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lghorizon-0.9.12.tar.gz (32.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lghorizon-0.9.12-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file lghorizon-0.9.12.tar.gz.

File metadata

  • Download URL: lghorizon-0.9.12.tar.gz
  • Upload date:
  • Size: 32.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lghorizon-0.9.12.tar.gz
Algorithm Hash digest
SHA256 d6bcd6955af366ed32ff2e161e5076e5b7a1e30e48496687e6b964ba24113a4e
MD5 507d1819fd3805b0764a88ac1b0c2d17
BLAKE2b-256 15a09fee7c78b894a87409c50d038292b1fc83c386c5c50fc43f0aad24476613

See more details on using hashes here.

Provenance

The following attestation bundles were made for lghorizon-0.9.12.tar.gz:

Publisher: publish-to-pypi.yml on Sholofly/lghorizon-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lghorizon-0.9.12-py3-none-any.whl.

File metadata

  • Download URL: lghorizon-0.9.12-py3-none-any.whl
  • Upload date:
  • Size: 28.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lghorizon-0.9.12-py3-none-any.whl
Algorithm Hash digest
SHA256 6cd3e25d4215c17357f622e82ce80c6c45fcbe832639a30a61fb4a345b05b34b
MD5 110444728cee671eb7de1c7bcb75bccd
BLAKE2b-256 050122adee4aef290ff25108fc410dfc3d0446ef2c36b214f28bf2f162c0cea9

See more details on using hashes here.

Provenance

The following attestation bundles were made for lghorizon-0.9.12-py3-none-any.whl:

Publisher: publish-to-pypi.yml on Sholofly/lghorizon-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page