Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions homeassistant/components/vizio/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
),
}

VIZIO_SOUND_MODE = "eq"
VIZIO_AUDIO_SETTINGS = "audio"

# Since Vizio component relies on device class, this dict will ensure that changes to
# the values of DEVICE_CLASS_SPEAKER or DEVICE_CLASS_TV don't require changes to pyvizio.
VIZIO_DEVICE_CLASSES = {
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/vizio/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "vizio",
"name": "Vizio SmartCast",
"documentation": "https://www.home-assistant.io/integrations/vizio",
"requirements": ["pyvizio==0.1.44"],
"requirements": ["pyvizio==0.1.45"],
"dependencies": [],
"codeowners": ["@raman325"],
"config_flow": true,
Expand Down
42 changes: 38 additions & 4 deletions homeassistant/components/vizio/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from homeassistant.components.media_player import (
DEVICE_CLASS_SPEAKER,
SUPPORT_SELECT_SOUND_MODE,
MediaPlayerDevice,
)
from homeassistant.config_entries import ConfigEntry
Expand Down Expand Up @@ -41,7 +42,9 @@
DOMAIN,
ICON,
SUPPORTED_COMMANDS,
VIZIO_AUDIO_SETTINGS,
VIZIO_DEVICE_CLASSES,
VIZIO_SOUND_MODE,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -133,6 +136,8 @@ def __init__(
self._current_input = None
self._current_app = None
self._current_app_config = None
self._current_sound_mode = None
self._available_sound_modes = None
self._available_inputs = []
self._available_apps = []
self._conf_apps = config_entry.options.get(CONF_APPS, {})
Expand Down Expand Up @@ -191,17 +196,29 @@ async def async_update(self) -> None:
self._current_app = None
self._current_app_config = None
self._available_apps = None
self._current_sound_mode = None
self._available_sound_modes = None
return

self._state = STATE_ON

audio_settings = await self._device.get_all_audio_settings(
log_api_exception=False
audio_settings = await self._device.get_all_settings(
VIZIO_AUDIO_SETTINGS, log_api_exception=False
)
if audio_settings is not None:
self._volume_level = float(audio_settings["volume"]) / self._max_volume
self._is_muted = audio_settings["mute"].lower() == "on"

if VIZIO_SOUND_MODE in audio_settings:
self._supported_commands |= SUPPORT_SELECT_SOUND_MODE
self._current_sound_mode = audio_settings[VIZIO_SOUND_MODE]
if self._available_sound_modes is None:
self._available_sound_modes = await self._device.get_setting_options(
VIZIO_AUDIO_SETTINGS, VIZIO_SOUND_MODE
)
else:
self._supported_commands ^= SUPPORT_SELECT_SOUND_MODE

input_ = await self._device.get_current_input(log_api_exception=False)
if input_ is not None:
self._current_input = input_
Expand Down Expand Up @@ -367,7 +384,7 @@ def unique_id(self) -> str:
return self._config_entry.unique_id

@property
def device_info(self):
def device_info(self) -> Dict[str, Any]:
"""Return device registry information."""
return {
"identifiers": {(DOMAIN, self._config_entry.unique_id)},
Expand All @@ -378,10 +395,27 @@ def device_info(self):
}

@property
def device_class(self):
def device_class(self) -> str:
"""Return device class for entity."""
return self._device_class

@property
def sound_mode(self) -> Optional[str]:
"""Name of the current sound mode."""
return self._current_sound_mode

@property
def sound_mode_list(self) -> Optional[List[str]]:
"""List of available sound modes."""
return self._available_sound_modes

async def async_select_sound_mode(self, sound_mode):
"""Select sound mode."""
if sound_mode in self._available_sound_modes:
await self._device.set_setting(
VIZIO_AUDIO_SETTINGS, VIZIO_SOUND_MODE, sound_mode
)

async def async_turn_on(self) -> None:
"""Turn the device on."""
await self._device.pow_on()
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1732,7 +1732,7 @@ pyversasense==0.0.6
pyvesync==1.1.0

# homeassistant.components.vizio
pyvizio==0.1.44
pyvizio==0.1.45

# homeassistant.components.velux
pyvlx==0.2.12
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ pyvera==0.3.7
pyvesync==1.1.0

# homeassistant.components.vizio
pyvizio==0.1.44
pyvizio==0.1.45

# homeassistant.components.html5
pywebpush==1.9.2
Expand Down
8 changes: 7 additions & 1 deletion tests/components/vizio/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
APP_LIST,
CH_TYPE,
CURRENT_APP_CONFIG,
CURRENT_EQ,
CURRENT_INPUT,
EQ_LIST,
INPUT_LIST,
INPUT_LIST_WITH_APPS,
MODEL,
Expand Down Expand Up @@ -135,11 +137,15 @@ def vizio_update_fixture():
"homeassistant.components.vizio.media_player.VizioAsync.can_connect_with_auth_check",
return_value=True,
), patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_all_audio_settings",
"homeassistant.components.vizio.media_player.VizioAsync.get_all_settings",
return_value={
"volume": int(MAX_VOLUME[DEVICE_CLASS_SPEAKER] / 2),
"eq": CURRENT_EQ,
"mute": "Off",
},
), patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_setting_options",
return_value=EQ_LIST,
), patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_current_input",
return_value=CURRENT_INPUT,
Expand Down
3 changes: 3 additions & 0 deletions tests/components/vizio/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ def __init__(self, auth_token: str) -> None:
self.auth_token = auth_token


CURRENT_EQ = "Music"
EQ_LIST = ["Music", "Movie"]

CURRENT_INPUT = "HDMI"
INPUT_LIST = ["HDMI", "USB", "Bluetooth", "AUX"]

Expand Down
28 changes: 25 additions & 3 deletions tests/components/vizio/test_media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
ATTR_INPUT_SOURCE,
ATTR_MEDIA_VOLUME_LEVEL,
ATTR_MEDIA_VOLUME_MUTED,
ATTR_SOUND_MODE,
DEVICE_CLASS_SPEAKER,
DEVICE_CLASS_TV,
DOMAIN as MP_DOMAIN,
SERVICE_MEDIA_NEXT_TRACK,
SERVICE_MEDIA_PREVIOUS_TRACK,
SERVICE_SELECT_SOUND_MODE,
SERVICE_SELECT_SOURCE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
Expand Down Expand Up @@ -58,9 +60,11 @@
APP_LIST,
CURRENT_APP,
CURRENT_APP_CONFIG,
CURRENT_EQ,
CURRENT_INPUT,
CUSTOM_CONFIG,
ENTITY_ID,
EQ_LIST,
INPUT_LIST,
INPUT_LIST_WITH_APPS,
MOCK_SPEAKER_APPS_FAILURE,
Expand Down Expand Up @@ -99,17 +103,29 @@ async def _test_setup(
data=vol.Schema(VIZIO_SCHEMA)(MOCK_SPEAKER_CONFIG),
unique_id=UNIQUE_ID,
)
dict_to_return = {
"volume": int(MAX_VOLUME[vizio_device_class] / 2),
"mute": "Off",
"eq": CURRENT_EQ,
}
else:
vizio_device_class = VIZIO_DEVICE_CLASS_TV
config_entry = MockConfigEntry(
domain=DOMAIN,
data=vol.Schema(VIZIO_SCHEMA)(MOCK_USER_VALID_TV_CONFIG),
unique_id=UNIQUE_ID,
)
dict_to_return = {
"volume": int(MAX_VOLUME[vizio_device_class] / 2),
"mute": "Off",
}

with patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_all_audio_settings",
return_value={"volume": int(MAX_VOLUME[vizio_device_class] / 2), "mute": "Off"},
"homeassistant.components.vizio.media_player.VizioAsync.get_all_settings",
return_value=dict_to_return,
), patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_setting_options",
return_value=EQ_LIST,
), patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_power_state",
return_value=vizio_power_state,
Expand All @@ -130,6 +146,9 @@ async def _test_setup(
assert attr["source"] == CURRENT_INPUT
if ha_device_class == DEVICE_CLASS_SPEAKER:
assert not service_call.called
assert "sound_mode" in attr
else:
assert "sound_mode" not in attr
assert (
attr["volume_level"]
== float(int(MAX_VOLUME[vizio_device_class] / 2))
Expand All @@ -149,7 +168,7 @@ async def _test_setup_with_apps(
)

with patch(
"homeassistant.components.vizio.media_player.VizioAsync.get_all_audio_settings",
"homeassistant.components.vizio.media_player.VizioAsync.get_all_settings",
return_value={
"volume": int(MAX_VOLUME[VIZIO_DEVICE_CLASS_TV] / 2),
"mute": "Off",
Expand Down Expand Up @@ -351,6 +370,9 @@ async def test_services(
)
await _test_service(hass, "ch_up", SERVICE_MEDIA_NEXT_TRACK, None)
await _test_service(hass, "ch_down", SERVICE_MEDIA_PREVIOUS_TRACK, None)
await _test_service(
hass, "set_setting", SERVICE_SELECT_SOUND_MODE, {ATTR_SOUND_MODE: "Music"}
)


async def test_options_update(
Expand Down