Update pyheos to 0.6.0 (#26191)

This commit is contained in:
Andrew Sayre 2019-08-25 13:57:43 -05:00 committed by Paulus Schoutsen
parent afab0a9568
commit 677995a05a
11 changed files with 66 additions and 92 deletions

View file

@ -4,7 +4,7 @@ from datetime import timedelta
import logging
from typing import Dict
from pyheos import CommandError, Heos, const as heos_const
from pyheos import Heos, HeosError, const as heos_const
import voluptuous as vol
from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN
@ -68,7 +68,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
try:
await controller.connect(auto_reconnect=True)
# Auto reconnect only operates if initial connection was successful.
except (asyncio.TimeoutError, ConnectionError, CommandError) as error:
except HeosError as error:
await controller.disconnect()
_LOGGER.debug("Unable to connect to controller %s: %s", host, error)
raise ConfigEntryNotReady
@ -93,13 +93,9 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
host,
)
inputs = await controller.get_input_sources()
except (asyncio.TimeoutError, ConnectionError, CommandError) as error:
except HeosError as error:
await controller.disconnect()
_LOGGER.debug(
"Unable to retrieve players and sources: %s",
error,
exc_info=isinstance(error, CommandError),
)
_LOGGER.debug("Unable to retrieve players and sources: %s", error)
raise ConfigEntryNotReady
controller_manager = ControllerManager(hass, controller)
@ -187,7 +183,7 @@ class ControllerManager:
# Retrieve latest players and refresh status
data = await self.controller.load_players()
self.update_ids(data[heos_const.DATA_MAPPED_IDS])
except (CommandError, asyncio.TimeoutError, ConnectionError) as ex:
except HeosError as ex:
_LOGGER.error("Unable to refresh players: %s", ex)
# Update players
self._hass.helpers.dispatcher.async_dispatcher_send(SIGNAL_HEOS_UPDATED)
@ -312,21 +308,15 @@ class SourceManager:
favorites = await controller.get_favorites()
inputs = await controller.get_input_sources()
return favorites, inputs
except (asyncio.TimeoutError, ConnectionError, CommandError) as error:
except HeosError as error:
if retry_attempts < self.max_retry_attempts:
retry_attempts += 1
_LOGGER.debug(
"Error retrieving sources and will " "retry: %s",
error,
exc_info=isinstance(error, CommandError),
"Error retrieving sources and will " "retry: %s", error
)
await asyncio.sleep(self.retry_delay)
else:
_LOGGER.error(
"Unable to update sources: %s",
error,
exc_info=isinstance(error, CommandError),
)
_LOGGER.error("Unable to update sources: %s", error)
return
async def update_sources(event, data=None):

View file

@ -1,7 +1,5 @@
"""Config flow to configure Heos."""
import asyncio
from pyheos import Heos
from pyheos import Heos, HeosError
import voluptuous as vol
from homeassistant import config_entries
@ -59,7 +57,7 @@ class HeosFlowHandler(config_entries.ConfigFlow):
await heos.connect()
self.hass.data.pop(DATA_DISCOVERED_HOSTS)
return await self.async_step_import({CONF_HOST: host})
except (asyncio.TimeoutError, ConnectionError):
except HeosError:
errors[CONF_HOST] = "connection_failure"
finally:
await heos.disconnect()

View file

@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/heos",
"requirements": [
"pyheos==0.5.2"
"pyheos==0.6.0"
],
"ssdp": {
"st": [
@ -15,4 +15,4 @@
"codeowners": [
"@andrewsayre"
]
}
}

View file

@ -1,11 +1,10 @@
"""Denon HEOS Media Player."""
import asyncio
from functools import reduce, wraps
import logging
from operator import ior
from typing import Sequence
from pyheos import CommandError, const as heos_const
from pyheos import HeosError, const as heos_const
from homeassistant.components.media_player import MediaPlayerDevice
from homeassistant.components.media_player.const import (
@ -83,12 +82,7 @@ def log_command_error(command: str):
async def wrapper(*args, **kwargs):
try:
await func(*args, **kwargs)
except (
CommandError,
asyncio.TimeoutError,
ConnectionError,
ValueError,
) as ex:
except (HeosError, ValueError) as ex:
_LOGGER.error("Unable to %s: %s", command, ex)
return wrapper

View file

@ -1,9 +1,8 @@
"""Services for the HEOS integration."""
import asyncio
import functools
import logging
from pyheos import CommandError, Heos, const
from pyheos import CommandFailedError, Heos, HeosError, const
import voluptuous as vol
from homeassistant.helpers import config_validation as cv
@ -57,9 +56,9 @@ async def _sign_in_handler(controller, service):
password = service.data[ATTR_PASSWORD]
try:
await controller.sign_in(username, password)
except CommandError as err:
except CommandFailedError as err:
_LOGGER.error("Sign in failed: %s", err)
except (asyncio.TimeoutError, ConnectionError) as err:
except HeosError as err:
_LOGGER.error("Unable to sign in: %s", err)
@ -70,5 +69,5 @@ async def _sign_out_handler(controller, service):
return
try:
await controller.sign_out()
except (asyncio.TimeoutError, ConnectionError, CommandError) as err:
except HeosError as err:
_LOGGER.error("Unable to sign out: %s", err)

View file

@ -1186,7 +1186,7 @@ pygtt==1.1.2
pyhaversion==3.0.2
# homeassistant.components.heos
pyheos==0.5.2
pyheos==0.6.0
# homeassistant.components.hikvision
pyhik==0.2.3

View file

@ -277,7 +277,7 @@ pydeconz==62
pydispatcher==2.0.5
# homeassistant.components.heos
pyheos==0.5.2
pyheos==0.6.0
# homeassistant.components.homematic
pyhomematic==0.1.60

View file

@ -1,5 +1,5 @@
"""Tests for the Heos config flow module."""
import asyncio
from pyheos import HeosError
from homeassistant import data_entry_flow
from homeassistant.components.heos.config_flow import HeosFlowHandler
@ -31,18 +31,15 @@ async def test_cannot_connect_shows_error_form(hass, controller):
"""Test form is shown with error when cannot connect."""
flow = HeosFlowHandler()
flow.hass = hass
errors = [ConnectionError, asyncio.TimeoutError]
for error in errors:
controller.connect.side_effect = error
result = await flow.async_step_user({CONF_HOST: "127.0.0.1"})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
assert result["errors"][CONF_HOST] == "connection_failure"
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
controller.connect.side_effect = HeosError()
result = await flow.async_step_user({CONF_HOST: "127.0.0.1"})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
assert result["errors"][CONF_HOST] == "connection_failure"
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
async def test_create_entry_when_host_valid(hass, controller):

View file

@ -2,7 +2,7 @@
import asyncio
from asynctest import Mock, patch
from pyheos import CommandError, const
from pyheos import CommandFailedError, HeosError, const
import pytest
from homeassistant.components.heos import (
@ -117,31 +117,27 @@ async def test_async_setup_entry_not_signed_in_loads_platforms(
async def test_async_setup_entry_connect_failure(hass, config_entry, controller):
"""Connection failure raises ConfigEntryNotReady."""
config_entry.add_to_hass(hass)
errors = [ConnectionError, asyncio.TimeoutError]
for error in errors:
controller.connect.side_effect = error
with pytest.raises(ConfigEntryNotReady):
await async_setup_entry(hass, config_entry)
await hass.async_block_till_done()
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
controller.connect.side_effect = HeosError()
with pytest.raises(ConfigEntryNotReady):
await async_setup_entry(hass, config_entry)
await hass.async_block_till_done()
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
async def test_async_setup_entry_player_failure(hass, config_entry, controller):
"""Failure to retrieve players/sources raises ConfigEntryNotReady."""
config_entry.add_to_hass(hass)
errors = [ConnectionError, asyncio.TimeoutError]
for error in errors:
controller.get_players.side_effect = error
with pytest.raises(ConfigEntryNotReady):
await async_setup_entry(hass, config_entry)
await hass.async_block_till_done()
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
controller.get_players.side_effect = HeosError()
with pytest.raises(ConfigEntryNotReady):
await async_setup_entry(hass, config_entry)
await hass.async_block_till_done()
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
controller.connect.reset_mock()
controller.disconnect.reset_mock()
async def test_unload_entry(hass, config_entry, controller):
@ -167,7 +163,7 @@ async def test_update_sources_retry(hass, config_entry, config, controller, capl
source_manager = hass.data[DOMAIN][DATA_SOURCE_MANAGER]
source_manager.retry_delay = 0
source_manager.max_retry_attempts = 1
controller.get_favorites.side_effect = CommandError("Test", "test", 0)
controller.get_favorites.side_effect = CommandFailedError("Test", "test", 0)
controller.dispatcher.send(
const.SIGNAL_CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {}
)

View file

@ -1,7 +1,7 @@
"""Tests for the Heos Media Player platform."""
import asyncio
from pyheos import CommandError, const
from pyheos import CommandFailedError, const
from homeassistant.components.heos import media_player
from homeassistant.components.heos.const import (
@ -179,7 +179,7 @@ async def test_updates_from_connection_event(
event.clear()
player.reset_mock()
controller.load_players.reset_mock()
controller.load_players.side_effect = CommandError(None, "Failure", 1)
controller.load_players.side_effect = CommandFailedError(None, "Failure", 1)
player.available = True
player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED)
await event.wait()
@ -313,7 +313,7 @@ async def test_clear_playlist(hass, config_entry, config, controller, caplog):
)
assert player.clear_queue.call_count == 1
player.clear_queue.reset_mock()
player.clear_queue.side_effect = CommandError(None, "Failure", 1)
player.clear_queue.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to clear playlist: Failure (1)" in caplog.text
@ -331,7 +331,7 @@ async def test_pause(hass, config_entry, config, controller, caplog):
)
assert player.pause.call_count == 1
player.pause.reset_mock()
player.pause.side_effect = CommandError(None, "Failure", 1)
player.pause.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to pause: Failure (1)" in caplog.text
@ -349,7 +349,7 @@ async def test_play(hass, config_entry, config, controller, caplog):
)
assert player.play.call_count == 1
player.play.reset_mock()
player.play.side_effect = CommandError(None, "Failure", 1)
player.play.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to play: Failure (1)" in caplog.text
@ -367,7 +367,7 @@ async def test_previous_track(hass, config_entry, config, controller, caplog):
)
assert player.play_previous.call_count == 1
player.play_previous.reset_mock()
player.play_previous.side_effect = CommandError(None, "Failure", 1)
player.play_previous.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to move to previous track: Failure (1)" in caplog.text
@ -385,7 +385,7 @@ async def test_next_track(hass, config_entry, config, controller, caplog):
)
assert player.play_next.call_count == 1
player.play_next.reset_mock()
player.play_next.side_effect = CommandError(None, "Failure", 1)
player.play_next.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to move to next track: Failure (1)" in caplog.text
@ -403,7 +403,7 @@ async def test_stop(hass, config_entry, config, controller, caplog):
)
assert player.stop.call_count == 1
player.stop.reset_mock()
player.stop.side_effect = CommandError(None, "Failure", 1)
player.stop.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to stop: Failure (1)" in caplog.text
@ -421,7 +421,7 @@ async def test_volume_mute(hass, config_entry, config, controller, caplog):
)
assert player.set_mute.call_count == 1
player.set_mute.reset_mock()
player.set_mute.side_effect = CommandError(None, "Failure", 1)
player.set_mute.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to set mute: Failure (1)" in caplog.text
@ -439,7 +439,7 @@ async def test_shuffle_set(hass, config_entry, config, controller, caplog):
)
player.set_play_mode.assert_called_once_with(player.repeat, True)
player.set_play_mode.reset_mock()
player.set_play_mode.side_effect = CommandError(None, "Failure", 1)
player.set_play_mode.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to set shuffle: Failure (1)" in caplog.text
@ -457,7 +457,7 @@ async def test_volume_set(hass, config_entry, config, controller, caplog):
)
player.set_volume.assert_called_once_with(100)
player.set_volume.reset_mock()
player.set_volume.side_effect = CommandError(None, "Failure", 1)
player.set_volume.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to set volume level: Failure (1)" in caplog.text
@ -516,7 +516,7 @@ async def test_select_radio_favorite_command_error(
player = controller.players[1]
# Test set radio preset
favorite = favorites[2]
player.play_favorite.side_effect = CommandError(None, "Failure", 1)
player.play_favorite.side_effect = CommandFailedError(None, "Failure", 1)
await hass.services.async_call(
MEDIA_PLAYER_DOMAIN,
SERVICE_SELECT_SOURCE,
@ -575,7 +575,7 @@ async def test_select_input_command_error(
await setup_platform(hass, config_entry, config)
player = controller.players[1]
input_source = input_sources[0]
player.play_input_source.side_effect = CommandError(None, "Failure", 1)
player.play_input_source.side_effect = CommandFailedError(None, "Failure", 1)
await hass.services.async_call(
MEDIA_PLAYER_DOMAIN,
SERVICE_SELECT_SOURCE,
@ -615,7 +615,7 @@ async def test_play_media_url(hass, config_entry, config, controller, caplog):
)
player.play_url.assert_called_once_with(url)
player.play_url.reset_mock()
player.play_url.side_effect = CommandError(None, "Failure", 1)
player.play_url.side_effect = CommandFailedError(None, "Failure", 1)
assert "Unable to play media: Failure (1)" in caplog.text

View file

@ -1,5 +1,5 @@
"""Tests for the services module."""
from pyheos import CommandError, const
from pyheos import CommandFailedError, HeosError, const
from homeassistant.components.heos.const import (
ATTR_PASSWORD,
@ -51,7 +51,7 @@ async def test_sign_in_not_connected(hass, config_entry, controller, caplog):
async def test_sign_in_failed(hass, config_entry, controller, caplog):
"""Test sign-in service logs error when not connected."""
await setup_component(hass, config_entry)
controller.sign_in.side_effect = CommandError("", "Invalid credentials", 6)
controller.sign_in.side_effect = CommandFailedError("", "Invalid credentials", 6)
await hass.services.async_call(
DOMAIN,
@ -67,7 +67,7 @@ async def test_sign_in_failed(hass, config_entry, controller, caplog):
async def test_sign_in_unknown_error(hass, config_entry, controller, caplog):
"""Test sign-in service logs error for failure."""
await setup_component(hass, config_entry)
controller.sign_in.side_effect = ConnectionError
controller.sign_in.side_effect = HeosError()
await hass.services.async_call(
DOMAIN,
@ -103,7 +103,7 @@ async def test_sign_out_not_connected(hass, config_entry, controller, caplog):
async def test_sign_out_unknown_error(hass, config_entry, controller, caplog):
"""Test the sign-out service."""
await setup_component(hass, config_entry)
controller.sign_out.side_effect = ConnectionError
controller.sign_out.side_effect = HeosError()
await hass.services.async_call(DOMAIN, SERVICE_SIGN_OUT, {}, blocking=True)