lghorizon 0.9.0.dev4__tar.gz → 0.9.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/.github/workflows/build-on-pr.yml +1 -1
  2. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/.github/workflows/publish-to-pypi.yml +1 -1
  3. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/.gitignore +1 -0
  4. lghorizon-0.9.2/.vscode/launch.json +15 -0
  5. lghorizon-0.9.2/PKG-INFO +189 -0
  6. lghorizon-0.9.2/README.md +151 -0
  7. lghorizon-0.9.2/lghorizon/__init__.py +74 -0
  8. lghorizon-0.9.2/lghorizon/const.py +90 -0
  9. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon/exceptions.py +3 -3
  10. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon/helpers.py +1 -1
  11. lghorizon-0.9.2/lghorizon/lghorizon_api.py +300 -0
  12. lghorizon-0.9.2/lghorizon/lghorizon_device.py +409 -0
  13. lghorizon-0.9.2/lghorizon/lghorizon_device_state_processor.py +364 -0
  14. lghorizon-0.9.2/lghorizon/lghorizon_message_factory.py +38 -0
  15. lghorizon-0.9.2/lghorizon/lghorizon_models.py +1512 -0
  16. lghorizon-0.9.2/lghorizon/lghorizon_mqtt_client.py +335 -0
  17. lghorizon-0.9.2/lghorizon/lghorizon_recording_factory.py +55 -0
  18. lghorizon-0.9.2/lghorizon.egg-info/PKG-INFO +189 -0
  19. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon.egg-info/SOURCES.txt +8 -2
  20. lghorizon-0.9.2/main.py +119 -0
  21. lghorizon-0.9.2/renovate.json +7 -0
  22. lghorizon-0.9.0.dev4/PKG-INFO +0 -41
  23. lghorizon-0.9.0.dev4/README.md +0 -3
  24. lghorizon-0.9.0.dev4/lghorizon/__init__.py +0 -41
  25. lghorizon-0.9.0.dev4/lghorizon/const.py +0 -148
  26. lghorizon-0.9.0.dev4/lghorizon/lghorizon_api.py +0 -539
  27. lghorizon-0.9.0.dev4/lghorizon/models.py +0 -768
  28. lghorizon-0.9.0.dev4/lghorizon.egg-info/PKG-INFO +0 -41
  29. lghorizon-0.9.0.dev4/renovate.json +0 -7
  30. lghorizon-0.9.0.dev4/test.py +0 -84
  31. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/.coverage +0 -0
  32. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/.flake8 +0 -0
  33. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/LICENSE +0 -0
  34. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/instructions.txt +0 -0
  35. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon/py.typed +0 -0
  36. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon.egg-info/dependency_links.txt +0 -0
  37. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon.egg-info/not-zip-safe +0 -0
  38. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon.egg-info/requires.txt +0 -0
  39. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lghorizon.egg-info/top_level.txt +0 -0
  40. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/lib64 +0 -0
  41. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/pyvenv.cfg +0 -0
  42. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/secrets_stub.json +0 -0
  43. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/setup.cfg +0 -0
  44. {lghorizon-0.9.0.dev4 → lghorizon-0.9.2}/setup.py +0 -0
@@ -11,7 +11,7 @@ jobs:
11
11
  steps:
12
12
  - uses: actions/checkout@master
13
13
  - name: Set up Python 3.10
14
- uses: actions/setup-python@v5
14
+ uses: actions/setup-python@v6
15
15
  with:
16
16
  python-version: '3.13'
17
17
  - name: Install pypa/build
@@ -12,7 +12,7 @@ jobs:
12
12
  steps:
13
13
  - uses: actions/checkout@master
14
14
  - name: Set up Python 3.10
15
- uses: actions/setup-python@v5
15
+ uses: actions/setup-python@v6
16
16
  with:
17
17
  python-version: '3.13'
18
18
 
@@ -24,3 +24,4 @@ __pycache__/*
24
24
  test/nl.py
25
25
  secrets.json
26
26
  logfile.log
27
+ lghorizon.log
@@ -0,0 +1,15 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Python Debugger: Debug LGHorizon",
9
+ "type": "debugpy",
10
+ "request": "launch",
11
+ "program": "main.py",
12
+ "console": "integratedTerminal"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: lghorizon
3
+ Version: 0.9.2
4
+ Summary: Python client for Liberty Global Horizon settop boxes
5
+ Home-page: https://github.com/sholofly/LGHorizon-python
6
+ Author: Rudolf Offereins
7
+ Author-email: r.offereins@gmail.com
8
+ License: MIT license
9
+ Keywords: LG,Horizon,API,Settop box
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Natural Language :: English
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3.6
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: paho-mqtt
24
+ Requires-Dist: requests>=2.22.0
25
+ Requires-Dist: backoff>=1.9.0
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: keywords
33
+ Dynamic: license
34
+ Dynamic: license-file
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # LG Horizon API Python Library
40
+
41
+ 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.
42
+
43
+ ## Features
44
+
45
+ - **Authentication**: Supports authentication using username/password or a refresh token. The library automatically handles access token refreshing.
46
+ - **Device Management**: Discover and manage multiple LG Horizon set-top boxes associated with your account.
47
+ - **Real-time Status**: Monitor device status (online/running/standby) and current playback information (channel, show, VOD, recording, app) through MQTT.
48
+ - **Channel Information**: Retrieve a list of available channels and profile-specific favorite channels.
49
+ - **Recording Management**:
50
+ - Get a list of all recordings.
51
+ - Retrieve recordings for specific shows.
52
+ - Check recording quota and usage.
53
+ - **Device Control**: Send various commands to your set-top box:
54
+ - Power on/off.
55
+ - Play, pause, stop, rewind, fast forward.
56
+ - Change channels (up/down, direct channel selection).
57
+ - Record current program.
58
+ - Set player position for VOD/recordings.
59
+ - Display custom messages on the TV screen.
60
+ - Send emulated remote control key presses.
61
+ - **Robustness**: Includes automatic MQTT reconnection with exponential backoff and token refresh logic to maintain a stable connection.
62
+
63
+ ## Installation
64
+
65
+ ```bash
66
+ pip install lghorizon-python # (Replace with actual package name if different)
67
+ ```
68
+
69
+ ## Usage
70
+
71
+ Here's a basic example of how to use the library to connect to your LG Horizon devices and monitor their state:
72
+
73
+ First, create a `secrets.json` file in the root of your project with your LG Horizon credentials:
74
+
75
+ ```json
76
+ {
77
+ "username": "your_username",
78
+ "password": "your_password",
79
+ "country": "nl" // e.g., "nl" for Netherlands, "be" for Belgium
80
+ }
81
+ ```
82
+
83
+ Then, you can use the library as follows:
84
+
85
+ ```python
86
+ import asyncio
87
+ import json
88
+ import logging
89
+ import aiohttp
90
+
91
+ from lghorizon.lghorizon_api import LGHorizonApi
92
+ from lghorizon.lghorizon_models import LGHorizonAuth
93
+
94
+ _LOGGER = logging.getLogger(__name__)
95
+
96
+ async def main():
97
+ logging.basicConfig(level=logging.INFO) # Set to DEBUG for more verbose output
98
+
99
+ with open("secrets.json", encoding="utf-8") as f:
100
+ secrets = json.load(f)
101
+ username = secrets.get("username")
102
+ password = secrets.get("password")
103
+ country = secrets.get("country", "nl")
104
+
105
+ async with aiohttp.ClientSession() as session:
106
+ auth = LGHorizonAuth(session, country, username=username, password=password)
107
+ api = LGHorizonApi(auth)
108
+
109
+ async def device_state_changed_callback(device_id: str):
110
+ device = devices[device_id]
111
+ _LOGGER.info(
112
+ f"Device {device.device_friendly_name} ({device.device_id}) state changed:\n"
113
+ f" State: {device.device_state.state.value}\n"
114
+ f" UI State: {device.device_state.ui_state_type.value}\n"
115
+ f" Source Type: {device.device_state.source_type.value}\n"
116
+ f" Channel: {device.device_state.channel_name or 'N/A'} ({device.device_state.channel_id or 'N/A'})\n"
117
+ f" Show: {device.device_state.show_title or 'N/A'}\n"
118
+ f" Episode: {device.device_state.episode_title or 'N/A'}\n"
119
+ f" Position: {device.device_state.position or 'N/A'} / {device.device_state.duration or 'N/A'}\n"
120
+ )
121
+
122
+ try:
123
+ _LOGGER.info("Initializing LG Horizon API...")
124
+ await api.initialize()
125
+ devices = await api.get_devices()
126
+
127
+ for device in devices.values():
128
+ _LOGGER.info(f"Registering callback for device: {device.device_friendly_name}")
129
+ await device.set_callback(device_state_changed_callback)
130
+
131
+ _LOGGER.info("API initialized. Monitoring device states. Press Ctrl+C to exit.")
132
+ # Keep the script running to receive MQTT updates
133
+ while True:
134
+ await asyncio.sleep(3600) # Sleep for a long time, MQTT callbacks will still fire
135
+
136
+ except Exception as e:
137
+ _LOGGER.error(f"An error occurred: {e}", exc_info=True)
138
+ finally:
139
+ _LOGGER.info("Disconnecting from LG Horizon API.")
140
+ await api.disconnect()
141
+ _LOGGER.info("Disconnected.")
142
+
143
+ if __name__ == "__main__":
144
+ asyncio.run(main())
145
+ ```
146
+
147
+ ## Authentication
148
+
149
+ 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.
150
+
151
+ ```python
152
+ # Using username and password
153
+ auth = LGHorizonAuth(session, "nl", username="your_username", password="your_password")
154
+
155
+ # Using a refresh token (e.g., if you've saved it from a previous session)
156
+ # auth = LGHorizonAuth(session, "nl", refresh_token="your_refresh_token")
157
+ ```
158
+
159
+ You can also set a callback to receive the updated refresh token when it's refreshed, allowing you to persist it for future sessions:
160
+
161
+ ```python
162
+ def token_updated_callback(new_refresh_token: str):
163
+ print(f"New refresh token received: {new_refresh_token}")
164
+ # Here you would typically save this new_refresh_token
165
+ # to your secrets.json or other persistent storage.
166
+
167
+ # After initializing LGHorizonApi:
168
+ # api.set_token_refresh_callback(token_updated_callback)
169
+ ```
170
+
171
+ ## Error Handling
172
+
173
+ The library defines custom exceptions for common error scenarios:
174
+
175
+ - `LGHorizonApiError`: Base exception for all API-related errors.
176
+ - `LGHorizonApiConnectionError`: Raised for network or connection issues.
177
+ - `LGHorizonApiUnauthorizedError`: Raised when authentication fails (e.g., invalid credentials).
178
+ - `LGHorizonApiLockedError`: A specific type of `LGHorizonApiUnauthorizedError` indicating a locked account.
179
+
180
+ These exceptions allow for more granular error handling in your application.
181
+
182
+ ## Development
183
+
184
+ To run the example script (`main.py`) from the repository:
185
+
186
+ 1. Clone this repository.
187
+ 2. Install dependencies: `pip install -r requirements.txt` (ensure `requirements.txt` is up-to-date).
188
+ 3. Create a `secrets.json` file as described in the Usage section.
189
+ 4. Run `python main.py`.
@@ -0,0 +1,151 @@
1
+ # LG Horizon API Python Library
2
+
3
+ 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.
4
+
5
+ ## Features
6
+
7
+ - **Authentication**: Supports authentication using username/password or a refresh token. The library automatically handles access token refreshing.
8
+ - **Device Management**: Discover and manage multiple LG Horizon set-top boxes associated with your account.
9
+ - **Real-time Status**: Monitor device status (online/running/standby) and current playback information (channel, show, VOD, recording, app) through MQTT.
10
+ - **Channel Information**: Retrieve a list of available channels and profile-specific favorite channels.
11
+ - **Recording Management**:
12
+ - Get a list of all recordings.
13
+ - Retrieve recordings for specific shows.
14
+ - Check recording quota and usage.
15
+ - **Device Control**: Send various commands to your set-top box:
16
+ - Power on/off.
17
+ - Play, pause, stop, rewind, fast forward.
18
+ - Change channels (up/down, direct channel selection).
19
+ - Record current program.
20
+ - Set player position for VOD/recordings.
21
+ - Display custom messages on the TV screen.
22
+ - Send emulated remote control key presses.
23
+ - **Robustness**: Includes automatic MQTT reconnection with exponential backoff and token refresh logic to maintain a stable connection.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install lghorizon-python # (Replace with actual package name if different)
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Here's a basic example of how to use the library to connect to your LG Horizon devices and monitor their state:
34
+
35
+ First, create a `secrets.json` file in the root of your project with your LG Horizon credentials:
36
+
37
+ ```json
38
+ {
39
+ "username": "your_username",
40
+ "password": "your_password",
41
+ "country": "nl" // e.g., "nl" for Netherlands, "be" for Belgium
42
+ }
43
+ ```
44
+
45
+ Then, you can use the library as follows:
46
+
47
+ ```python
48
+ import asyncio
49
+ import json
50
+ import logging
51
+ import aiohttp
52
+
53
+ from lghorizon.lghorizon_api import LGHorizonApi
54
+ from lghorizon.lghorizon_models import LGHorizonAuth
55
+
56
+ _LOGGER = logging.getLogger(__name__)
57
+
58
+ async def main():
59
+ logging.basicConfig(level=logging.INFO) # Set to DEBUG for more verbose output
60
+
61
+ with open("secrets.json", encoding="utf-8") as f:
62
+ secrets = json.load(f)
63
+ username = secrets.get("username")
64
+ password = secrets.get("password")
65
+ country = secrets.get("country", "nl")
66
+
67
+ async with aiohttp.ClientSession() as session:
68
+ auth = LGHorizonAuth(session, country, username=username, password=password)
69
+ api = LGHorizonApi(auth)
70
+
71
+ async def device_state_changed_callback(device_id: str):
72
+ device = devices[device_id]
73
+ _LOGGER.info(
74
+ f"Device {device.device_friendly_name} ({device.device_id}) state changed:\n"
75
+ f" State: {device.device_state.state.value}\n"
76
+ f" UI State: {device.device_state.ui_state_type.value}\n"
77
+ f" Source Type: {device.device_state.source_type.value}\n"
78
+ f" Channel: {device.device_state.channel_name or 'N/A'} ({device.device_state.channel_id or 'N/A'})\n"
79
+ f" Show: {device.device_state.show_title or 'N/A'}\n"
80
+ f" Episode: {device.device_state.episode_title or 'N/A'}\n"
81
+ f" Position: {device.device_state.position or 'N/A'} / {device.device_state.duration or 'N/A'}\n"
82
+ )
83
+
84
+ try:
85
+ _LOGGER.info("Initializing LG Horizon API...")
86
+ await api.initialize()
87
+ devices = await api.get_devices()
88
+
89
+ for device in devices.values():
90
+ _LOGGER.info(f"Registering callback for device: {device.device_friendly_name}")
91
+ await device.set_callback(device_state_changed_callback)
92
+
93
+ _LOGGER.info("API initialized. Monitoring device states. Press Ctrl+C to exit.")
94
+ # Keep the script running to receive MQTT updates
95
+ while True:
96
+ await asyncio.sleep(3600) # Sleep for a long time, MQTT callbacks will still fire
97
+
98
+ except Exception as e:
99
+ _LOGGER.error(f"An error occurred: {e}", exc_info=True)
100
+ finally:
101
+ _LOGGER.info("Disconnecting from LG Horizon API.")
102
+ await api.disconnect()
103
+ _LOGGER.info("Disconnected.")
104
+
105
+ if __name__ == "__main__":
106
+ asyncio.run(main())
107
+ ```
108
+
109
+ ## Authentication
110
+
111
+ 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.
112
+
113
+ ```python
114
+ # Using username and password
115
+ auth = LGHorizonAuth(session, "nl", username="your_username", password="your_password")
116
+
117
+ # Using a refresh token (e.g., if you've saved it from a previous session)
118
+ # auth = LGHorizonAuth(session, "nl", refresh_token="your_refresh_token")
119
+ ```
120
+
121
+ You can also set a callback to receive the updated refresh token when it's refreshed, allowing you to persist it for future sessions:
122
+
123
+ ```python
124
+ def token_updated_callback(new_refresh_token: str):
125
+ print(f"New refresh token received: {new_refresh_token}")
126
+ # Here you would typically save this new_refresh_token
127
+ # to your secrets.json or other persistent storage.
128
+
129
+ # After initializing LGHorizonApi:
130
+ # api.set_token_refresh_callback(token_updated_callback)
131
+ ```
132
+
133
+ ## Error Handling
134
+
135
+ The library defines custom exceptions for common error scenarios:
136
+
137
+ - `LGHorizonApiError`: Base exception for all API-related errors.
138
+ - `LGHorizonApiConnectionError`: Raised for network or connection issues.
139
+ - `LGHorizonApiUnauthorizedError`: Raised when authentication fails (e.g., invalid credentials).
140
+ - `LGHorizonApiLockedError`: A specific type of `LGHorizonApiUnauthorizedError` indicating a locked account.
141
+
142
+ These exceptions allow for more granular error handling in your application.
143
+
144
+ ## Development
145
+
146
+ To run the example script (`main.py`) from the repository:
147
+
148
+ 1. Clone this repository.
149
+ 2. Install dependencies: `pip install -r requirements.txt` (ensure `requirements.txt` is up-to-date).
150
+ 3. Create a `secrets.json` file as described in the Usage section.
151
+ 4. Run `python main.py`.
@@ -0,0 +1,74 @@
1
+ """Python client for LG Horizon."""
2
+
3
+ from .lghorizon_api import LGHorizonApi
4
+ from .lghorizon_device import LGHorizonDevice
5
+ from .lghorizon_models import (
6
+ LGHorizonAuth,
7
+ LGHorizonChannel,
8
+ LGHorizonCustomer,
9
+ LGHorizonDeviceState,
10
+ LGHorizonProfile,
11
+ LGHorizonRecording,
12
+ LGHorizonRecordingList,
13
+ LGHorizonShowRecordingList,
14
+ LGHorizonRecordingSeason,
15
+ LGHorizonRecordingSingle,
16
+ LGHorizonRecordingShow,
17
+ LGHorizonRecordingQuota,
18
+ LGHorizonRecordingType,
19
+ LGHorizonUIStateType,
20
+ LGHorizonMessageType,
21
+ LGHorizonRunningState,
22
+ LGHorizonRecordingSource,
23
+ LGHorizonRecordingState,
24
+ LGHorizonSourceType,
25
+ LGHorizonPlayerState,
26
+ LGHorizonAppsState,
27
+ LGHorizonUIState,
28
+ LGHorizonProfileOptions,
29
+ LGHorizonServicesConfig,
30
+ )
31
+ from .exceptions import (
32
+ LGHorizonApiError,
33
+ LGHorizonApiConnectionError,
34
+ LGHorizonApiUnauthorizedError,
35
+ LGHorizonApiLockedError,
36
+ )
37
+
38
+ from .const import COUNTRY_SETTINGS
39
+
40
+ __all__ = [
41
+ "LGHorizonApi",
42
+ "LGHorizonDevice",
43
+ "LGHorizonAuth",
44
+ "LGHorizonChannel",
45
+ "LGHorizonCustomer",
46
+ "LGHorizonDeviceState",
47
+ "LGHorizonProfile",
48
+ "LGHorizonApiError",
49
+ "LGHorizonApiConnectionError",
50
+ "LGHorizonApiUnauthorizedError",
51
+ "LGHorizonApiLockedError",
52
+ "LGHorizonRecordingList",
53
+ "LGHorizonRecordingSeason",
54
+ "LGHorizonRecordingSingle",
55
+ "LGHorizonRecordingShow",
56
+ "LGHorizonRecordingQuota",
57
+ "LGHorizonRecordingType",
58
+ "LGHorizonUIStateType",
59
+ "LGHorizonMessageType",
60
+ "LGHorizonRunningState",
61
+ "LGHorizonRecordingSource",
62
+ "LGHorizonRecordingState",
63
+ "LGHorizonSourceType",
64
+ "LGHorizonPlayerState",
65
+ "LGHorizonAppsState",
66
+ "LGHorizonUIState",
67
+ "LGHorizonProfileOptions",
68
+ "LGHorizonProfile",
69
+ "LGHorizonAuth",
70
+ "LGHorizonServicesConfig",
71
+ "LGHorizonRecording",
72
+ "LGHorizonShowRecordingList",
73
+ "COUNTRY_SETTINGS",
74
+ ]
@@ -0,0 +1,90 @@
1
+ """Python client for LGHorizon."""
2
+
3
+ # flake8: noqa
4
+ # Box states
5
+ ONLINE_RUNNING = "ONLINE_RUNNING"
6
+ ONLINE_STANDBY = "ONLINE_STANDBY"
7
+ UNKNOWN = "UNKNOWN"
8
+
9
+ BOX_PLAY_STATE_CHANNEL = "linear"
10
+ BOX_PLAY_STATE_REPLAY = "replay"
11
+ BOX_PLAY_STATE_DVR = "nDVR"
12
+ BOX_PLAY_STATE_BUFFER = "reviewbuffer"
13
+ BOX_PLAY_STATE_APP = "app"
14
+ BOX_PLAY_STATE_VOD = "VOD"
15
+
16
+ # List with available media keys.
17
+ MEDIA_KEY_POWER = "Power"
18
+ MEDIA_KEY_ENTER = "Enter"
19
+ MEDIA_KEY_ESCAPE = "Escape" # Not yet implemented
20
+
21
+ MEDIA_KEY_HELP = "Help" # Not yet implemented
22
+ MEDIA_KEY_INFO = "Info" # Not yet implemented
23
+ MEDIA_KEY_GUIDE = "Guide" # Not yet implemented
24
+
25
+ MEDIA_KEY_CONTEXT_MENU = "ContextMenu" # Not yet implemented
26
+ MEDIA_KEY_CHANNEL_UP = "ChannelUp"
27
+ MEDIA_KEY_CHANNEL_DOWN = "ChannelDown"
28
+
29
+ MEDIA_KEY_RECORD = "MediaRecord"
30
+ MEDIA_KEY_PLAY_PAUSE = "MediaPlayPause"
31
+ MEDIA_KEY_STOP = "MediaStop"
32
+ MEDIA_KEY_REWIND = "MediaRewind"
33
+ MEDIA_KEY_FAST_FORWARD = "MediaFastForward"
34
+
35
+ RECORDING_TYPE_SINGLE = "single"
36
+ RECORDING_TYPE_SHOW = "show"
37
+ RECORDING_TYPE_SEASON = "season"
38
+
39
+ BE_AUTH_URL = "https://login.prd.telenet.be/openid/login.do"
40
+
41
+ PLATFORM_TYPES = {
42
+ "EOS": {"manufacturer": "Arris", "model": "DCX960"},
43
+ "EOS2": {"manufacturer": "HUMAX", "model": "2008C-STB-TN"},
44
+ "HORIZON": {"manufacturer": "Arris", "model": "DCX960"},
45
+ "APOLLO": {"manufacturer": "Arris", "model": "VIP5002W"},
46
+ }
47
+
48
+ COUNTRY_SETTINGS = {
49
+ "nl": {
50
+ "api_url": "https://spark-prod-nl.gnp.cloud.ziggogo.tv",
51
+ "mqtt_url": "obomsg.prod.nl.horizon.tv",
52
+ "use_refreshtoken": False,
53
+ "name": "Ziggo",
54
+ },
55
+ "ch": {
56
+ "api_url": "https://spark-prod-ch.gnp.cloud.sunrisetv.ch",
57
+ "use_refreshtoken": True,
58
+ "name": "UPC Switzerland",
59
+ },
60
+ "be-basetv": {
61
+ "api_url": "https://spark-prod-be.gnp.cloud.base.tv",
62
+ "use_refreshtoken": True,
63
+ "name": "BASE TV (BE)",
64
+ },
65
+ "be-nl": {
66
+ "api_url": "https://spark-prod-be.gnp.cloud.telenet.tv",
67
+ "use_refreshtoken": True,
68
+ "name": "Telenet (BE)",
69
+ },
70
+ "be-nl-preprod": {
71
+ "api_url": "https://spark-preprod-be.gnp.cloud.telenet.tv",
72
+ "use_refreshtoken": True,
73
+ "name": "Telenet (BE, PREPROD)",
74
+ },
75
+ "gb": {
76
+ "api_url": "https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com",
77
+ "use_refreshtoken": True,
78
+ "name": "Virgin Media (GB)",
79
+ },
80
+ "ie": {
81
+ "api_url": "https://spark-prod-ie.gnp.cloud.virginmediatv.ie",
82
+ "use_refreshtoken": False,
83
+ "name": "Virgin Media (IE)",
84
+ },
85
+ "pl": {
86
+ "api_url": "https://spark-prod-pl.gnp.cloud.upctv.pl",
87
+ "use_refreshtoken": False,
88
+ "name": "UPC (PL)",
89
+ },
90
+ }
@@ -6,12 +6,12 @@ class LGHorizonApiError(Exception):
6
6
 
7
7
 
8
8
  class LGHorizonApiConnectionError(LGHorizonApiError):
9
- """Generic LGHorizon exception."""
9
+ """Exception for connection-related errors with the LG Horizon API."""
10
10
 
11
11
 
12
12
  class LGHorizonApiUnauthorizedError(Exception):
13
- """Generic LGHorizon exception."""
13
+ """Exception for unauthorized access to the LG Horizon API."""
14
14
 
15
15
 
16
16
  class LGHorizonApiLockedError(LGHorizonApiUnauthorizedError):
17
- """Generic LGHorizon exception."""
17
+ """Exception for locked account errors with the LG Horizon API."""
@@ -3,7 +3,7 @@
3
3
  import random
4
4
 
5
5
 
6
- def make_id(string_length=10):
6
+ async def make_id(string_length=10):
7
7
  """Create an id with given length."""
8
8
  letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
9
9
  return "".join(random.choice(letters) for i in range(string_length))