Skip to content

Commit

Permalink
fix: change platform loading to be account specific
Browse files Browse the repository at this point in the history
Previously loading platforms would try to load all devices across all 
accounts. This could result in a race condition if multiple accounts 
loaded platforms at the same time.
  • Loading branch information
alandtse committed Sep 3, 2019
1 parent 5c98a9c commit bcc0de7
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 68 deletions.
11 changes: 8 additions & 3 deletions custom_components/alexa_media/__init__.py
Expand Up @@ -255,7 +255,8 @@ async def test_login_status(hass, config, login,
"""Test the login status and spawn requests for info."""
_LOGGER.debug("Testing login status: %s", login.status)
if 'login_successful' in login.status and login.status['login_successful']:
_LOGGER.debug("Setting up Alexa devices")
_LOGGER.debug("Setting up Alexa devices for %s",
hide_email(login.email))
await hass.async_add_job(setup_alexa, hass, config,
login)
return
Expand Down Expand Up @@ -303,7 +304,11 @@ async def update_devices(login_obj):
['accounts']
[email]
['entities']
['media_player'].keys())
['media_player'].keys() if 'entities' in (
hass.data[DATA_ALEXAMEDIA]
['accounts']
[email])
else [])
existing_entities = (hass.data[DATA_ALEXAMEDIA]
['accounts']
[email]
Expand Down Expand Up @@ -413,7 +418,7 @@ async def update_devices(login_obj):
async_load_platform(hass,
component,
DOMAIN,
{CONF_NAME: DOMAIN},
{CONF_NAME: DOMAIN, "config": config},
config))

# Process last_called data to fire events
Expand Down
41 changes: 29 additions & 12 deletions custom_components/alexa_media/alarm_control_panel.py
Expand Up @@ -18,7 +18,11 @@

from . import DATA_ALEXAMEDIA
from . import DOMAIN as ALEXA_DOMAIN
from . import MIN_TIME_BETWEEN_FORCED_SCANS, MIN_TIME_BETWEEN_SCANS, hide_email
from . import (
CONF_EMAIL,
MIN_TIME_BETWEEN_FORCED_SCANS,
MIN_TIME_BETWEEN_SCANS, hide_email
)
from .helpers import add_devices

_LOGGER = logging.getLogger(__name__)
Expand All @@ -32,22 +36,35 @@ async def async_setup_platform(hass,
discovery_info=None) -> bool:
"""Set up the Alexa alarm control panel platform."""
devices = [] # type: List[AlexaAlarmControlPanel]
for account, account_dict in (hass.data[DATA_ALEXAMEDIA]
['accounts'].items()):
alexa_client: AlexaAlarmControlPanel = AlexaAlarmControlPanel(
account_dict['login_obj'])
await alexa_client.init()
if not (alexa_client and alexa_client.unique_id):
_LOGGER.debug("%s: Skipping creation of uninitialized device: %s",
hide_email(account),
alexa_client)
continue
config = discovery_info['config']
account = config[CONF_EMAIL]
account_dict = hass.data[DATA_ALEXAMEDIA]['accounts'][account]
if 'alarm_control_panel' not in (account_dict
['entities']):
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']['alarm_control_panel']) = {}
alexa_client: AlexaAlarmControlPanel = AlexaAlarmControlPanel(
account_dict['login_obj'])
await alexa_client.init()
if not (alexa_client and alexa_client.unique_id):
_LOGGER.debug("%s: Skipping creation of uninitialized device: %s",
hide_email(account),
alexa_client)
elif alexa_client.unique_id not in (account_dict
['entities']
['alarm_control_panel']):
devices.append(alexa_client)
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['alarm_control_panel']) = alexa_client
['alarm_control_panel'][alexa_client.unique_id]) = alexa_client
else:
_LOGGER.debug("%s: Skipping already added device: %s",
hide_email(account),
alexa_client)
return await add_devices(devices, add_devices_callback)


Expand Down
37 changes: 22 additions & 15 deletions custom_components/alexa_media/media_player.py
Expand Up @@ -40,7 +40,7 @@

from . import (
DOMAIN as ALEXA_DOMAIN,
CONF_NAME,
CONF_NAME, CONF_EMAIL,
DATA_ALEXAMEDIA,
MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS,
hide_email, hide_serial)
Expand All @@ -59,20 +59,27 @@ async def async_setup_platform(hass, config, add_devices_callback,
discovery_info=None):
"""Set up the Alexa media player platform."""
devices = [] # type: List[AlexaClient]
for account, account_dict in (hass.data[DATA_ALEXAMEDIA]
['accounts'].items()):
for key, device in account_dict['devices']['media_player'].items():
if key not in account_dict['entities']['media_player']:
alexa_client = AlexaClient(device,
account_dict['login_obj']
)
await alexa_client.init(device)
devices.append(alexa_client)
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['media_player'][key]) = alexa_client
config = discovery_info['config']
account = config[CONF_EMAIL]
account_dict = hass.data[DATA_ALEXAMEDIA]['accounts'][account]
for key, device in account_dict['devices']['media_player'].items():
if key not in account_dict['entities']['media_player']:
alexa_client = AlexaClient(device,
account_dict['login_obj']
)
await alexa_client.init(device)
devices.append(alexa_client)
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['media_player'][key]) = alexa_client
else:
_LOGGER.debug("%s: Skipping already added device: %s:%s",
hide_email(account),
hide_serial(key),
alexa_client
)
return await add_devices(devices, add_devices_callback)


Expand Down
87 changes: 49 additions & 38 deletions custom_components/alexa_media/switch.py
Expand Up @@ -19,7 +19,7 @@
from . import DOMAIN as ALEXA_DOMAIN
from . import (
MIN_TIME_BETWEEN_FORCED_SCANS, MIN_TIME_BETWEEN_SCANS,
hide_email, hide_serial
hide_email, hide_serial, CONF_EMAIL
)
from .helpers import add_devices

Expand All @@ -36,46 +36,58 @@ async def async_setup_platform(hass, config, add_devices_callback,
('shuffle', ShuffleSwitch),
('repeat', RepeatSwitch)
]
for account, account_dict in (hass.data[DATA_ALEXAMEDIA]
['accounts'].items()):
for key, device in account_dict['devices']['media_player'].items():
if 'switch' not in account_dict['entities']:
config = discovery_info['config']
account = config[CONF_EMAIL]
account_dict = hass.data[DATA_ALEXAMEDIA]['accounts'][account]
if 'switch' not in account_dict['entities']:
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch']) = {}
for key, device in account_dict['devices']['media_player'].items():
if key not in account_dict['entities']['media_player']:
_LOGGER.debug("Media Players not loaded yet; delaying load")
async_call_later(hass, 5, lambda _:
hass.async_create_task(
async_setup_platform(hass,
config,
add_devices_callback,
discovery_info)))
return True
if key not in (hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch']):
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch'][key]) = {}
for (switch_key, class_) in SWITCH_TYPES:
alexa_client = class_(account_dict['entities']
['media_player']
[key],
account) # type: AlexaMediaSwitch
_LOGGER.debug("%s: Found %s %s switch with status: %s",
hide_email(account),
hide_serial(key),
switch_key,
alexa_client.is_on)
devices.append(alexa_client)
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch']) = {}
if key not in account_dict['entities']['media_player']:
_LOGGER.debug("Media Players not loaded yet; delaying load")
async_call_later(hass, 5, lambda _:
hass.async_create_task(
async_setup_platform(hass,
config,
add_devices_callback,
discovery_info)))
return True
elif key not in account_dict['entities']['switch']:
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch'][key]) = {}
for (switch_key, class_) in SWITCH_TYPES:
alexa_client = class_(account_dict['entities']
['media_player']
[key],
account) # type: AlexaMediaSwitch
(hass.data[DATA_ALEXAMEDIA]
['accounts']
[account]
['entities']
['switch'][key][switch_key]) = alexa_client
_LOGGER.debug("%s: Found %s %s switch with status: %s",
hide_email(account),
hide_serial(key),
switch_key,
alexa_client.is_on)
devices.append(alexa_client)
['switch']
[key]
[switch_key]) = alexa_client
else:
_LOGGER.debug("%s: Skipping already added device: %s:%s",
hide_email(account),
key,
alexa_client)
return await add_devices(devices, add_devices_callback)


Expand All @@ -96,7 +108,6 @@ def __init__(self,
self._switch_property = switch_property
self._state = False
self._switch_function = switch_function
_LOGGER.debug("Creating %s switch for %s", name, client)

async def async_added_to_hass(self):
"""Store register state change callback."""
Expand Down

0 comments on commit bcc0de7

Please sign in to comment.