'Retrieve latest state.'

def update(self):

    if (self._speaker_info is None):
        self._speaker_info = self._player.get_speaker_info(True)
        self._name = self._speaker_info['zone_name'].replace('    (R)', '').replace('    (L)', '')
        self._favorite_sources = self._player.get_sonos_favorites()['favorites']
    if self._last_avtransport_event:
        is_available = True
    else:
        is_available = self._is_available()
    if (not is_available):
        self._player_volume = None
        self._player_volume_muted = None
        self._status = 'OFF'
        self._coordinator = None
        self._media_content_id = None
        self._media_duration = None
        self._media_position = None
        self._media_position_updated_at = None
        self._media_image_url = None
        self._media_artist = None
        self._media_album_name = None
        self._media_title = None
        self._media_radio_show = None
        self._media_next_title = None
        self._current_track_uri = None
        self._current_track_is_radio_stream = False
        self._support_previous_track = False
        self._support_next_track = False
        self._support_play = False
        self._support_stop = False
        self._support_pause = False
        self._is_playing_tv = False
        self._is_playing_line_in = False
        self._source_name = None
        self._last_avtransport_event = None
        return
    if self._player.is_coordinator:
        self._coordinator = None
    else:
        try:
            self._coordinator = _get_entity_from_soco(self.hass, self._player.group.coordinator)
            if (not self._coordinator.is_coordinator):
                self._coordinator._coordinator = None
        except ValueError:
            self._coordinator = None
    track_info = None
    if self._last_avtransport_event:
        variables = self._last_avtransport_event.variables
        current_track_metadata = variables.get('current_track_meta_data', {})
        self._status = variables.get('transport_state')
        if current_track_metadata:
            current_track_metadata = current_track_metadata.__dict__
            track_info = {'uri': variables.get('current_track_uri'), 'artist': current_track_metadata.get('creator'), 'album': current_track_metadata.get('album'), 'title': current_track_metadata.get('title'), 'playlist_position': variables.get('current_track'), 'duration': variables.get('current_track_duration')}
    else:
        self._player_volume = self._player.volume
        self._player_volume_muted = self._player.mute
        transport_info = self._player.get_current_transport_info()
        self._status = transport_info.get('current_transport_state')
    if (not track_info):
        track_info = self._player.get_current_track_info()
    if self._coordinator:
        self._last_avtransport_event = None
        return
    is_playing_tv = self._player.is_playing_tv
    is_playing_line_in = self._player.is_playing_line_in
    media_info = self._player.avTransport.GetMediaInfo([('InstanceID', 0)])
    current_media_uri = media_info['CurrentURI']
    media_artist = track_info.get('artist')
    media_album_name = track_info.get('album')
    media_title = track_info.get('title')
    media_image_url = track_info.get('album_art', None)
    media_position = None
    media_position_updated_at = None
    source_name = None
    is_radio_stream = (current_media_uri.startswith('x-sonosapi-stream:') or current_media_uri.startswith('x-rincon-mp3radio:'))
    if (is_playing_tv or is_playing_line_in):
        support_previous_track = False
        support_next_track = False
        support_play = False
        support_stop = True
        support_pause = False
        if is_playing_tv:
            media_artist = SUPPORT_SOURCE_TV
        else:
            media_artist = SUPPORT_SOURCE_LINEIN
        source_name = media_artist
        media_album_name = None
        media_title = None
        media_image_url = None
    elif is_radio_stream:
        media_image_url = self._format_media_image_url(media_image_url, current_media_uri)
        support_previous_track = False
        support_next_track = False
        support_play = True
        support_stop = True
        support_pause = False
        source_name = 'Radio'
        favc = [fav for fav in self._favorite_sources if (fav['uri'] == current_media_uri)]
        if (len(favc) == 1):
            src = favc.pop()
            source_name = src['title']
        if (media_artist and media_title):
            media_artist = '{artist}    -    {title}'.format(artist=media_artist, title=media_title)
        else:
            media_artist = self._media_radio_show
        current_uri_metadata = media_info['CurrentURIMetaData']
        if (current_uri_metadata not in ('', 'NOT_IMPLEMENTED', None)):
            import soco
            current_uri_metadata = soco.xml.XML.fromstring(soco.utils.really_utf8(current_uri_metadata))
            md_title = current_uri_metadata.findtext('.//{http://purl.org/dc/elements/1.1/}title')
            if (md_title not in ('', 'NOT_IMPLEMENTED', None)):
                media_title = md_title
        if (media_artist and media_title):
            str_to_trim = '{title}    -    '.format(title=media_title)
            chars = min(len(media_artist), len(str_to_trim))
            if (media_artist[:chars].upper() == str_to_trim[:chars].upper()):
                media_artist = media_artist[chars:]
    else:
        media_image_url = self._format_media_image_url(media_image_url, track_info['uri'])
        support_previous_track = True
        support_next_track = True
        support_play = True
        support_stop = True
        support_pause = True
        position_info = self._player.avTransport.GetPositionInfo([('InstanceID', 0), ('Channel', 'Master')])
        rel_time = _parse_timespan(position_info.get('RelTime'))
        update_media_position = ((rel_time is None) and (self._media_position is not None))
        update_media_position |= ((rel_time is not None) and (self._media_position is None))
        if ((rel_time is not None) and (self._media_position is not None)):
            time_diff = (utcnow() - self._media_position_updated_at)
            time_diff = time_diff.total_seconds()
            calculated_position = (self._media_position + time_diff)
            update_media_position = (abs((calculated_position - rel_time)) > 1.5)
        if (update_media_position and (self.state == STATE_PLAYING)):
            media_position = rel_time
            media_position_updated_at = utcnow()
        else:
            media_position = self._media_position
            media_position_updated_at = self._media_position_updated_at
        playlist_position = track_info.get('playlist_position')
        if (playlist_position in ('', 'NOT_IMPLEMENTED', None)):
            playlist_position = None
        else:
            playlist_position = int(playlist_position)
        playlist_size = media_info.get('NrTracks')
        if (playlist_size in ('', 'NOT_IMPLEMENTED', None)):
            playlist_size = None
        else:
            playlist_size = int(playlist_size)
        if ((playlist_position is not None) and (playlist_size is not None)):
            if (playlist_position <= 1):
                support_previous_track = False
            if (playlist_position == playlist_size):
                support_next_track = False
    self._media_content_id = track_info.get('title')
    self._media_duration = _parse_timespan(track_info.get('duration'))
    self._media_position = media_position
    self._media_position_updated_at = media_position_updated_at
    self._media_image_url = media_image_url
    self._media_artist = media_artist
    self._media_album_name = media_album_name
    self._media_title = media_title
    self._current_track_uri = track_info['uri']
    self._current_track_is_radio_stream = is_radio_stream
    self._support_previous_track = support_previous_track
    self._support_next_track = support_next_track
    self._support_play = support_play
    self._support_stop = support_stop
    self._support_pause = support_pause
    self._is_playing_tv = is_playing_tv
    self._is_playing_line_in = is_playing_line_in
    self._source_name = source_name
    self._last_avtransport_event = None
