Skip to content

Commit

Permalink
fix: check for login object changes
Browse files Browse the repository at this point in the history
This will handle the case where a new login was required and the devices are
using the old login information to connect. This happens when the
cookies expires.
closes #796
  • Loading branch information
alandtse committed Jun 22, 2020
1 parent 04fe69d commit b53e292
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
20 changes: 17 additions & 3 deletions custom_components/alexa_media/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ def __init__(self, login, media_players=None) -> None:
# Class info
self._login = login
self.alexa_api = AlexaAPI(self, login)
self.alexa_api_session = login.session
self.email = login.email
self.account = hide_email(login.email)

Expand All @@ -147,6 +146,21 @@ def __init__(self, login, media_players=None) -> None:
self._attrs: Dict[Text, Text] = {}
self._media_players = {} or media_players

def check_login_changes(self):
"""Update Login object if it has changed."""
try:
login = self.hass.data[DATA_ALEXAMEDIA]["accounts"][self.email]["login_obj"]
except (AttributeError, KeyError):
return
if self._login != login:
from alexapy import AlexaAPI

_LOGGER.debug("Login object has changed; updating")
self._login = login
self.alexa_api = AlexaAPI(self, login)
self.email = login.email
self.account = hide_email(login.email)

async def init(self):
"""Initialize."""
try:
Expand Down Expand Up @@ -220,6 +234,7 @@ def _handle_event(self, event):
@_catch_login_errors
async def async_update(self):
"""Update Guard state."""
self.check_login_changes()
try:
if not self.enabled:
return
Expand Down Expand Up @@ -266,6 +281,7 @@ async def async_update(self):
async def _async_alarm_set(self, command: Text = "", code=None) -> None:
# pylint: disable=unexpected-keyword-arg
"""Send command."""
self.check_login_changes()
try:
if not self.enabled:
return
Expand Down Expand Up @@ -296,13 +312,11 @@ async def _async_alarm_set(self, command: Text = "", code=None) -> None:
await self.async_update(no_throttle=True)
self.async_schedule_update_ha_state()

@_catch_login_errors
async def async_alarm_disarm(self, code=None) -> None:
# pylint: disable=unexpected-keyword-arg
"""Send disarm command."""
await self._async_alarm_set(STATE_ALARM_DISARMED)

@_catch_login_errors
async def async_alarm_arm_away(self, code=None) -> None:
"""Send arm away command."""
# pylint: disable=unexpected-keyword-arg
Expand Down
33 changes: 33 additions & 0 deletions custom_components/alexa_media/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,21 @@ async def init(self, device):
"""Initialize."""
await self.refresh(device)

def check_login_changes(self):
"""Update Login object if it has changed."""
try:
login = self.hass.data[DATA_ALEXAMEDIA]["accounts"][self.email]["login_obj"]
except (AttributeError, KeyError):
return
if self._login != login:
from alexapy import AlexaAPI

_LOGGER.debug("Login object has changed; updating")
self._login = login
self.alexa_api = AlexaAPI(self, login)
self.email = login.email
self.account = hide_email(login.email)

async def async_added_to_hass(self):
"""Perform tasks after loading."""
# Register event handler on bus
Expand Down Expand Up @@ -284,6 +299,7 @@ async def _refresh_if_no_audiopush(already_refreshed=False):
return
except AttributeError:
pass
self.check_login_changes()
already_refreshed = False
event_serial = None
if "last_called_change" in event:
Expand Down Expand Up @@ -464,6 +480,7 @@ async def refresh(self, device=None, skip_api: bool = False):
skip_api (bool): Whether to only due a device json update and not hit the API
"""
self.check_login_changes()
if device is not None:
self._device_name = device["accountName"]
self._device_family = device["deviceFamily"]
Expand Down Expand Up @@ -643,6 +660,7 @@ def source_list(self):
@_catch_login_errors
async def async_select_source(self, source):
"""Select input source."""
self.check_login_changes()
if source == "Local Speaker":
await self.alexa_api.disconnect_bluetooth()
self._source = "Local Speaker"
Expand Down Expand Up @@ -775,6 +793,7 @@ async def async_update(self):
every update. However, this quickly floods the network for every new
device added. This should only call refresh() to call the AlexaAPI.
"""
self.check_login_changes()
try:
if not self.enabled:
return
Expand Down Expand Up @@ -921,6 +940,7 @@ def dnd_state(self, state):
@_catch_login_errors
async def async_set_shuffle(self, shuffle):
"""Enable/disable shuffle mode."""
self.check_login_changes()
await self.alexa_api.shuffle(shuffle)
self._shuffle = shuffle

Expand Down Expand Up @@ -954,6 +974,7 @@ def supported_features(self):
@_catch_login_errors
async def async_set_volume_level(self, volume):
"""Set volume level, range 0..1."""
self.check_login_changes()
if not self.available:
return
await self.alexa_api.set_volume(volume)
Expand Down Expand Up @@ -983,6 +1004,7 @@ async def async_mute_volume(self, mute):
- On mute, store volume and set volume to 0
- On unmute, set volume to previously stored volume
"""
self.check_login_changes()
if not self.available:
return

Expand All @@ -1003,6 +1025,7 @@ async def async_mute_volume(self, mute):
@_catch_login_errors
async def async_media_play(self):
"""Send play command."""
self.check_login_changes()
if not (self.state in [STATE_PLAYING, STATE_PAUSED] and self.available):
return
if self._playing_parent:
Expand All @@ -1017,6 +1040,7 @@ async def async_media_play(self):
@_catch_login_errors
async def async_media_pause(self):
"""Send pause command."""
self.check_login_changes()
if not (self.state in [STATE_PLAYING, STATE_PAUSED] and self.available):
return
if self._playing_parent:
Expand All @@ -1031,6 +1055,7 @@ async def async_media_pause(self):
@_catch_login_errors
async def async_media_stop(self):
"""Send stop command."""
self.check_login_changes()
if not self.available:
return
if self._playing_parent:
Expand All @@ -1054,6 +1079,7 @@ async def async_turn_off(self):
While Alexa's do not have on/off capability, we can use this as another
trigger to do updates. For turning off, we can clear media_details.
"""
self.check_login_changes()
self._should_poll = False
await self.async_media_pause()
self._clear_media_details()
Expand All @@ -1065,12 +1091,14 @@ async def async_turn_on(self):
While Alexa's do not have on/off capability, we can use this as another
trigger to do updates.
"""
self.check_login_changes()
self._should_poll = True
await self.async_media_pause()

@_catch_login_errors
async def async_media_next_track(self):
"""Send next track command."""
self.check_login_changes()
if not (self.state in [STATE_PLAYING, STATE_PAUSED] and self.available):
return
if self._playing_parent:
Expand All @@ -1085,6 +1113,7 @@ async def async_media_next_track(self):
@_catch_login_errors
async def async_media_previous_track(self):
"""Send previous track command."""
self.check_login_changes()
if not (self.state in [STATE_PLAYING, STATE_PAUSED] and self.available):
return
if self._playing_parent:
Expand All @@ -1102,18 +1131,21 @@ async def async_send_tts(self, message, **kwargs):
NOTE: Does not work on WHA Groups.
"""
self.check_login_changes()
await self.alexa_api.send_tts(message, customer_id=self._customer_id, **kwargs)

@_catch_login_errors
async def async_send_announcement(self, message, **kwargs):
"""Send announcement to the media player."""
self.check_login_changes()
await self.alexa_api.send_announcement(
message, customer_id=self._customer_id, **kwargs
)

@_catch_login_errors
async def async_send_mobilepush(self, message, **kwargs):
"""Send push to the media player's associated mobile devices."""
self.check_login_changes()
await self.alexa_api.send_mobilepush(
message, customer_id=self._customer_id, **kwargs
)
Expand All @@ -1122,6 +1154,7 @@ async def async_send_mobilepush(self, message, **kwargs):
async def async_play_media(self, media_type, media_id, enqueue=None, **kwargs):
# pylint: disable=unused-argument
"""Send the play_media command to the media player."""
self.check_login_changes()
if media_type == "music":
await self.async_send_tts(
"Sorry, text to speech can only be called"
Expand Down

0 comments on commit b53e292

Please sign in to comment.