Stability improvement in Pandora and proper shutdown in LIRC (#2299)

* Pandora cleanups and enhancements

Added media_content_type
reduced debug messages
made more robust station list
Eliminated auto-pause detection issue

* Added proper de-init of LIRC

* Now won't re-spawn Pandora client if turn_on command is sent twice
This commit is contained in:
Nick Touran 2016-06-14 22:42:54 -07:00 committed by Paulus Schoutsen
parent 7b8b78ec0e
commit 5c601f1d5f
2 changed files with 30 additions and 9 deletions

View File

@ -65,6 +65,7 @@ class LircInterface(threading.Thread):
def run(self): def run(self):
"""Main loop of LIRC interface thread.""" """Main loop of LIRC interface thread."""
import lirc import lirc
_LOGGER.debug('LIRC interface thread started')
while not self.stopped.isSet(): while not self.stopped.isSet():
try: try:
code = lirc.nextcode() # list; empty if no buttons pressed code = lirc.nextcode() # list; empty if no buttons pressed
@ -80,4 +81,5 @@ class LircInterface(threading.Thread):
{BUTTON_NAME: code}) {BUTTON_NAME: code})
else: else:
time.sleep(0.2) time.sleep(0.2)
_LOGGER.info('LIRC interface thread stopped') lirc.deinit()
_LOGGER.debug('LIRC interface thread stopped')

View File

@ -14,7 +14,7 @@ import shutil
from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, MEDIA_TYPE_MUSIC,
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
SUPPORT_SELECT_SOURCE, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PLAY_PAUSE, SUPPORT_SELECT_SOURCE, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PLAY_PAUSE,
SERVICE_MEDIA_PLAY, SERVICE_VOLUME_UP, SERVICE_VOLUME_DOWN, SERVICE_MEDIA_PLAY, SERVICE_VOLUME_UP, SERVICE_VOLUME_DOWN,
@ -97,6 +97,8 @@ class PandoraMediaPlayer(MediaPlayerDevice):
def turn_on(self): def turn_on(self):
"""Turn the media player on.""" """Turn the media player on."""
import pexpect import pexpect
if self._player_state != STATE_OFF:
return
self._pianobar = pexpect.spawn('pianobar') self._pianobar = pexpect.spawn('pianobar')
_LOGGER.info('Started pianobar subprocess') _LOGGER.info('Started pianobar subprocess')
mode = self._pianobar.expect(['Receiving new playlist', mode = self._pianobar.expect(['Receiving new playlist',
@ -166,6 +168,11 @@ class PandoraMediaPlayer(MediaPlayerDevice):
self.update_playing_status() self.update_playing_status()
return self._media_title return self._media_title
@property
def media_content_type(self):
"""Content type of current playing media."""
return MEDIA_TYPE_MUSIC
@property @property
def media_artist(self): def media_artist(self):
"""Artist of current playing media, music track only.""" """Artist of current playing media, music track only."""
@ -189,12 +196,23 @@ class PandoraMediaPlayer(MediaPlayerDevice):
_LOGGER.warning('Station `%s` is not in list', source) _LOGGER.warning('Station `%s` is not in list', source)
return return
_LOGGER.info('Setting station %s, %d', source, station_index) _LOGGER.info('Setting station %s, %d', source, station_index)
self._pianobar.send('s') self._send_station_list_command()
self._pianobar.expect('Select station')
self._pianobar.sendline('{}'.format(station_index)) self._pianobar.sendline('{}'.format(station_index))
self._pianobar.expect('\r\n') self._pianobar.expect('\r\n')
self._player_state = STATE_PLAYING self._player_state = STATE_PLAYING
def _send_station_list_command(self):
"""Send a station list command."""
import pexpect
self._pianobar.send('s')
try:
self._pianobar.expect('Select station:', timeout=1)
except pexpect.exceptions.TIMEOUT:
# try again. Buffer was contaminated.
self._clear_buffer()
self._pianobar.send('s')
self._pianobar.expect('Select station:')
def update_playing_status(self): def update_playing_status(self):
"""Query pianobar for info about current media_title, station.""" """Query pianobar for info about current media_title, station."""
response = self._query_for_playing_status() response = self._query_for_playing_status()
@ -268,11 +286,10 @@ class PandoraMediaPlayer(MediaPlayerDevice):
time_remaining = int(cur_minutes) * 60 + int(cur_seconds) time_remaining = int(cur_minutes) * 60 + int(cur_seconds)
self._media_duration = int(total_minutes) * 60 + int(total_seconds) self._media_duration = int(total_minutes) * 60 + int(total_seconds)
if time_remaining != self._time_remaining: if (time_remaining != self._time_remaining and
_LOGGER.debug('PLAYING') time_remaining != self._media_duration):
self._player_state = STATE_PLAYING self._player_state = STATE_PLAYING
elif self._player_state == STATE_PLAYING: elif self._player_state == STATE_PLAYING:
_LOGGER.debug('PAUSED')
self._player_state = STATE_PAUSED self._player_state = STATE_PAUSED
self._time_remaining = time_remaining self._time_remaining = time_remaining
@ -286,14 +303,16 @@ class PandoraMediaPlayer(MediaPlayerDevice):
def _send_pianobar_command(self, service_cmd): def _send_pianobar_command(self, service_cmd):
"""Send a command to Pianobar.""" """Send a command to Pianobar."""
command = CMD_MAP.get(service_cmd) command = CMD_MAP.get(service_cmd)
_LOGGER.debug('Sending pinaobar command %s for %s',
command, service_cmd)
if command is None: if command is None:
_LOGGER.info('Command %s not supported yet', service_cmd) _LOGGER.info('Command %s not supported yet', service_cmd)
self._clear_buffer()
self._pianobar.sendline(command) self._pianobar.sendline(command)
def _update_stations(self): def _update_stations(self):
"""List defined Pandora stations.""" """List defined Pandora stations."""
self._pianobar.send('s') self._send_station_list_command()
self._pianobar.expect('Select station:')
station_lines = self._pianobar.before.decode('utf-8') station_lines = self._pianobar.before.decode('utf-8')
_LOGGER.debug('Getting stations: %s', station_lines) _LOGGER.debug('Getting stations: %s', station_lines)
self._stations = [] self._stations = []