diff --git a/.coveragerc b/.coveragerc index 4b19519038f09b..ec41cf05b7c492 100644 --- a/.coveragerc +++ b/.coveragerc @@ -462,6 +462,7 @@ omit = homeassistant/components/media_player/vizio.py homeassistant/components/media_player/vlc.py homeassistant/components/media_player/volumio.py + homeassistant/components/media_player/xiaomi_tv.py homeassistant/components/media_player/yamaha.py homeassistant/components/media_player/yamaha_musiccast.py homeassistant/components/media_player/ziggo_mediabox_xl.py diff --git a/CODEOWNERS b/CODEOWNERS index 6e088a84e5d85d..b442fa90b2cffe 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -55,6 +55,7 @@ homeassistant/components/light/tplink.py @rytilahti homeassistant/components/light/yeelight.py @rytilahti homeassistant/components/media_player/kodi.py @armills homeassistant/components/media_player/monoprice.py @etsinko +homeassistant/components/media_player/xiaomi_tv.py @fattdev homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth homeassistant/components/plant.py @ChristianKuehnel homeassistant/components/sensor/airvisual.py @bachya diff --git a/homeassistant/components/media_player/xiaomi_tv.py b/homeassistant/components/media_player/xiaomi_tv.py new file mode 100644 index 00000000000000..be40bf7d010752 --- /dev/null +++ b/homeassistant/components/media_player/xiaomi_tv.py @@ -0,0 +1,112 @@ +""" +Add support for the Xiaomi TVs. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/xiaomi_tv/ +""" + +import logging +import voluptuous as vol +import homeassistant.helpers.config_validation as cv +from homeassistant.const import (CONF_HOST, CONF_NAME, STATE_OFF, STATE_ON) +from homeassistant.components.media_player import ( + SUPPORT_TURN_ON, SUPPORT_TURN_OFF, MediaPlayerDevice, PLATFORM_SCHEMA, + SUPPORT_VOLUME_STEP) + +REQUIREMENTS = ['pymitv==1.0.0'] + +DEFAULT_NAME = "Xiaomi TV" + +_LOGGER = logging.getLogger(__name__) + +SUPPORT_XIAOMI_TV = SUPPORT_VOLUME_STEP | SUPPORT_TURN_ON | \ + SUPPORT_TURN_OFF + +# No host is needed for configuration, however it can be set. +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_HOST): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Xiaomi TV platform.""" + from pymitv import Discover + + # If a hostname is set. Discovery is skipped. + host = config.get(CONF_HOST) + name = config.get(CONF_NAME) + + if host is not None: + # Check if there's a valid TV at the IP address. + if not Discover().checkIp(host): + _LOGGER.error( + "Could not find Xiaomi TV with specified IP: %s", host + ) + else: + # Register TV with Home Assistant. + add_devices([XiaomiTV(host, name)]) + else: + # Otherwise, discover TVs on network. + add_devices(XiaomiTV(tv, DEFAULT_NAME) for tv in Discover().scan()) + + +class XiaomiTV(MediaPlayerDevice): + """Represent the Xiaomi TV for Home Assistant.""" + + def __init__(self, ip, name): + """Receive IP address and name to construct class.""" + # Import pymitv library. + from pymitv import TV + + # Initialize the Xiaomi TV. + self._tv = TV(ip) + # Default name value, only to be overridden by user. + self._name = name + self._state = STATE_OFF + + @property + def name(self): + """Return the display name of this TV.""" + return self._name + + @property + def state(self): + """Return _state variable, containing the appropriate constant.""" + return self._state + + @property + def assumed_state(self): + """Indicate that state is assumed.""" + return True + + @property + def supported_features(self): + """Flag media player features that are supported.""" + return SUPPORT_XIAOMI_TV + + def turn_off(self): + """ + Instruct the TV to turn sleep. + + This is done instead of turning off, + because the TV won't accept any input when turned off. Thus, the user + would be unable to turn the TV back on, unless it's done manually. + """ + self._tv.sleep() + + self._state = STATE_OFF + + def turn_on(self): + """Wake the TV back up from sleep.""" + self._tv.wake() + + self._state = STATE_ON + + def volume_up(self): + """Increase volume by one.""" + self._tv.volume_up() + + def volume_down(self): + """Decrease volume by one.""" + self._tv.volume_down() diff --git a/requirements_all.txt b/requirements_all.txt index 82c98817affcba..b42b48aef20943 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -787,6 +787,9 @@ pymailgunner==1.4 # homeassistant.components.media_player.mediaroom pymediaroom==0.5 +# homeassistant.components.media_player.xiaomi_tv +pymitv==1.0.0 + # homeassistant.components.mochad pymochad==0.2.0