Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
Add more inputs (#11)
Browse files Browse the repository at this point in the history
* Add files via upload

Added Netflix/Amazon/YouTube support via --key (netflix/amazon/youtube)
Added more Buttons (ok/play/pause/fast_forward/etc.)
Added input selection via --key (source_1/source_2....)

* Added some additional features

Added Netflix/Amazon/YouTube support via --key (netflix/amazon/youtube)
Added more Buttons (ok/play/pause/fast_forward/etc.)
Added input selection via --key (source_1/source_2....)

* Add files via upload

* Format files with black.

* Update hisensetv/__main__.py

Co-authored-by: Alex <7845120+newAM@users.noreply.github.com>

* Update hisensetv/__init__.py

Co-authored-by: Alex <7845120+newAM@users.noreply.github.com>

* Update hisensetv/__init__.py

Co-authored-by: Alex <7845120+newAM@users.noreply.github.com>

* Better readability and extended set of keys

List of available keys:

power,
up,down,left,right,
menu,back,exit,ok,
volume_up,volume_down,
channel_up,channel_down,
fast_forward,rewind,
stop,play,pause,mute,
home,subtitle,
netflix,youtube,amazon,
0,1,2,3,4,5,6,7,8,9,
source_1,source_2,source_3,source_4,source_5,source_6,source_7",

* Add files via upload

* Formatting.

Co-authored-by: Alex M <alexmgit@protonmail.com>
Co-authored-by: Alex <7845120+newAM@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 25, 2021
1 parent 9507553 commit d355847
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 24 deletions.
213 changes: 191 additions & 22 deletions hisensetv/__init__.py
@@ -1,5 +1,3 @@
#!/usr/bin/env python3.8

from types import TracebackType
from typing import Any
from typing import Callable
Expand Down Expand Up @@ -60,7 +58,6 @@ def wrapper(self, *args, **kwargs):
class HisenseTv:
"""
Hisense TV.
Args:
hostname: TV hostname or IP.
port: Port of the MQTT broker on the TV, typically 36669.
Expand Down Expand Up @@ -157,7 +154,10 @@ def _on_connect(
self.connected = True

def _on_message(
self, client: mqtt.Client, userdata: Optional[Any], msg: mqtt.MQTTMessage,
self,
client: mqtt.Client,
userdata: Optional[Any],
msg: mqtt.MQTTMessage,
):
""" Callback upon MQTT broker message on a subcribed topic. """
if msg.payload:
Expand Down Expand Up @@ -191,11 +191,14 @@ def _wait_for_response(self) -> Optional[dict]:
) from e

def _call_service(
self, *, service: str, action: str, payload: Optional[Union[str, dict]] = None,
self,
*,
service: str,
action: str,
payload: Optional[Union[str, dict]] = None,
):
"""
Calls a service on the TV API.
Args:
service: "platform_service", remote_service", or "ui_service".
action: The action to send to the service.
Expand All @@ -211,7 +214,13 @@ def _call_service(
payload = json.dumps(payload)

full_topic = posixpath.join(
"/", "remoteapp", "tv", service, self._device_topic, "actions", action,
"/",
"remoteapp",
"tv",
service,
self._device_topic,
"actions",
action,
)

msg = self._mqtt_client.publish(topic=full_topic, payload=payload)
Expand All @@ -220,12 +229,51 @@ def _call_service(
def send_key(self, keyname: str):
"""
Sends a keypress to the TV, as if it had been pressed on the IR remote.
Args:
keyname: Name of the key press to send.
"""
self._call_service(service="remote_service", action="sendkey", payload=keyname)

def _launch_app(self, app: str):
"""
Sends a launch command to the TV, as if it had been pressed on the
"remoteNOW" app.
Args:
app: Name of the app to launch
"""
if app == "amazon":
launch = {"name": "Amazon", "urlType": 37, "storeType": 0, "url": "amazon"}

elif app == "netflix":
launch = {
"name": "Netflix",
"urlType": 37,
"storeType": 0,
"url": "netflix",
}

elif app == "youtube":
launch = {
"name": "YouTube",
"urlType": 37,
"storeType": 0,
"url": "youtube",
}

else:
raise ValueError(f"{app} is not a known app.")

self._call_service(service="ui_service", action="launchapp", payload=launch)

def _change_source(self, id: str):
"""
Sets the source of the TV.
id: id of the Source
"""
payload = {"sourceid": id}
self._call_service(service="ui_service", action="changesource", payload=payload)

@_check_connected
def send_key_power(self):
""" Sends a keypress of the powerkey to the TV. """
Expand Down Expand Up @@ -281,6 +329,16 @@ def send_key_volume_down(self):
""" Sends a keypress of the volume down key to the TV. """
self.send_key("KEY_VOLUMEDOWN")

@_check_connected
def send_key_fast_channel_up(self):
""" Sends a keypress of the channel up key to the TV. """
self.send_key("KEY_CHANNELUP")

@_check_connected
def send_key_fast_channel_down(self):
""" Sends a keypress of the channel down key to the TV. """
self.send_key("KEY_CHANNELDOWN")

@_check_connected
def send_key_fast_forward(self):
""" Sends a keypress of the fast forward key to the TV. """
Expand All @@ -289,7 +347,7 @@ def send_key_fast_forward(self):
@_check_connected
def send_key_rewind(self):
""" Sends a keypress of the rewind key to the TV. """
self.send_key("KEY_BACKS")
self.send_key("KEY_BACK")

@_check_connected
def send_key_stop(self):
Expand All @@ -303,19 +361,136 @@ def send_key_play(self):

@_check_connected
def send_key_pause(self):
""" Sends a keypress of the stop key to the TV. """
""" Sends a keypress of the pause key to the TV. """
self.send_key("KEY_PAUSE")

@_check_connected
def send_key_mute(self):
""" Sends a keypress of the mute key to the TV. """
self.send_key("KEY_MUTE")

@_check_connected
def send_key_home(self):
""" Sends a keypress of the home key to the TV. """
self.send_key("KEY_HOME")

@_check_connected
def send_key_subtitle(self):
""" Sends a keypress of the subtitle key to the TV. """
self.send_key("KEY_SUBTITLE")

@_check_connected
def send_key_netflix(self):
""" Sends a keypress of the Netflix key to the TV. """
self._launch_app("netflix")

@_check_connected
def send_key_youtube(self):
""" Sends a keypress of the YouTube key to the TV. """
self._launch_app("youtube")

@_check_connected
def send_key_amazon(self):
""" Sends a keypress of the Amazon key to the TV. """
self._launch_app("amazon")

@_check_connected
def send_key_0(self):
""" Sends a keypress of the 0 key to the TV. """
self.send_key("KEY_0")

@_check_connected
def send_key_1(self):
""" Sends a keypress of the 1 key to the TV. """
self.send_key("KEY_1")

@_check_connected
def send_key_2(self):
""" Sends a keypress of the 2 key to the TV. """
self.send_key("KEY_2")

@_check_connected
def send_key_3(self):
""" Sends a keypress of the 3 key to the TV. """
self.send_key("KEY_3")

@_check_connected
def send_key_4(self):
""" Sends a keypress of the 4 key to the TV. """
self.send_key("KEY_4")

@_check_connected
def send_key_5(self):
""" Sends a keypress of the 5 key to the TV. """
self.send_key("KEY_5")

@_check_connected
def send_key_6(self):
""" Sends a keypress of the 6 key to the TV. """
self.send_key("KEY_6")

@_check_connected
def send_key_7(self):
""" Sends a keypress of the 7 key to the TV. """
self.send_key("KEY_7")

@_check_connected
def send_key_8(self):
""" Sends a keypress of the 8 key to the TV. """
self.send_key("KEY_8")

@_check_connected
def send_key_9(self):
""" Sends a keypress of the 9 key to the TV. """
self.send_key("KEY_9")

@_check_connected
def send_key_source_0(self):
""" Sets TV to Input 0 """
self._change_source("0")

@_check_connected
def send_key_source_1(self):
""" Sets TV to Input 1 """
self._change_source("1")

@_check_connected
def send_key_source_2(self):
""" Sets TV to Input 2 """
self._change_source("2")

@_check_connected
def send_key_source_3(self):
""" Sets TV to Input 3 """
self._change_source("3")

@_check_connected
def send_key_source_4(self):
""" Sets TV to Input 4 """
self._change_source("4")

@_check_connected
def send_key_source_5(self):
""" Sets TV to Input 5 """
self._change_source("5")

@_check_connected
def send_key_source_6(self):
""" Sets TV to Input 6 """
self._change_source("6")

@_check_connected
def send_key_source_7(self):
""" Sets TV to Input 7 """
self._change_source("7")

@_check_connected
def get_sources(self) -> List[Dict[str, str]]:
"""
Gets the video sources from the TV.
Returns:
List of source dictionaries.
Example::
[
{
"displayname": "TV",
Expand Down Expand Up @@ -374,7 +549,6 @@ def get_sources(self) -> List[Dict[str, str]]:
def set_source(self, sourceid: Union[int, str], sourcename: str):
"""
Sets the video source on the TV.
Args:
sourceid: Numeric source identier.
sourcename: Human readable source name.
Expand All @@ -390,12 +564,9 @@ def set_source(self, sourceid: Union[int, str], sourcename: str):
def get_volume(self) -> dict:
"""
Gets the volume level on the TV.
Returns:
Dictionary with keys for volume_type and volume_value.
Example::
{"volume_type": 0, "volume_value": 0}
"""
self._call_service(service="platform_service", action="getvolume")
Expand All @@ -405,10 +576,8 @@ def get_volume(self) -> dict:
def set_volume(self, volume: int):
"""
Sets the volume level on the TV.
Args:
volume: Volume level from 0-100.
Raises:
ValueError: Volume level is out of range.
"""
Expand All @@ -418,7 +587,9 @@ def set_volume(self, volume: int):
f"volume of {volume!r} is invalid, volume must be between 0 and 100"
)
self._call_service(
service="platform_service", action="changevolume", payload=str(volume),
service="platform_service",
action="changevolume",
payload=str(volume),
)

@_check_connected
Expand All @@ -431,10 +602,8 @@ def start_authorization(self):
def send_authorization_code(self, code: Union[int, str]):
"""
Sends the authorization code to the TV.
Args:
code: 4-digit code as displayed on the TV.
Raises:
HisenseTvAuthorizationError: Failed to authenticate with the TV.
"""
Expand Down

0 comments on commit d355847

Please sign in to comment.