forked from home-assistant/core
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vizio SmartCast support (home-assistant#8260)
* Vizio SmartCast support * Requested changes Added new config params * Vizio SmartCast support * Requested changes Added new config params
- Loading branch information
1 parent
cbeda83
commit 8bc7906
Showing
3 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
""" | ||
Vizio SmartCast TV support. | ||
Usually only 2016+ models come with SmartCast capabilities. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/media_player.vizio/ | ||
""" | ||
import logging | ||
from datetime import timedelta | ||
|
||
import voluptuous as vol | ||
|
||
import homeassistant.util as util | ||
from homeassistant.components.media_player import ( | ||
PLATFORM_SCHEMA, | ||
SUPPORT_TURN_ON, | ||
SUPPORT_TURN_OFF, | ||
SUPPORT_SELECT_SOURCE, | ||
SUPPORT_PREVIOUS_TRACK, | ||
SUPPORT_NEXT_TRACK, | ||
SUPPORT_VOLUME_MUTE, | ||
SUPPORT_VOLUME_STEP, | ||
MediaPlayerDevice | ||
) | ||
from homeassistant.const import ( | ||
STATE_UNKNOWN, | ||
STATE_OFF, | ||
STATE_ON, | ||
CONF_NAME, | ||
CONF_HOST, | ||
CONF_ACCESS_TOKEN | ||
) | ||
from homeassistant.helpers import config_validation as cv | ||
|
||
REQUIREMENTS = ['pyvizio==0.0.2'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
CONF_SUPPRESS_WARNING = 'suppress_warning' | ||
CONF_VOLUME_STEP = 'volume_step' | ||
|
||
ICON = 'mdi:television' | ||
DEFAULT_NAME = 'Vizio SmartCast' | ||
DEFAULT_VOLUME_STEP = 1 | ||
DEVICE_NAME = 'Python Vizio' | ||
DEVICE_ID = 'pyvizio' | ||
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) | ||
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1) | ||
SUPPORTED_COMMANDS = SUPPORT_TURN_ON | SUPPORT_TURN_OFF \ | ||
| SUPPORT_SELECT_SOURCE \ | ||
| SUPPORT_NEXT_TRACK | SUPPORT_PREVIOUS_TRACK \ | ||
| SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP | ||
|
||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
vol.Required(CONF_HOST): cv.string, | ||
vol.Required(CONF_ACCESS_TOKEN): cv.string, | ||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, | ||
vol.Optional(CONF_SUPPRESS_WARNING, default=False): cv.boolean, | ||
vol.Optional(CONF_VOLUME_STEP, default=DEFAULT_VOLUME_STEP): | ||
vol.All(vol.Coerce(int), vol.Range(min=1, max=10)), | ||
}) | ||
|
||
|
||
def setup_platform(hass, config, add_devices, discovery_info=None): | ||
"""Set up the VizioTV media player platform.""" | ||
host = config.get(CONF_HOST) | ||
token = config.get(CONF_ACCESS_TOKEN) | ||
name = config.get(CONF_NAME) | ||
volume_step = config.get(CONF_VOLUME_STEP) | ||
|
||
device = VizioDevice(host, token, name, volume_step) | ||
if device.validate_setup() is False: | ||
_LOGGER.error('Failed to setup Vizio TV platform, ' | ||
'please check if host and API key are correct.') | ||
return False | ||
|
||
if config.get(CONF_SUPPRESS_WARNING): | ||
import requests | ||
from requests.packages.urllib3.exceptions import InsecureRequestWarning | ||
_LOGGER.warning('InsecureRequestWarning is disabled ' | ||
'because of Vizio platform configuration.') | ||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning) | ||
add_devices([device], True) | ||
|
||
|
||
class VizioDevice(MediaPlayerDevice): | ||
"""Media Player implementation which performs REST requests to TV.""" | ||
|
||
def __init__(self, host, token, name, volume_step): | ||
"""Initialize Vizio device.""" | ||
import pyvizio | ||
self._device = pyvizio.Vizio(DEVICE_ID, host, DEFAULT_NAME, token) | ||
self._name = name | ||
self._state = STATE_UNKNOWN | ||
self._volume_level = None | ||
self._volume_step = volume_step | ||
self._current_input = None | ||
self._available_inputs = None | ||
|
||
@util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) | ||
def update(self): | ||
"""Retrieve latest state of the TV.""" | ||
is_on = self._device.get_power_state() | ||
if is_on is None: | ||
self._state = STATE_UNKNOWN | ||
return | ||
elif is_on is False: | ||
self._state = STATE_OFF | ||
else: | ||
self._state = STATE_ON | ||
|
||
self._volume_level = self._device.get_current_volume() | ||
input_ = self._device.get_current_input() | ||
if input_ is not None: | ||
self._current_input = input_.meta_name | ||
inputs = self._device.get_inputs() | ||
if inputs is not None: | ||
self._available_inputs = [] | ||
for input_ in inputs: | ||
self._available_inputs.append(input_.name) | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the TV.""" | ||
return self._state | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the TV.""" | ||
return self._name | ||
|
||
@property | ||
def volume_level(self): | ||
"""Return the volume level of the TV.""" | ||
return self._volume_level | ||
|
||
@property | ||
def source(self): | ||
"""Return current input of the TV.""" | ||
return self._current_input | ||
|
||
@property | ||
def source_list(self): | ||
"""Return list of available inputs of the TV.""" | ||
return self._available_inputs | ||
|
||
@property | ||
def supported_features(self): | ||
"""Flag TV features that are supported.""" | ||
return SUPPORTED_COMMANDS | ||
|
||
def turn_on(self): | ||
"""Turn the TV player on.""" | ||
self._device.pow_on() | ||
|
||
def turn_off(self): | ||
"""Turn the TV player off.""" | ||
self._device.pow_off() | ||
|
||
def mute_volume(self, mute): | ||
"""Mute the volume.""" | ||
if mute: | ||
self._device.mute_on() | ||
else: | ||
self._device.mute_off() | ||
|
||
def media_previous_track(self): | ||
"""Send previous channel command.""" | ||
self._device.ch_down() | ||
|
||
def media_next_track(self): | ||
"""Send next channel command.""" | ||
self._device.ch_up() | ||
|
||
def select_source(self, source): | ||
"""Select input source.""" | ||
self._device.input_switch(source) | ||
|
||
def volume_up(self): | ||
"""Increasing volume of the TV.""" | ||
self._device.vol_up(num=self._volume_step) | ||
|
||
def volume_down(self): | ||
"""Decreasing volume of the TV.""" | ||
self._device.vol_down(num=self._volume_step) | ||
|
||
def validate_setup(self): | ||
"""Validating if host is available and key is correct.""" | ||
return self._device.get_current_volume() is not None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters