Improve handling of unavailable Sonos speakers (#23472)

This commit is contained in:
Anders Melchiorsen 2019-04-27 19:05:50 +02:00 committed by GitHub
parent b6a13262da
commit 5efe089699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 22 deletions

View File

@ -3,7 +3,7 @@
"name": "Sonos", "name": "Sonos",
"documentation": "https://www.home-assistant.io/components/sonos", "documentation": "https://www.home-assistant.io/components/sonos",
"requirements": [ "requirements": [
"pysonos==0.0.10" "pysonos==0.0.11"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [ "codeowners": [

View File

@ -7,9 +7,12 @@ import socket
import urllib import urllib
import async_timeout import async_timeout
import requests
import voluptuous as vol import voluptuous as vol
import pysonos
import pysonos.snapshot
from pysonos.exceptions import SoCoUPnPException, SoCoException
from homeassistant.components.media_player import MediaPlayerDevice from homeassistant.components.media_player import MediaPlayerDevice
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player.const import (
ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_CLEAR_PLAYLIST, ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_CLEAR_PLAYLIST,
@ -122,8 +125,6 @@ async def async_setup_platform(hass,
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up Sonos from a config entry.""" """Set up Sonos from a config entry."""
import pysonos
if DATA_SONOS not in hass.data: if DATA_SONOS not in hass.data:
hass.data[DATA_SONOS] = SonosData(hass) hass.data[DATA_SONOS] = SonosData(hass)
@ -142,7 +143,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for host in hosts: for host in hosts:
try: try:
players.append(pysonos.SoCo(socket.gethostbyname(host))) players.append(pysonos.SoCo(socket.gethostbyname(host)))
except OSError: except (OSError, SoCoException):
_LOGGER.warning("Failed to initialize '%s'", host) _LOGGER.warning("Failed to initialize '%s'", host)
else: else:
players = pysonos.discover( players = pysonos.discover(
@ -260,8 +261,6 @@ def soco_error(errorcodes=None):
@ft.wraps(funct) @ft.wraps(funct)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
"""Wrap for all soco UPnP exception.""" """Wrap for all soco UPnP exception."""
from pysonos.exceptions import SoCoUPnPException, SoCoException
try: try:
return funct(*args, **kwargs) return funct(*args, **kwargs)
except SoCoUPnPException as err: except SoCoUPnPException as err:
@ -472,7 +471,7 @@ class SonosEntity(MediaPlayerDevice):
self._subscribe_to_player_events() self._subscribe_to_player_events()
else: else:
for subscription in self._subscriptions: for subscription in self._subscriptions:
self.hass.async_add_executor_job(subscription.unsubscribe) subscription.unsubscribe()
self._subscriptions = [] self._subscriptions = []
self._player_volume = None self._player_volume = None
@ -488,10 +487,13 @@ class SonosEntity(MediaPlayerDevice):
self._media_title = None self._media_title = None
self._source_name = None self._source_name = None
elif available and not self._receives_events: elif available and not self._receives_events:
self.update_groups() try:
self.update_volume() self.update_groups()
if self.is_coordinator: self.update_volume()
self.update_media() if self.is_coordinator:
self.update_media()
except SoCoException:
pass
def update_media(self, event=None): def update_media(self, event=None):
"""Update information about currently playing media.""" """Update information about currently playing media."""
@ -574,7 +576,6 @@ class SonosEntity(MediaPlayerDevice):
current_uri_metadata = media_info["CurrentURIMetaData"] current_uri_metadata = media_info["CurrentURIMetaData"]
if current_uri_metadata not in ('', 'NOT_IMPLEMENTED', None): if current_uri_metadata not in ('', 'NOT_IMPLEMENTED', None):
# currently soco does not have an API for this # currently soco does not have an API for this
import pysonos
current_uri_metadata = pysonos.xml.XML.fromstring( current_uri_metadata = pysonos.xml.XML.fromstring(
pysonos.utils.really_utf8(current_uri_metadata)) pysonos.utils.really_utf8(current_uri_metadata))
@ -678,7 +679,7 @@ class SonosEntity(MediaPlayerDevice):
coordinator_uid = self.soco.group.coordinator.uid coordinator_uid = self.soco.group.coordinator.uid
slave_uids = [p.uid for p in self.soco.group.members slave_uids = [p.uid for p in self.soco.group.members
if p.uid != coordinator_uid] if p.uid != coordinator_uid]
except requests.exceptions.RequestException: except SoCoException:
pass pass
return [coordinator_uid] + slave_uids return [coordinator_uid] + slave_uids
@ -933,7 +934,6 @@ class SonosEntity(MediaPlayerDevice):
If ATTR_MEDIA_ENQUEUE is True, add `media_id` to the queue. If ATTR_MEDIA_ENQUEUE is True, add `media_id` to the queue.
""" """
if kwargs.get(ATTR_MEDIA_ENQUEUE): if kwargs.get(ATTR_MEDIA_ENQUEUE):
from pysonos.exceptions import SoCoUPnPException
try: try:
self.soco.add_uri_to_queue(media_id) self.soco.add_uri_to_queue(media_id)
except SoCoUPnPException: except SoCoUPnPException:
@ -994,9 +994,7 @@ class SonosEntity(MediaPlayerDevice):
@soco_error() @soco_error()
def snapshot(self, with_group): def snapshot(self, with_group):
"""Snapshot the state of a player.""" """Snapshot the state of a player."""
from pysonos.snapshot import Snapshot self._soco_snapshot = pysonos.snapshot.Snapshot(self.soco)
self._soco_snapshot = Snapshot(self.soco)
self._soco_snapshot.snapshot() self._soco_snapshot.snapshot()
if with_group: if with_group:
self._snapshot_group = self._sonos_group.copy() self._snapshot_group = self._sonos_group.copy()
@ -1025,8 +1023,6 @@ class SonosEntity(MediaPlayerDevice):
@soco_error() @soco_error()
def restore(self): def restore(self):
"""Restore a snapshotted state to a player.""" """Restore a snapshotted state to a player."""
from pysonos.exceptions import SoCoException
try: try:
# pylint: disable=protected-access # pylint: disable=protected-access
self._soco_snapshot.restore() self._soco_snapshot.restore()

View File

@ -1288,7 +1288,7 @@ pysmartthings==0.6.7
pysnmp==4.4.8 pysnmp==4.4.8
# homeassistant.components.sonos # homeassistant.components.sonos
pysonos==0.0.10 pysonos==0.0.11
# homeassistant.components.spc # homeassistant.components.spc
pyspcwebgw==0.4.0 pyspcwebgw==0.4.0

View File

@ -258,7 +258,7 @@ pysmartapp==0.3.2
pysmartthings==0.6.7 pysmartthings==0.6.7
# homeassistant.components.sonos # homeassistant.components.sonos
pysonos==0.0.10 pysonos==0.0.11
# homeassistant.components.spc # homeassistant.components.spc
pyspcwebgw==0.4.0 pyspcwebgw==0.4.0