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
26 changes: 8 additions & 18 deletions homeassistant/components/heos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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
Expand Down Expand Up @@ -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
Expand All @@ -93,13 +93,9 @@ async def disconnect_controller(event):
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)
Expand Down Expand Up @@ -187,7 +183,7 @@ async def _heos_event(self, event):
# 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)
Expand Down Expand Up @@ -312,21 +308,15 @@ async def get_sources():
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):
Expand Down
6 changes: 2 additions & 4 deletions homeassistant/components/heos/config_flow.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -59,7 +57,7 @@ async def async_step_user(self, user_input=None):
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()
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/heos/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand All @@ -15,4 +15,4 @@
"codeowners": [
"@andrewsayre"
]
}
}
10 changes: 2 additions & 8 deletions homeassistant/components/heos/media_player.py
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down Expand Up @@ -83,12 +82,7 @@ def decorator(func):
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
Expand Down
9 changes: 4 additions & 5 deletions homeassistant/components/heos/services.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)


Expand All @@ -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)
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 10 additions & 13 deletions tests/components/heos/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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):
Expand Down
40 changes: 18 additions & 22 deletions tests/components/heos/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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):
Expand All @@ -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, {}
)
Expand Down
Loading