mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Fix dead Sonos web interface with some music sources (#12796)
* Get data from soco, not event * Patch soco.events.parse_event_xml to ignore exceptions
This commit is contained in:
parent
7511286a25
commit
b6805853f1
@ -120,6 +120,19 @@ class SonosData:
|
|||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
"""Set up the Sonos platform."""
|
"""Set up the Sonos platform."""
|
||||||
import soco
|
import soco
|
||||||
|
import soco.events
|
||||||
|
import soco.exceptions
|
||||||
|
|
||||||
|
orig_parse_event_xml = soco.events.parse_event_xml
|
||||||
|
|
||||||
|
def safe_parse_event_xml(xml):
|
||||||
|
"""Avoid SoCo 0.14 event thread dying from invalid xml."""
|
||||||
|
try:
|
||||||
|
return orig_parse_event_xml(xml)
|
||||||
|
except soco.exceptions.SoCoException:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
soco.events.parse_event_xml = safe_parse_event_xml
|
||||||
|
|
||||||
if DATA_SONOS not in hass.data:
|
if DATA_SONOS not in hass.data:
|
||||||
hass.data[DATA_SONOS] = SonosData()
|
hass.data[DATA_SONOS] = SonosData()
|
||||||
@ -452,14 +465,14 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
|
|
||||||
def process_avtransport_event(self, event):
|
def process_avtransport_event(self, event):
|
||||||
"""Process a track change event coming from a coordinator."""
|
"""Process a track change event coming from a coordinator."""
|
||||||
variables = event.variables
|
transport_info = self.soco.get_current_transport_info()
|
||||||
|
new_status = transport_info.get('current_transport_state')
|
||||||
|
|
||||||
# Ignore transitions, we should get the target state soon
|
# Ignore transitions, we should get the target state soon
|
||||||
new_status = variables.get('transport_state')
|
|
||||||
if new_status == 'TRANSITIONING':
|
if new_status == 'TRANSITIONING':
|
||||||
return
|
return
|
||||||
|
|
||||||
self._play_mode = variables.get('current_play_mode', self._play_mode)
|
self._play_mode = self.soco.play_mode
|
||||||
|
|
||||||
if self.soco.is_playing_tv:
|
if self.soco.is_playing_tv:
|
||||||
self._refresh_linein(SOURCE_TV)
|
self._refresh_linein(SOURCE_TV)
|
||||||
@ -473,11 +486,11 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if _is_radio_uri(track_info['uri']):
|
if _is_radio_uri(track_info['uri']):
|
||||||
self._refresh_radio(variables, media_info, track_info)
|
self._refresh_radio(event.variables, media_info, track_info)
|
||||||
else:
|
else:
|
||||||
self._refresh_music(variables, media_info, track_info)
|
update_position = (new_status != self._status)
|
||||||
|
self._refresh_music(update_position, media_info, track_info)
|
||||||
|
|
||||||
if new_status:
|
|
||||||
self._status = new_status
|
self._status = new_status
|
||||||
|
|
||||||
self.schedule_update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
@ -586,9 +599,7 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# "On Now" field in the sonos pc app
|
# "On Now" field in the sonos pc app
|
||||||
current_track_metadata = variables.get(
|
current_track_metadata = variables.get('current_track_meta_data')
|
||||||
'current_track_meta_data'
|
|
||||||
)
|
|
||||||
if current_track_metadata:
|
if current_track_metadata:
|
||||||
self._media_artist = \
|
self._media_artist = \
|
||||||
current_track_metadata.radio_show.split(',')[0]
|
current_track_metadata.radio_show.split(',')[0]
|
||||||
@ -626,7 +637,7 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
if fav.reference.get_uri() == media_info['CurrentURI']:
|
if fav.reference.get_uri() == media_info['CurrentURI']:
|
||||||
self._source_name = fav.title
|
self._source_name = fav.title
|
||||||
|
|
||||||
def _refresh_music(self, variables, media_info, track_info):
|
def _refresh_music(self, update_media_position, media_info, track_info):
|
||||||
"""Update state when playing music tracks."""
|
"""Update state when playing music tracks."""
|
||||||
self._extra_features = SUPPORT_PAUSE | SUPPORT_SHUFFLE_SET |\
|
self._extra_features = SUPPORT_PAUSE | SUPPORT_SHUFFLE_SET |\
|
||||||
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
||||||
@ -659,16 +670,13 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
rel_time = _timespan_secs(position_info.get("RelTime"))
|
rel_time = _timespan_secs(position_info.get("RelTime"))
|
||||||
|
|
||||||
# player no longer reports position?
|
# player no longer reports position?
|
||||||
update_media_position = rel_time is None and \
|
update_media_position |= rel_time is None and \
|
||||||
self._media_position is not None
|
self._media_position is not None
|
||||||
|
|
||||||
# player started reporting position?
|
# player started reporting position?
|
||||||
update_media_position |= rel_time is not None and \
|
update_media_position |= rel_time is not None and \
|
||||||
self._media_position is None
|
self._media_position is None
|
||||||
|
|
||||||
if self._status != variables.get('transport_state'):
|
|
||||||
update_media_position = True
|
|
||||||
else:
|
|
||||||
# position jumped?
|
# position jumped?
|
||||||
if rel_time is not None and self._media_position is not None:
|
if rel_time is not None and self._media_position is not None:
|
||||||
time_diff = utcnow() - self._media_position_updated_at
|
time_diff = utcnow() - self._media_position_updated_at
|
||||||
@ -676,8 +684,7 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
|
|
||||||
calculated_position = self._media_position + time_diff
|
calculated_position = self._media_position + time_diff
|
||||||
|
|
||||||
update_media_position = \
|
update_media_position |= abs(calculated_position - rel_time) > 1.5
|
||||||
abs(calculated_position - rel_time) > 1.5
|
|
||||||
|
|
||||||
if update_media_position:
|
if update_media_position:
|
||||||
self._media_position = rel_time
|
self._media_position = rel_time
|
||||||
|
Loading…
x
Reference in New Issue
Block a user