Skip to content

Query Samsung TV status via REST end point #11179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions homeassistant/components/media_player/samsungtv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import socket
from datetime import timedelta

import requests
import voluptuous as vol

from homeassistant.components.media_player import (
Expand All @@ -16,16 +17,14 @@
SUPPORT_PLAY, MediaPlayerDevice, PLATFORM_SCHEMA, SUPPORT_TURN_ON)
from homeassistant.const import (
CONF_HOST, CONF_NAME, STATE_OFF, STATE_ON, STATE_UNKNOWN, CONF_PORT,
CONF_MAC)
CONF_MAC, CONF_TIMEOUT)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import dt as dt_util

REQUIREMENTS = ['samsungctl==0.6.0', 'wakeonlan==0.2.2']

_LOGGER = logging.getLogger(__name__)

CONF_TIMEOUT = 'timeout'

DEFAULT_NAME = 'Samsung TV Remote'
DEFAULT_PORT = 55000
DEFAULT_TIMEOUT = 0
Expand All @@ -36,11 +35,14 @@
SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | \
SUPPORT_NEXT_TRACK | SUPPORT_TURN_OFF | SUPPORT_PLAY

CONF_STATUS_VIA_REST = 'get_status_via_rest'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_STATUS_VIA_REST, default=False): cv.boolean
})


Expand All @@ -59,6 +61,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
name = config.get(CONF_NAME)
mac = config.get(CONF_MAC)
timeout = config.get(CONF_TIMEOUT)
status_via_rest = config.get(CONF_STATUS_VIA_REST)
elif discovery_info is not None:
tv_name = discovery_info.get('name')
model = discovery_info.get('model_name')
Expand All @@ -67,6 +70,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
port = DEFAULT_PORT
timeout = DEFAULT_TIMEOUT
mac = None
status_via_rest = False
else:
_LOGGER.warning("Cannot determine device")
return
Expand All @@ -76,7 +80,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
ip_addr = socket.gethostbyname(host)
if ip_addr not in known_devices:
known_devices.add(ip_addr)
add_devices([SamsungTVDevice(host, port, name, timeout, mac)])
add_devices([
SamsungTVDevice(host, port, name, timeout, mac, status_via_rest)
])
_LOGGER.info("Samsung TV %s:%d added as '%s'", host, port, name)
else:
_LOGGER.info("Ignoring duplicate Samsung TV %s:%d", host, port)
Expand All @@ -85,7 +91,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class SamsungTVDevice(MediaPlayerDevice):
"""Representation of a Samsung TV."""

def __init__(self, host, port, name, timeout, mac):
def __init__(self, host, port, name, timeout, mac, status_via_rest):
"""Initialize the Samsung device."""
from samsungctl import exceptions
from samsungctl import Remote
Expand All @@ -96,6 +102,7 @@ def __init__(self, host, port, name, timeout, mac):
self._name = name
self._mac = mac
self._wol = wol
self._status_via_rest = status_via_rest
# Assume that the TV is not muted
self._muted = False
# Assume that the TV is in Play mode
Expand All @@ -122,8 +129,28 @@ def __init__(self, host, port, name, timeout, mac):

def update(self):
"""Retrieve the latest data."""
# Send an empty key to see if we are still connected
self.send_key('KEY')
if self._config['method'] == 'websocket' and self._status_via_rest:
# Check if the TV Rest Server is active
self._update_status_via_rest()
else:
# Send an empty key to see if we are still connected
self.send_key('KEY')

def _update_status_via_rest(self):
url = "http://{}:{}/api/v2/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic needs to be added to the upstream samsungctl library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid that would be out of scope for this library, since the library just focus on control via websocket, and does not interact with the REST endpoint for now.

If it's required I'll try, but not sure my code make it to samsungctl library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request opened in SamsungCTL library
Ape/samsungctl#71

url = url.format(self._config['host'], self._config['port'])
try:
res = requests.get(url, timeout=5)
except (requests.exceptions.Timeout,
requests.exceptions.ConnectionError,
requests.exceptions.HTTPError,
requests.exceptions.ReadTimeout):
self._state = STATE_OFF
return
if res is not None and res.status_code == 200:
self._state = STATE_ON
else:
self._state = STATE_OFF

def get_remote(self):
"""Create or return a remote control instance."""
Expand Down