lghorizon 0.9.0b0__py3-none-any.whl → 0.9.0.dev1__py3-none-any.whl
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.
- lghorizon/__init__.py +34 -4
- lghorizon/{lghorizon_device_state_processor.py → device_state_processor.py} +9 -9
- lghorizon/{lghorizon_api.py → lghorizonapi.py} +16 -16
- lghorizon/{lghorizon_message_factory.py → message_factory.py} +1 -1
- lghorizon/{lghorizon_recording_factory.py → recording_factory.py} +1 -1
- {lghorizon-0.9.0b0.dist-info → lghorizon-0.9.0.dev1.dist-info}/METADATA +1 -1
- lghorizon-0.9.0.dev1.dist-info/RECORD +13 -0
- lghorizon/exceptions.py +0 -17
- lghorizon/lghorizon_device.py +0 -336
- lghorizon/lghorizon_models.py +0 -1331
- lghorizon/lghorizon_mqtt_client.py +0 -123
- lghorizon-0.9.0b0.dist-info/RECORD +0 -17
- {lghorizon-0.9.0b0.dist-info → lghorizon-0.9.0.dev1.dist-info}/WHEEL +0 -0
- {lghorizon-0.9.0b0.dist-info → lghorizon-0.9.0.dev1.dist-info}/licenses/LICENSE +0 -0
- {lghorizon-0.9.0b0.dist-info → lghorizon-0.9.0.dev1.dist-info}/top_level.txt +0 -0
lghorizon/__init__.py
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
"""Python client for LG Horizon."""
|
|
2
2
|
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
from .lghorizonapi import LGHorizonApi
|
|
4
|
+
from .models.lghorizon_auth import (
|
|
5
|
+
LGHorizonAuth,
|
|
6
|
+
)
|
|
7
|
+
from .models.exceptions import (
|
|
8
|
+
LGHorizonApiUnauthorizedError,
|
|
9
|
+
LGHorizonApiConnectionError,
|
|
10
|
+
LGHorizonApiLockedError,
|
|
11
|
+
)
|
|
12
|
+
from .const import (
|
|
13
|
+
ONLINE_RUNNING,
|
|
14
|
+
ONLINE_STANDBY,
|
|
15
|
+
RECORDING_TYPE_SHOW,
|
|
16
|
+
RECORDING_TYPE_SEASON,
|
|
17
|
+
RECORDING_TYPE_SINGLE,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"LGHorizonApi",
|
|
22
|
+
"LGHorizonBox",
|
|
23
|
+
"LGHorizonRecordingListSeasonShow",
|
|
24
|
+
"LGHorizonRecordingSingle",
|
|
25
|
+
"LGHorizonRecordingShow",
|
|
26
|
+
"LGHorizonRecordingEpisode",
|
|
27
|
+
"LGHorizonCustomer",
|
|
28
|
+
"LGHorizonApiUnauthorizedError",
|
|
29
|
+
"LGHorizonApiConnectionError",
|
|
30
|
+
"LGHorizonApiLockedError",
|
|
31
|
+
"ONLINE_RUNNING",
|
|
32
|
+
"ONLINE_STANDBY",
|
|
33
|
+
"RECORDING_TYPE_SHOW",
|
|
34
|
+
"RECORDING_TYPE_SEASON",
|
|
35
|
+
"RECORDING_TYPE_SINGLE",
|
|
36
|
+
] # noqa
|
|
@@ -6,9 +6,9 @@ import urllib.parse
|
|
|
6
6
|
|
|
7
7
|
from typing import cast, Dict, Optional
|
|
8
8
|
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
from .
|
|
9
|
+
from .models.lghorizon_device_state import LGHorizonDeviceState, LGHorizonRunningState
|
|
10
|
+
from .models.lghorizon_message import LGHorizonStatusMessage, LGHorizonUIStatusMessage
|
|
11
|
+
from .models.lghorizon_sources import (
|
|
12
12
|
LGHorizonSourceType,
|
|
13
13
|
LGHorizonLinearSource,
|
|
14
14
|
LGHorizonVODSource,
|
|
@@ -16,20 +16,20 @@ from .lghorizon_models import (
|
|
|
16
16
|
LGHorizonNDVRSource,
|
|
17
17
|
LGHorizonReviewBufferSource,
|
|
18
18
|
)
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
19
|
+
from .models.lghorizon_auth import LGHorizonAuth
|
|
20
|
+
from .models.lghorizon_events import (
|
|
21
21
|
LGHorizonReplayEvent,
|
|
22
22
|
LGHorizonVOD,
|
|
23
23
|
)
|
|
24
24
|
|
|
25
|
-
from .
|
|
26
|
-
from .
|
|
27
|
-
from .
|
|
25
|
+
from .models.lghorizon_recordings import LGHorizonRecordingSingle
|
|
26
|
+
from .models.lghorizon_channel import LGHorizonChannel
|
|
27
|
+
from .models.lghorizon_ui_status import (
|
|
28
28
|
LGHorizonUIStateType,
|
|
29
29
|
LGHorizonAppsState,
|
|
30
30
|
LGHorizonPlayerState,
|
|
31
31
|
)
|
|
32
|
-
from .
|
|
32
|
+
from .models.lghorizon_customer import LGHorizonCustomer
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class LGHorizonDeviceStateProcessor:
|
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
from typing import Any, Dict, cast
|
|
5
5
|
|
|
6
|
-
from .lghorizon_device import LGHorizonDevice
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
from .lghorizon_mqtt_client import LGHorizonMqttClient
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
14
|
-
from .
|
|
15
|
-
from .
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
6
|
+
from .models.lghorizon_device import LGHorizonDevice
|
|
7
|
+
from .models.lghorizon_channel import LGHorizonChannel
|
|
8
|
+
from .models.lghorizon_auth import LGHorizonAuth
|
|
9
|
+
from .models.lghorizon_customer import LGHorizonCustomer
|
|
10
|
+
from .models.lghorizon_mqtt_client import LGHorizonMqttClient
|
|
11
|
+
from .models.lghorizon_config import LGHorizonServicesConfig
|
|
12
|
+
from .models.lghorizon_entitlements import LGHorizonEntitlements
|
|
13
|
+
from .models.lghorizon_profile import LGHorizonProfile
|
|
14
|
+
from .models.lghorizon_message import LGHorizonMessageType
|
|
15
|
+
from .message_factory import LGHorizonMessageFactory
|
|
16
|
+
from .models.lghorizon_message import LGHorizonStatusMessage, LGHorizonUIStatusMessage
|
|
17
|
+
from .models.lghorizon_device_state import LGHorizonRunningState
|
|
18
|
+
from .models.lghorizon_recordings import LGHorizonRecordingList, LGHorizonRecordingQuota
|
|
19
|
+
from .recording_factory import LGHorizonRecordingFactory
|
|
20
|
+
from .device_state_processor import LGHorizonDeviceStateProcessor
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -190,7 +190,7 @@ class LGHorizonApi:
|
|
|
190
190
|
return
|
|
191
191
|
await device.handle_ui_status_message(ui_status_message)
|
|
192
192
|
|
|
193
|
-
async def _get_customer_info(self) ->
|
|
193
|
+
async def _get_customer_info(self) -> Any:
|
|
194
194
|
service_url = await self._service_config.get_service_url(
|
|
195
195
|
"personalizationService"
|
|
196
196
|
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
lghorizon/__init__.py,sha256=Hv5lGe6Nb0OlkugLpNA0gyIPFRHOGkdnUvhLS0Sn0eA,863
|
|
2
|
+
lghorizon/const.py,sha256=HINlbyevEN9ZRnfIBbSGNc6i9J8WkIgpqkLZrwyqpGQ,5307
|
|
3
|
+
lghorizon/device_state_processor.py,sha256=MuItTJoXDUeSXHW5QjmPjbdQ72JFBGLWfuo6iMKOTYk,12141
|
|
4
|
+
lghorizon/helpers.py,sha256=SGlEN6V0kh2vqw1qCKmM1KhfeO-UvPyyQmnThgFLFhs,272
|
|
5
|
+
lghorizon/lghorizonapi.py,sha256=eZmcIlbA_Xgtcq65ShVSiBXAapFdAVUIxYuBOKVV8h8,11841
|
|
6
|
+
lghorizon/message_factory.py,sha256=Bk0k6fZSJNgpmcN_IxPL26lwc6V1fCbQe7acd65Km0g,1504
|
|
7
|
+
lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
lghorizon/recording_factory.py,sha256=xcEVzchn2SSV1ojRo9N17VfaEDlD9AaYLEo92uNNgaA,1766
|
|
9
|
+
lghorizon-0.9.0.dev1.dist-info/licenses/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
|
|
10
|
+
lghorizon-0.9.0.dev1.dist-info/METADATA,sha256=zwM_v9XJf8B7v5H32jxRv3Qpt_aphskTKturNLIcnk4,1287
|
|
11
|
+
lghorizon-0.9.0.dev1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
+
lghorizon-0.9.0.dev1.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
|
|
13
|
+
lghorizon-0.9.0.dev1.dist-info/RECORD,,
|
lghorizon/exceptions.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""Exceptions for the LGHorizon API."""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class LGHorizonApiError(Exception):
|
|
5
|
-
"""Generic LGHorizon exception."""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class LGHorizonApiConnectionError(LGHorizonApiError):
|
|
9
|
-
"""Generic LGHorizon exception."""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class LGHorizonApiUnauthorizedError(Exception):
|
|
13
|
-
"""Generic LGHorizon exception."""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class LGHorizonApiLockedError(LGHorizonApiUnauthorizedError):
|
|
17
|
-
"""Generic LGHorizon exception."""
|
lghorizon/lghorizon_device.py
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
"""LG Horizon Device."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
import logging
|
|
7
|
-
from typing import Any, Callable, Coroutine, Dict, Optional
|
|
8
|
-
from .lghorizon_models import (
|
|
9
|
-
LGHorizonRunningState,
|
|
10
|
-
LGHorizonStatusMessage,
|
|
11
|
-
LGHorizonUIStatusMessage,
|
|
12
|
-
LGHorizonDeviceState,
|
|
13
|
-
LGHorizonAuth,
|
|
14
|
-
LGHorizonChannel,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
from .exceptions import LGHorizonApiConnectionError
|
|
18
|
-
from .helpers import make_id
|
|
19
|
-
from .lghorizon_device_state_processor import LGHorizonDeviceStateProcessor
|
|
20
|
-
from .lghorizon_mqtt_client import LGHorizonMqttClient
|
|
21
|
-
from .const import (
|
|
22
|
-
MEDIA_KEY_CHANNEL_DOWN,
|
|
23
|
-
MEDIA_KEY_CHANNEL_UP,
|
|
24
|
-
MEDIA_KEY_ENTER,
|
|
25
|
-
MEDIA_KEY_FAST_FORWARD,
|
|
26
|
-
MEDIA_KEY_PLAY_PAUSE,
|
|
27
|
-
MEDIA_KEY_POWER,
|
|
28
|
-
MEDIA_KEY_RECORD,
|
|
29
|
-
MEDIA_KEY_REWIND,
|
|
30
|
-
MEDIA_KEY_STOP,
|
|
31
|
-
ONLINE_RUNNING,
|
|
32
|
-
PLATFORM_TYPES,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
_LOGGER = logging.getLogger(__name__)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class LGHorizonDevice:
|
|
39
|
-
"""The LG Horizon device (set-top box)."""
|
|
40
|
-
|
|
41
|
-
_device_id: str
|
|
42
|
-
_hashed_cpe_id: str
|
|
43
|
-
_device_friendly_name: str
|
|
44
|
-
_platform_type: str
|
|
45
|
-
_device_state: LGHorizonDeviceState
|
|
46
|
-
_manufacturer: Optional[str]
|
|
47
|
-
_model: Optional[str]
|
|
48
|
-
_recording_capacity: Optional[int]
|
|
49
|
-
_device_state_processor: LGHorizonDeviceStateProcessor
|
|
50
|
-
_mqtt_client: LGHorizonMqttClient
|
|
51
|
-
_change_callback: Callable[[str], Coroutine[Any, Any, Any]]
|
|
52
|
-
_auth: LGHorizonAuth
|
|
53
|
-
_channels: Dict[str, LGHorizonChannel]
|
|
54
|
-
_last_ui_message_timestamp: int = 0
|
|
55
|
-
|
|
56
|
-
def __init__(
|
|
57
|
-
self,
|
|
58
|
-
device_json,
|
|
59
|
-
mqtt_client: LGHorizonMqttClient,
|
|
60
|
-
device_state_processor: LGHorizonDeviceStateProcessor,
|
|
61
|
-
auth: LGHorizonAuth,
|
|
62
|
-
channels: Dict[str, LGHorizonChannel],
|
|
63
|
-
):
|
|
64
|
-
"""Initialize the LG Horizon device."""
|
|
65
|
-
self._device_id = device_json["deviceId"]
|
|
66
|
-
self._hashed_cpe_id = device_json["hashedCPEId"]
|
|
67
|
-
self._device_friendly_name = device_json["settings"]["deviceFriendlyName"]
|
|
68
|
-
self._platform_type = device_json.get("platformType")
|
|
69
|
-
self._mqtt_client = mqtt_client
|
|
70
|
-
self._auth = auth
|
|
71
|
-
self._channels = channels
|
|
72
|
-
self._device_state = LGHorizonDeviceState() # Initialize state
|
|
73
|
-
self._manufacturer = None
|
|
74
|
-
self._model = None
|
|
75
|
-
self._recording_capacity = None
|
|
76
|
-
self._device_state_processor = device_state_processor
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def device_id(self) -> str:
|
|
80
|
-
"""Return the device ID."""
|
|
81
|
-
return self._device_id
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def platform_type(self) -> str:
|
|
85
|
-
"""Return the device ID."""
|
|
86
|
-
return self._platform_type
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def manufacturer(self) -> str:
|
|
90
|
-
"""Return the manufacturer of the settop box."""
|
|
91
|
-
platform_info = PLATFORM_TYPES.get(self._platform_type, dict())
|
|
92
|
-
return platform_info.get("manufacturer", "unknown")
|
|
93
|
-
|
|
94
|
-
@property
|
|
95
|
-
def model(self) -> str:
|
|
96
|
-
"""Return the model of the settop box."""
|
|
97
|
-
platform_info = PLATFORM_TYPES.get(self._platform_type, dict())
|
|
98
|
-
return platform_info.get("model", "unknown")
|
|
99
|
-
|
|
100
|
-
@property
|
|
101
|
-
def is_available(self) -> bool:
|
|
102
|
-
"""Return the availability of the settop box."""
|
|
103
|
-
return self._device_state.state in (
|
|
104
|
-
LGHorizonRunningState.ONLINE_RUNNING,
|
|
105
|
-
LGHorizonRunningState.ONLINE_STANDBY,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
@property
|
|
109
|
-
def hashed_cpe_id(self) -> str:
|
|
110
|
-
"""Return the hashed CPE ID."""
|
|
111
|
-
return self._hashed_cpe_id
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def device_friendly_name(self) -> str:
|
|
115
|
-
"""Return the device friendly name."""
|
|
116
|
-
return self._device_friendly_name
|
|
117
|
-
|
|
118
|
-
@property
|
|
119
|
-
def device_state(self) -> LGHorizonDeviceState:
|
|
120
|
-
"""Return the current playing information."""
|
|
121
|
-
return self._device_state
|
|
122
|
-
|
|
123
|
-
@property
|
|
124
|
-
def recording_capacity(self) -> Optional[int]:
|
|
125
|
-
"""Return the recording capacity used."""
|
|
126
|
-
return self._recording_capacity
|
|
127
|
-
|
|
128
|
-
@recording_capacity.setter
|
|
129
|
-
def recording_capacity(self, value: int) -> None:
|
|
130
|
-
"""Set the recording capacity used."""
|
|
131
|
-
self._recording_capacity = value
|
|
132
|
-
|
|
133
|
-
@property
|
|
134
|
-
def last_ui_message_timestamp(self) -> int:
|
|
135
|
-
"""Return the last ui message timestamp."""
|
|
136
|
-
return self._last_ui_message_timestamp
|
|
137
|
-
|
|
138
|
-
@last_ui_message_timestamp.setter
|
|
139
|
-
def last_ui_message_timestamp(self, value: int) -> None:
|
|
140
|
-
"""Set the last ui message timestamp."""
|
|
141
|
-
self._last_ui_message_timestamp = value
|
|
142
|
-
|
|
143
|
-
async def update_channels(self, channels: Dict[str, LGHorizonChannel]):
|
|
144
|
-
"""Update the channels list."""
|
|
145
|
-
self._channels = channels
|
|
146
|
-
|
|
147
|
-
async def register_mqtt(self) -> None:
|
|
148
|
-
"""Register the mqtt connection."""
|
|
149
|
-
if not self._mqtt_client.is_connected:
|
|
150
|
-
raise LGHorizonApiConnectionError("MQTT client not connected.")
|
|
151
|
-
topic = f"{self._auth.household_id}/{self._mqtt_client.client_id}/status"
|
|
152
|
-
payload = {
|
|
153
|
-
"source": self._mqtt_client.client_id,
|
|
154
|
-
"state": ONLINE_RUNNING,
|
|
155
|
-
"deviceType": "HGO",
|
|
156
|
-
}
|
|
157
|
-
await self._mqtt_client.publish_message(topic, json.dumps(payload))
|
|
158
|
-
|
|
159
|
-
async def set_callback(
|
|
160
|
-
self, change_callback: Callable[[str], Coroutine[Any, Any, Any]]
|
|
161
|
-
) -> None:
|
|
162
|
-
"""Set a callback function."""
|
|
163
|
-
self._change_callback = change_callback
|
|
164
|
-
await self.register_mqtt() # type: ignore [assignment] # Callback can be None
|
|
165
|
-
|
|
166
|
-
async def handle_status_message(
|
|
167
|
-
self, status_message: LGHorizonStatusMessage
|
|
168
|
-
) -> None:
|
|
169
|
-
"""Register a new settop box."""
|
|
170
|
-
old_running_state = self.device_state.state
|
|
171
|
-
new_running_state = status_message.running_state
|
|
172
|
-
if (
|
|
173
|
-
old_running_state == new_running_state
|
|
174
|
-
): # Access backing field for comparison
|
|
175
|
-
return
|
|
176
|
-
await self._device_state_processor.process_state(
|
|
177
|
-
self.device_state, status_message
|
|
178
|
-
) # Use the setter
|
|
179
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
180
|
-
await self._request_settop_box_state()
|
|
181
|
-
|
|
182
|
-
await self._trigger_callback()
|
|
183
|
-
await self._request_settop_box_recording_capacity()
|
|
184
|
-
|
|
185
|
-
async def handle_ui_status_message(
|
|
186
|
-
self, status_message: LGHorizonUIStatusMessage
|
|
187
|
-
) -> None:
|
|
188
|
-
"""Handle UI status message."""
|
|
189
|
-
|
|
190
|
-
await self._device_state_processor.process_ui_state(
|
|
191
|
-
self.device_state, status_message
|
|
192
|
-
)
|
|
193
|
-
self.last_ui_message_timestamp = status_message.message_timestamp
|
|
194
|
-
await self._trigger_callback()
|
|
195
|
-
|
|
196
|
-
async def update_recording_capacity(self, payload) -> None:
|
|
197
|
-
"""Updates the recording capacity."""
|
|
198
|
-
if "CPE.capacity" not in payload or "used" not in payload:
|
|
199
|
-
return
|
|
200
|
-
self.recording_capacity = payload["used"] # Use the setter
|
|
201
|
-
|
|
202
|
-
async def _trigger_callback(self):
|
|
203
|
-
if self._change_callback:
|
|
204
|
-
_LOGGER.debug("Callback called from box %s", self.device_id)
|
|
205
|
-
await self._change_callback(self.device_id)
|
|
206
|
-
|
|
207
|
-
async def turn_on(self) -> None:
|
|
208
|
-
"""Turn the settop box on."""
|
|
209
|
-
|
|
210
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_STANDBY:
|
|
211
|
-
await self.send_key_to_box(MEDIA_KEY_POWER)
|
|
212
|
-
|
|
213
|
-
async def turn_off(self) -> None:
|
|
214
|
-
"""Turn the settop box off."""
|
|
215
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
216
|
-
await self.send_key_to_box(MEDIA_KEY_POWER)
|
|
217
|
-
await self._device_state.reset()
|
|
218
|
-
|
|
219
|
-
async def pause(self) -> None:
|
|
220
|
-
"""Pause the given settopbox."""
|
|
221
|
-
if (
|
|
222
|
-
self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING
|
|
223
|
-
and not self._device_state.paused
|
|
224
|
-
):
|
|
225
|
-
await self.send_key_to_box(MEDIA_KEY_PLAY_PAUSE)
|
|
226
|
-
|
|
227
|
-
async def play(self) -> None:
|
|
228
|
-
"""Resume the settopbox."""
|
|
229
|
-
if (
|
|
230
|
-
self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING
|
|
231
|
-
and self._device_state.paused
|
|
232
|
-
):
|
|
233
|
-
await self.send_key_to_box(MEDIA_KEY_PLAY_PAUSE)
|
|
234
|
-
|
|
235
|
-
async def stop(self) -> None:
|
|
236
|
-
"""Stop the settopbox."""
|
|
237
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
238
|
-
await self.send_key_to_box(MEDIA_KEY_STOP)
|
|
239
|
-
|
|
240
|
-
async def next_channel(self):
|
|
241
|
-
"""Select the next channel for given settop box."""
|
|
242
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
243
|
-
await self.send_key_to_box(MEDIA_KEY_CHANNEL_UP)
|
|
244
|
-
|
|
245
|
-
async def previous_channel(self) -> None:
|
|
246
|
-
"""Select the previous channel for given settop box."""
|
|
247
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
248
|
-
await self.send_key_to_box(MEDIA_KEY_CHANNEL_DOWN)
|
|
249
|
-
|
|
250
|
-
async def press_enter(self) -> None:
|
|
251
|
-
"""Press enter on the settop box."""
|
|
252
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
253
|
-
await self.send_key_to_box(MEDIA_KEY_ENTER)
|
|
254
|
-
|
|
255
|
-
async def rewind(self) -> None:
|
|
256
|
-
"""Rewind the settop box."""
|
|
257
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
258
|
-
await self.send_key_to_box(MEDIA_KEY_REWIND)
|
|
259
|
-
|
|
260
|
-
async def fast_forward(self) -> None:
|
|
261
|
-
"""Fast forward the settop box."""
|
|
262
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
263
|
-
await self.send_key_to_box(MEDIA_KEY_FAST_FORWARD)
|
|
264
|
-
|
|
265
|
-
async def record(self):
|
|
266
|
-
"""Record on the settop box."""
|
|
267
|
-
if self._device_state.state == LGHorizonRunningState.ONLINE_RUNNING:
|
|
268
|
-
await self.send_key_to_box(MEDIA_KEY_RECORD)
|
|
269
|
-
|
|
270
|
-
async def set_channel(self, source: str) -> None:
|
|
271
|
-
"""Change te channel from the settopbox."""
|
|
272
|
-
channel = [src for src in self._channels.values() if src.title == source][0]
|
|
273
|
-
payload = (
|
|
274
|
-
'{"id":"'
|
|
275
|
-
+ await make_id(8)
|
|
276
|
-
+ '","type":"CPE.pushToTV","source":{"clientId":"'
|
|
277
|
-
+ self._mqtt_client.client_id
|
|
278
|
-
+ '","friendlyDeviceName":"Home Assistant"},'
|
|
279
|
-
+ '"status":{"sourceType":"linear","source":{"channelId":"'
|
|
280
|
-
+ channel.id
|
|
281
|
-
+ '"},"relativePosition":0,"speed":1}}'
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
await self._mqtt_client.publish_message(
|
|
285
|
-
f"{self._auth.household_id}/{self.device_id}", payload
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
async def play_recording(self, recording_id):
|
|
289
|
-
"""Play recording."""
|
|
290
|
-
payload = (
|
|
291
|
-
'{"id":"'
|
|
292
|
-
+ await make_id(8)
|
|
293
|
-
+ '","type":"CPE.pushToTV","source":{"clientId":"'
|
|
294
|
-
+ self._mqtt_client.client_id
|
|
295
|
-
+ '","friendlyDeviceName":"Home Assistant"},'
|
|
296
|
-
+ '"status":{"sourceType":"nDVR","source":{"recordingId":"'
|
|
297
|
-
+ recording_id
|
|
298
|
-
+ '"},"relativePosition":0}}'
|
|
299
|
-
)
|
|
300
|
-
await self._mqtt_client.publish_message(
|
|
301
|
-
f"{self._auth.household_id}/{self.device_id}", payload
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
async def send_key_to_box(self, key: str) -> None:
|
|
305
|
-
"""Send emulated (remote) key press to settopbox."""
|
|
306
|
-
payload_dict = {
|
|
307
|
-
"type": "CPE.KeyEvent",
|
|
308
|
-
"runtimeType": "key",
|
|
309
|
-
"id": "ha",
|
|
310
|
-
"source": self.device_id.lower(),
|
|
311
|
-
"status": {"w3cKey": key, "eventType": "keyDownUp"},
|
|
312
|
-
}
|
|
313
|
-
payload = json.dumps(payload_dict)
|
|
314
|
-
await self._mqtt_client.publish_message(
|
|
315
|
-
f"{self._auth.household_id}/{self.device_id}", payload
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
async def _request_settop_box_state(self) -> None:
|
|
319
|
-
"""Send mqtt message to receive state from settop box."""
|
|
320
|
-
topic = f"{self._auth.household_id}/{self.device_id}"
|
|
321
|
-
payload = {
|
|
322
|
-
"id": await make_id(8),
|
|
323
|
-
"type": "CPE.getUiStatus",
|
|
324
|
-
"source": self._mqtt_client.client_id,
|
|
325
|
-
}
|
|
326
|
-
await self._mqtt_client.publish_message(topic, json.dumps(payload))
|
|
327
|
-
|
|
328
|
-
async def _request_settop_box_recording_capacity(self) -> None:
|
|
329
|
-
"""Send mqtt message to receive state from settop box."""
|
|
330
|
-
topic = f"{self._auth.household_id}/{self.device_id}"
|
|
331
|
-
payload = {
|
|
332
|
-
"id": await make_id(8),
|
|
333
|
-
"type": "CPE.capacity",
|
|
334
|
-
"source": self._mqtt_client.client_id,
|
|
335
|
-
}
|
|
336
|
-
await self._mqtt_client.publish_message(topic, json.dumps(payload))
|