diff --git a/.coveragerc b/.coveragerc index dd486626c54..cb5299beaad 100644 --- a/.coveragerc +++ b/.coveragerc @@ -777,7 +777,7 @@ omit = homeassistant/components/viaggiatreno/sensor.py homeassistant/components/vicare/* homeassistant/components/vivotek/camera.py - homeassistant/components/vizio/media_player.py + homeassistant/components/vizio/* homeassistant/components/vlc/media_player.py homeassistant/components/vlc_telnet/media_player.py homeassistant/components/volkszaehler/sensor.py diff --git a/homeassistant/components/vizio/__init__.py b/homeassistant/components/vizio/__init__.py index 3575f2cf648..00d34fc6591 100644 --- a/homeassistant/components/vizio/__init__.py +++ b/homeassistant/components/vizio/__init__.py @@ -1 +1,43 @@ """The vizio component.""" +import voluptuous as vol + +from homeassistant.const import ( + CONF_ACCESS_TOKEN, + CONF_DEVICE_CLASS, + CONF_HOST, + CONF_NAME, +) +from homeassistant.helpers import config_validation as cv + +from .const import ( + CONF_SUPPRESS_WARNING, + CONF_VOLUME_STEP, + DEFAULT_DEVICE_CLASS, + DEFAULT_NAME, + DEFAULT_VOLUME_STEP, +) + + +def validate_auth(config): + """Validate presence of CONF_ACCESS_TOKEN when CONF_DEVICE_CLASS=tv.""" + token = config.get(CONF_ACCESS_TOKEN) + if config[CONF_DEVICE_CLASS] == "tv" and not token: + raise vol.Invalid( + f"When '{CONF_DEVICE_CLASS}' is 'tv' then '{CONF_ACCESS_TOKEN}' is required.", + path=[CONF_ACCESS_TOKEN], + ) + return config + + +VIZIO_SCHEMA = { + vol.Required(CONF_HOST): cv.string, + vol.Optional(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_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): vol.All( + cv.string, vol.Lower, vol.In(["tv", "soundbar"]) + ), + vol.Optional(CONF_VOLUME_STEP, default=DEFAULT_VOLUME_STEP): vol.All( + vol.Coerce(int), vol.Range(min=1, max=10) + ), +} diff --git a/homeassistant/components/vizio/const.py b/homeassistant/components/vizio/const.py new file mode 100644 index 00000000000..f668fb0795f --- /dev/null +++ b/homeassistant/components/vizio/const.py @@ -0,0 +1,14 @@ +"""Constants used by vizio component.""" + +CONF_SUPPRESS_WARNING = "suppress_warning" +CONF_VOLUME_STEP = "volume_step" + +DEFAULT_NAME = "Vizio SmartCast" +DEFAULT_VOLUME_STEP = 1 +DEFAULT_DEVICE_CLASS = "tv" +DEVICE_ID = "pyvizio" +DEVICE_NAME = "Python Vizio" + +DOMAIN = "vizio" + +ICON = {"tv": "mdi:television", "soundbar": "mdi:speaker"} diff --git a/homeassistant/components/vizio/manifest.json b/homeassistant/components/vizio/manifest.json index 125f2374c7c..25070462a82 100644 --- a/homeassistant/components/vizio/manifest.json +++ b/homeassistant/components/vizio/manifest.json @@ -2,7 +2,9 @@ "domain": "vizio", "name": "Vizio", "documentation": "https://www.home-assistant.io/integrations/vizio", - "requirements": ["pyvizio==0.0.9"], + "requirements": [ + "pyvizio==0.0.11" + ], "dependencies": [], "codeowners": ["@raman325"] } diff --git a/homeassistant/components/vizio/media_player.py b/homeassistant/components/vizio/media_player.py index ac920a05330..35b54284c93 100644 --- a/homeassistant/components/vizio/media_player.py +++ b/homeassistant/components/vizio/media_player.py @@ -26,21 +26,18 @@ from homeassistant.const import ( STATE_OFF, STATE_ON, ) -from homeassistant.helpers import config_validation as cv + +from . import VIZIO_SCHEMA, validate_auth +from .const import ( + CONF_SUPPRESS_WARNING, + CONF_VOLUME_STEP, + DEFAULT_NAME, + DEVICE_ID, + ICON, +) _LOGGER = logging.getLogger(__name__) -CONF_SUPPRESS_WARNING = "suppress_warning" -CONF_VOLUME_STEP = "volume_step" - -DEFAULT_NAME = "Vizio SmartCast" -DEFAULT_VOLUME_STEP = 1 -DEFAULT_DEVICE_CLASS = "tv" -DEVICE_ID = "pyvizio" -DEVICE_NAME = "Python Vizio" - -ICON = "mdi:television" - MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) @@ -59,34 +56,7 @@ SUPPORTED_COMMANDS = { } -def validate_auth(config): - """Validate presence of CONF_ACCESS_TOKEN when CONF_DEVICE_CLASS=tv.""" - token = config.get(CONF_ACCESS_TOKEN) - if config[CONF_DEVICE_CLASS] == "tv" and (token is None or token == ""): - raise vol.Invalid( - f"When '{CONF_DEVICE_CLASS}' is 'tv' then '{CONF_ACCESS_TOKEN}' is required.", - path=[CONF_ACCESS_TOKEN], - ) - return config - - -PLATFORM_SCHEMA = vol.All( - PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_HOST): cv.string, - vol.Optional(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_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): vol.All( - cv.string, vol.Lower, vol.In(["tv", "soundbar"]) - ), - vol.Optional(CONF_VOLUME_STEP, default=DEFAULT_VOLUME_STEP): vol.All( - vol.Coerce(int), vol.Range(min=1, max=10) - ), - } - ), - validate_auth, -) +PLATFORM_SCHEMA = vol.All(PLATFORM_SCHEMA.extend(VIZIO_SCHEMA), validate_auth) def setup_platform(hass, config, add_entities, discovery_info=None): @@ -97,9 +67,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None): volume_step = config[CONF_VOLUME_STEP] device_type = config[CONF_DEVICE_CLASS] device = VizioDevice(host, token, name, volume_step, device_type) - if device.validate_setup() is False: + if not device.validate_setup(): fail_auth_msg = "" - if token is not None and token != "": + if token: fail_auth_msg = " and auth token is correct" _LOGGER.error( "Failed to set up Vizio platform, please check if host " @@ -133,13 +103,17 @@ class VizioDevice(MediaPlayerDevice): self._supported_commands = SUPPORTED_COMMANDS[device_type] self._device = Vizio(DEVICE_ID, host, DEFAULT_NAME, token, device_type) self._max_volume = float(self._device.get_max_volume()) - self._unique_id = self._device.get_esn() + self._unique_id = None + self._icon = ICON[device_type] @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) def update(self): """Retrieve latest state of the device.""" is_on = self._device.get_power_state() + if not self._unique_id: + self._unique_id = self._device.get_esn() + if is_on: self._state = STATE_ON @@ -175,6 +149,11 @@ class VizioDevice(MediaPlayerDevice): """Return the name of the device.""" return self._name + @property + def icon(self): + """Return the icon of the device.""" + return self._icon + @property def volume_level(self): """Return the volume level of the device.""" @@ -245,7 +224,7 @@ class VizioDevice(MediaPlayerDevice): def validate_setup(self): """Validate if host is available and auth token is correct.""" - return self._device.get_current_volume() is not None + return self._device.can_connect() def set_volume_level(self, volume): """Set volume level.""" diff --git a/requirements_all.txt b/requirements_all.txt index a6d9fcb04be..372cd4e9d15 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1696,7 +1696,7 @@ pyversasense==0.0.6 pyvesync==1.1.0 # homeassistant.components.vizio -pyvizio==0.0.9 +pyvizio==0.0.11 # homeassistant.components.velux pyvlx==0.2.12