Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions homeassistant/components/harmony/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,18 @@ async def async_step_ssdp(self, discovery_info):

if harmony:
unique_id = find_unique_id_for_remote(harmony)
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured(
updates={CONF_HOST: self.harmony_config[CONF_HOST]}
)
if self._uniqueid_already_configured(unique_id):
# Race Condition:
# We check to see if the unique id is configured
# before we call async_set_unique_id
# to update the host in the event that ssdp happened
# before the yaml imported in order to prevent
# aborting the import because the unique id
# is already set
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured(
updates={CONF_HOST: self.harmony_config[CONF_HOST]}
)
self.harmony_config[UNIQUE_ID] = unique_id

return await self.async_step_link()
Expand All @@ -111,6 +119,12 @@ async def async_step_link(self, user_input=None):
errors = {}

if user_input is not None:
# Race Condition:
# We have to check again that that harmony
# was not imported from yaml between the time
# they hit configure and when we found it via ssdp
await self.async_set_unique_id(self.harmony_config[UNIQUE_ID])
self._abort_if_unique_id_configured()
# Everything was validated in async_step_ssdp
# all we do now is create.
return await self._async_create_entry_from_valid_input(
Expand All @@ -130,6 +144,7 @@ async def async_step_import(self, validated_input):
"""Handle import."""
await self.async_set_unique_id(validated_input[UNIQUE_ID])
Comment thread
bdraco marked this conversation as resolved.
Outdated
self._abort_if_unique_id_configured()

# Everything was validated in remote async_setup_platform
# all we do now is create.
return await self._async_create_entry_from_valid_input(
Expand All @@ -149,14 +164,22 @@ async def _async_create_entry_from_valid_input(self, validated, user_input):
# Options from yaml are preserved, we will pull them out when
# we setup the config entry
data.update(_options_from_user_input(user_input))

return self.async_create_entry(title=validated[CONF_NAME], data=data)

def _host_already_configured(self, user_input):
Comment thread
bdraco marked this conversation as resolved.
"""See if we already have a harmony matching user input configured."""
existing_hosts = {
entry.data[CONF_HOST] for entry in self._async_current_entries()
def _uniqueid_already_configured(self, unique_id):
"""
See if we already have a harmony with this unique_id configured.

This function avoids setting the unique id to do
the checking which can cause a race condition where
the yaml will not get imported because ssdp discovers
the hub first.
"""
existing_unique_ids = {
entry.unique_id for entry in self._async_current_entries()
}
return user_input[CONF_HOST] in existing_hosts
return unique_id in existing_unique_ids


def _options_from_user_input(user_input):
Expand Down