diff --git a/homeassistant/components/alexa/state_report.py b/homeassistant/components/alexa/state_report.py index 1e22d5fc09f..fbf928fd23e 100644 --- a/homeassistant/components/alexa/state_report.py +++ b/homeassistant/components/alexa/state_report.py @@ -97,12 +97,15 @@ async def async_send_changereport_message( _LOGGER.debug("Sent: %s", json.dumps(message_serialized)) _LOGGER.debug("Received (%s): %s", response.status, response_text) - if response.status == 202 and not invalidate_access_token: + if response.status == 202: return response_json = json.loads(response_text) - if response_json["payload"]["code"] == "INVALID_ACCESS_TOKEN_EXCEPTION": + if ( + response_json["payload"]["code"] == "INVALID_ACCESS_TOKEN_EXCEPTION" + and not invalidate_access_token + ): config.async_invalidate_access_token() return await async_send_changereport_message( hass, config, alexa_entity, invalidate_access_token=False diff --git a/homeassistant/components/deconz/.translations/en.json b/homeassistant/components/deconz/.translations/en.json index 57da3c706a0..3c6656d6ae6 100644 --- a/homeassistant/components/deconz/.translations/en.json +++ b/homeassistant/components/deconz/.translations/en.json @@ -43,7 +43,7 @@ }, "options": { "step": { - "async_step_deconz_devices": { + "deconz_devices": { "data": { "allow_clip_sensor": "Allow deCONZ CLIP sensors", "allow_deconz_groups": "Allow deCONZ light groups" diff --git a/homeassistant/components/deconz/strings.json b/homeassistant/components/deconz/strings.json index ea9ea280515..7081f816e6a 100644 --- a/homeassistant/components/deconz/strings.json +++ b/homeassistant/components/deconz/strings.json @@ -43,7 +43,7 @@ }, "options": { "step": { - "async_step_deconz_devices": { + "deconz_devices": { "description": "Configure visibility of deCONZ device types", "data": { "allow_clip_sensor": "Allow deCONZ CLIP sensors", diff --git a/homeassistant/components/harmony/manifest.json b/homeassistant/components/harmony/manifest.json index b2f9e69e014..a957db0675f 100644 --- a/homeassistant/components/harmony/manifest.json +++ b/homeassistant/components/harmony/manifest.json @@ -3,7 +3,7 @@ "name": "Harmony", "documentation": "https://www.home-assistant.io/components/harmony", "requirements": [ - "aioharmony==0.1.11" + "aioharmony==0.1.13" ], "dependencies": [], "codeowners": [ diff --git a/homeassistant/components/isy994/manifest.json b/homeassistant/components/isy994/manifest.json index 7860c080b2f..0dd0f1eae80 100644 --- a/homeassistant/components/isy994/manifest.json +++ b/homeassistant/components/isy994/manifest.json @@ -3,7 +3,7 @@ "name": "Isy994", "documentation": "https://www.home-assistant.io/components/isy994", "requirements": [ - "PyISY==1.1.1" + "PyISY==1.1.2" ], "dependencies": [], "codeowners": [] diff --git a/homeassistant/components/met/.translations/en.json b/homeassistant/components/met/.translations/en.json index 21ae7cb78fa..93d028b0626 100644 --- a/homeassistant/components/met/.translations/en.json +++ b/homeassistant/components/met/.translations/en.json @@ -1,7 +1,7 @@ { "config": { "error": { - "name_exists": "Name already exists" + "name_exists": "Location already exists" }, "step": { "user": { diff --git a/homeassistant/components/met/config_flow.py b/homeassistant/components/met/config_flow.py index 795ba57d988..c7ff4973c7d 100644 --- a/homeassistant/components/met/config_flow.py +++ b/homeassistant/components/met/config_flow.py @@ -12,9 +12,15 @@ from .const import DOMAIN, HOME_LOCATION_NAME, CONF_TRACK_HOME @callback def configured_instances(hass): """Return a set of configured SimpliSafe instances.""" - return set( - entry.data[CONF_NAME] for entry in hass.config_entries.async_entries(DOMAIN) - ) + entites = [] + for entry in hass.config_entries.async_entries(DOMAIN): + if entry.data.get("track_home"): + entites.append("home") + continue + entites.append( + f"{entry.data.get(CONF_LATITUDE)}-{entry.data.get(CONF_LONGITUDE)}" + ) + return set(entites) class MetFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): @@ -32,11 +38,13 @@ class MetFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): self._errors = {} if user_input is not None: - if user_input[CONF_NAME] not in configured_instances(self.hass): + if ( + f"{user_input.get(CONF_LATITUDE)}-{user_input.get(CONF_LONGITUDE)}" + not in configured_instances(self.hass) + ): return self.async_create_entry( title=user_input[CONF_NAME], data=user_input ) - self._errors[CONF_NAME] = "name_exists" return await self._show_config_form( diff --git a/homeassistant/components/met/strings.json b/homeassistant/components/met/strings.json index f5c49bac3c4..0c52e624418 100644 --- a/homeassistant/components/met/strings.json +++ b/homeassistant/components/met/strings.json @@ -14,7 +14,7 @@ } }, "error": { - "name_exists": "Name already exists" + "name_exists": "Location already exists" } } } diff --git a/homeassistant/components/sonos/media_player.py b/homeassistant/components/sonos/media_player.py index 86e30621334..70461ad15d2 100644 --- a/homeassistant/components/sonos/media_player.py +++ b/homeassistant/components/sonos/media_player.py @@ -337,8 +337,16 @@ class SonosEntity(MediaPlayerDevice): async def async_added_to_hass(self): """Subscribe sonos events.""" await self.async_seen() + self.hass.data[DATA_SONOS].entities.append(self) + def _rebuild_groups(): + """Build the current group topology.""" + for entity in self.hass.data[DATA_SONOS].entities: + entity.update_groups() + + self.hass.async_add_executor_job(_rebuild_groups) + @property def unique_id(self): """Return a unique ID.""" @@ -469,10 +477,6 @@ class SonosEntity(MediaPlayerDevice): self.update_volume() self._set_favorites() - # New player available, build the current group topology - for entity in self.hass.data[DATA_SONOS].entities: - entity.update_groups() - player = self.soco def subscribe(service, action): diff --git a/homeassistant/components/version/manifest.json b/homeassistant/components/version/manifest.json index 2a48f91a6f8..815e7ff9a25 100644 --- a/homeassistant/components/version/manifest.json +++ b/homeassistant/components/version/manifest.json @@ -3,7 +3,7 @@ "name": "Version", "documentation": "https://www.home-assistant.io/components/version", "requirements": [ - "pyhaversion==3.0.2" + "pyhaversion==3.1.0" ], "dependencies": [], "codeowners": [ diff --git a/homeassistant/components/version/sensor.py b/homeassistant/components/version/sensor.py index 438ea8f690c..3e00b87e984 100644 --- a/homeassistant/components/version/sensor.py +++ b/homeassistant/components/version/sensor.py @@ -28,7 +28,7 @@ ALL_IMAGES = [ "odroid-c2", "odroid-xu", ] -ALL_SOURCES = ["local", "pypi", "hassio", "docker"] +ALL_SOURCES = ["local", "pypi", "hassio", "docker", "haio"] CONF_BETA = "beta" CONF_IMAGE = "image" @@ -54,7 +54,13 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the Version sensor platform.""" - from pyhaversion import LocalVersion, DockerVersion, HassioVersion, PyPiVersion + from pyhaversion import ( + LocalVersion, + DockerVersion, + HassioVersion, + PyPiVersion, + HaIoVersion, + ) beta = config.get(CONF_BETA) image = config.get(CONF_IMAGE) @@ -74,6 +80,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= haversion = VersionData(HassioVersion(hass.loop, session, branch, image)) elif source == "docker": haversion = VersionData(DockerVersion(hass.loop, session, branch, image)) + elif source == "haio": + haversion = VersionData(HaIoVersion(hass.loop, session)) else: haversion = VersionData(LocalVersion(hass.loop, session)) diff --git a/homeassistant/components/websocket_api/permissions.py b/homeassistant/components/websocket_api/permissions.py index 7aa845a298d..ffbb80fa19e 100644 --- a/homeassistant/components/websocket_api/permissions.py +++ b/homeassistant/components/websocket_api/permissions.py @@ -8,6 +8,7 @@ from homeassistant.const import ( EVENT_SERVICE_REMOVED, EVENT_STATE_CHANGED, EVENT_THEMES_UPDATED, + EVENT_CORE_CONFIG_UPDATE, ) from homeassistant.components.persistent_notification import ( EVENT_PERSISTENT_NOTIFICATIONS_UPDATED, @@ -22,6 +23,7 @@ from homeassistant.components.frontend import EVENT_PANELS_UPDATED # Except for state_changed, which is handled accordingly. SUBSCRIBE_WHITELIST = { EVENT_COMPONENT_LOADED, + EVENT_CORE_CONFIG_UPDATE, EVENT_PANELS_UPDATED, EVENT_PERSISTENT_NOTIFICATIONS_UPDATED, EVENT_SERVICE_REGISTERED, diff --git a/homeassistant/const.py b/homeassistant/const.py index 6d195da991e..2a20917b3be 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 98 -PATCH_VERSION = "2" +PATCH_VERSION = "3" __short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION) __version__ = "{}.{}".format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 6, 0) diff --git a/requirements_all.txt b/requirements_all.txt index 2bf7e6a841c..3660514e355 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -50,7 +50,7 @@ PyEssent==0.13 PyGithub==1.43.5 # homeassistant.components.isy994 -PyISY==1.1.1 +PyISY==1.1.2 # homeassistant.components.mvglive PyMVGLive==1.1.4 @@ -142,7 +142,7 @@ aiofreepybox==0.0.8 aioftp==0.12.0 # homeassistant.components.harmony -aioharmony==0.1.11 +aioharmony==0.1.13 # homeassistant.components.emulated_hue # homeassistant.components.http @@ -1186,7 +1186,7 @@ pygtfs==0.1.5 pygtt==1.1.2 # homeassistant.components.version -pyhaversion==3.0.2 +pyhaversion==3.1.0 # homeassistant.components.heos pyheos==0.6.0 diff --git a/tests/components/alexa/test_state_report.py b/tests/components/alexa/test_state_report.py index f6bb4c9cc29..2b3f9f34adf 100644 --- a/tests/components/alexa/test_state_report.py +++ b/tests/components/alexa/test_state_report.py @@ -5,7 +5,7 @@ from . import TEST_URL, DEFAULT_CONFIG async def test_report_state(hass, aioclient_mock): """Test proactive state reports.""" - aioclient_mock.post(TEST_URL, json={"data": "is irrelevant"}, status=202) + aioclient_mock.post(TEST_URL, text="", status=202) hass.states.async_set( "binary_sensor.test_contact", @@ -39,7 +39,7 @@ async def test_report_state(hass, aioclient_mock): async def test_send_add_or_update_message(hass, aioclient_mock): """Test sending an AddOrUpdateReport message.""" - aioclient_mock.post(TEST_URL, json={"data": "is irrelevant"}) + aioclient_mock.post(TEST_URL, text="") hass.states.async_set( "binary_sensor.test_contact", diff --git a/tests/components/met/test_config_flow.py b/tests/components/met/test_config_flow.py index 22061386b93..32f3be676e0 100644 --- a/tests/components/met/test_config_flow.py +++ b/tests/components/met/test_config_flow.py @@ -102,7 +102,7 @@ async def test_flow_entry_created_from_user_input(): async def test_flow_entry_config_entry_already_exists(): """Test that create data from user input and config_entry already exists. - Test when the form should show when user puts existing name + Test when the form should show when user puts existing location in the config gui. Then the form should show with error """ hass = Mock() @@ -112,6 +112,8 @@ async def test_flow_entry_config_entry_already_exists(): first_entry = MockConfigEntry(domain="met") first_entry.data["name"] = "home" + first_entry.data[CONF_LONGITUDE] = "0" + first_entry.data[CONF_LATITUDE] = "0" first_entry.add_to_hass(hass) test_data = {