From 9b3c3232be59e5eeff34a4c7ccd41da71bb65968 Mon Sep 17 00:00:00 2001 From: kevdliu <1766838+kevdliu@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:17:40 -0400 Subject: [PATCH 01/10] Revert "Take Abode camera snapshot before fetching latest image" (#68626) --- homeassistant/components/abode/camera.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/components/abode/camera.py b/homeassistant/components/abode/camera.py index 1eb6f859d0c..9885ccb54ef 100644 --- a/homeassistant/components/abode/camera.py +++ b/homeassistant/components/abode/camera.py @@ -88,8 +88,6 @@ class AbodeCamera(AbodeDevice, Camera): self, width: int | None = None, height: int | None = None ) -> bytes | None: """Get a camera image.""" - if not self.capture(): - return None self.refresh_image() if self._response: From d5e80ed2a54a7a8680b5b7a3ec5da5fab1c9bb09 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 26 Mar 2022 01:07:24 -1000 Subject: [PATCH 02/10] Fix screenlogic to get the macaddress from discovery (#68687) --- homeassistant/components/screenlogic/config_flow.py | 2 +- homeassistant/components/screenlogic/manifest.json | 2 +- homeassistant/generated/dhcp.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/screenlogic/config_flow.py b/homeassistant/components/screenlogic/config_flow.py index d9feec629e2..260317dca11 100644 --- a/homeassistant/components/screenlogic/config_flow.py +++ b/homeassistant/components/screenlogic/config_flow.py @@ -79,7 +79,7 @@ class ScreenlogicConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult: """Handle dhcp discovery.""" - mac = _extract_mac_from_name(discovery_info.hostname) + mac = format_mac(discovery_info.macaddress) await self.async_set_unique_id(mac) self._abort_if_unique_id_configured( updates={CONF_IP_ADDRESS: discovery_info.ip} diff --git a/homeassistant/components/screenlogic/manifest.json b/homeassistant/components/screenlogic/manifest.json index 98129e24f01..32ec1872877 100644 --- a/homeassistant/components/screenlogic/manifest.json +++ b/homeassistant/components/screenlogic/manifest.json @@ -8,7 +8,7 @@ "dhcp": [ {"registered_devices": true}, { - "hostname": "pentair: *", + "hostname": "pentair*", "macaddress": "00C033*" } ], diff --git a/homeassistant/generated/dhcp.py b/homeassistant/generated/dhcp.py index 8633534e976..db5bc2f8127 100644 --- a/homeassistant/generated/dhcp.py +++ b/homeassistant/generated/dhcp.py @@ -81,7 +81,7 @@ DHCP: list[dict[str, str | bool]] = [ {'domain': 'samsungtv', 'macaddress': '4844F7*'}, {'domain': 'samsungtv', 'macaddress': '8CEA48*'}, {'domain': 'screenlogic', 'registered_devices': True}, - {'domain': 'screenlogic', 'hostname': 'pentair: *', 'macaddress': '00C033*'}, + {'domain': 'screenlogic', 'hostname': 'pentair*', 'macaddress': '00C033*'}, {'domain': 'sense', 'hostname': 'sense-*', 'macaddress': '009D6B*'}, {'domain': 'sense', 'hostname': 'sense-*', 'macaddress': 'DCEFCA*'}, {'domain': 'sense', 'hostname': 'sense-*', 'macaddress': 'A4D578*'}, From 45638c78ae162254d501843850b34e0c2d5ad365 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 26 Mar 2022 02:15:47 -1000 Subject: [PATCH 03/10] Ensure solaredge can still be setup with an ignored entry (#68688) --- .../components/solaredge/config_flow.py | 22 +++++++-------- .../components/solaredge/test_config_flow.py | 27 ++++++++++++++++++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/solaredge/config_flow.py b/homeassistant/components/solaredge/config_flow.py index 523c75116e9..58e5577ccfa 100644 --- a/homeassistant/components/solaredge/config_flow.py +++ b/homeassistant/components/solaredge/config_flow.py @@ -9,22 +9,13 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_API_KEY, CONF_NAME -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult from homeassistant.util import slugify from .const import CONF_SITE_ID, DEFAULT_NAME, DOMAIN -@callback -def solaredge_entries(hass: HomeAssistant): - """Return the site_ids for the domain.""" - return { - (entry.data[CONF_SITE_ID]) - for entry in hass.config_entries.async_entries(DOMAIN) - } - - class SolarEdgeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow.""" @@ -34,9 +25,18 @@ class SolarEdgeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Initialize the config flow.""" self._errors = {} + @callback + def _async_current_site_ids(self) -> set[str]: + """Return the site_ids for the domain.""" + return { + entry.data[CONF_SITE_ID] + for entry in self._async_current_entries(include_ignore=False) + if CONF_SITE_ID in entry.data + } + def _site_in_configuration_exists(self, site_id: str) -> bool: """Return True if site_id exists in configuration.""" - return site_id in solaredge_entries(self.hass) + return site_id in self._async_current_site_ids() def _check_site(self, site_id: str, api_key: str) -> bool: """Check if we can connect to the soleredge api service.""" diff --git a/tests/components/solaredge/test_config_flow.py b/tests/components/solaredge/test_config_flow.py index 059e10c7662..d0f0ac01235 100644 --- a/tests/components/solaredge/test_config_flow.py +++ b/tests/components/solaredge/test_config_flow.py @@ -6,7 +6,7 @@ from requests.exceptions import ConnectTimeout, HTTPError from homeassistant import data_entry_flow from homeassistant.components.solaredge.const import CONF_SITE_ID, DEFAULT_NAME, DOMAIN -from homeassistant.config_entries import SOURCE_USER +from homeassistant.config_entries import SOURCE_IGNORE, SOURCE_USER from homeassistant.const import CONF_API_KEY, CONF_NAME from homeassistant.core import HomeAssistant @@ -66,6 +66,31 @@ async def test_abort_if_already_setup(hass: HomeAssistant, test_api: str) -> Non assert result.get("errors") == {CONF_SITE_ID: "already_configured"} +async def test_ignored_entry_does_not_cause_error( + hass: HomeAssistant, test_api: str +) -> None: + """Test an ignored entry does not cause and error and we can still create an new entry.""" + MockConfigEntry( + domain="solaredge", + data={CONF_NAME: DEFAULT_NAME, CONF_API_KEY: API_KEY}, + source=SOURCE_IGNORE, + ).add_to_hass(hass) + + # user: Should fail, same SITE_ID + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_NAME: "test", CONF_SITE_ID: SITE_ID, CONF_API_KEY: "test"}, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result["title"] == "test" + + data = result["data"] + assert data + assert data[CONF_SITE_ID] == SITE_ID + assert data[CONF_API_KEY] == "test" + + async def test_asserts(hass: HomeAssistant, test_api: Mock) -> None: """Test the _site_in_configuration_exists method.""" From 112732c6734e56876a3cfd46fb946a3b9a51267d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 28 Mar 2022 21:10:49 -1000 Subject: [PATCH 04/10] Add option to connect to elkm1 non-secure when secure is discovered (#68735) Co-authored-by: Glenn Waters --- homeassistant/components/elkm1/config_flow.py | 42 +++-- homeassistant/components/elkm1/strings.json | 2 + .../components/elkm1/translations/en.json | 12 +- tests/components/elkm1/__init__.py | 1 + tests/components/elkm1/test_config_flow.py | 166 ++++++++++++++++-- 5 files changed, 190 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/elkm1/config_flow.py b/homeassistant/components/elkm1/config_flow.py index d68fce268a2..865f9d2323f 100644 --- a/homeassistant/components/elkm1/config_flow.py +++ b/homeassistant/components/elkm1/config_flow.py @@ -37,7 +37,9 @@ from .discovery import ( CONF_DEVICE = "device" +NON_SECURE_PORT = 2101 SECURE_PORT = 2601 +STANDARD_PORTS = {NON_SECURE_PORT, SECURE_PORT} _LOGGER = logging.getLogger(__name__) @@ -48,6 +50,7 @@ PROTOCOL_MAP = { "serial": "serial://", } + VALIDATE_TIMEOUT = 35 BASE_SCHEMA = { @@ -60,6 +63,11 @@ ALL_PROTOCOLS = [*SECURE_PROTOCOLS, "non-secure", "serial"] DEFAULT_SECURE_PROTOCOL = "secure" DEFAULT_NON_SECURE_PROTOCOL = "non-secure" +PORT_PROTOCOL_MAP = { + NON_SECURE_PORT: DEFAULT_NON_SECURE_PROTOCOL, + SECURE_PORT: DEFAULT_SECURE_PROTOCOL, +} + async def validate_input(data: dict[str, str], mac: str | None) -> dict[str, str]: """Validate the user input allows us to connect. @@ -97,6 +105,13 @@ async def validate_input(data: dict[str, str], mac: str | None) -> dict[str, str return {"title": device_name, CONF_HOST: url, CONF_PREFIX: slugify(prefix)} +def _address_from_discovery(device: ElkSystem): + """Append the port only if its non-standard.""" + if device.port in STANDARD_PORTS: + return device.ip_address + return f"{device.ip_address}:{device.port}" + + def _make_url_from_data(data): if host := data.get(CONF_HOST): return host @@ -109,7 +124,7 @@ def _make_url_from_data(data): def _placeholders_from_device(device: ElkSystem) -> dict[str, str]: return { "mac_address": _short_mac(device.mac_address), - "host": f"{device.ip_address}:{device.port}", + "host": _address_from_discovery(device), } @@ -255,26 +270,26 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): device = self._discovered_device assert device is not None if user_input is not None: - user_input[CONF_ADDRESS] = f"{device.ip_address}:{device.port}" + user_input[CONF_ADDRESS] = _address_from_discovery(device) if self._async_current_entries(): user_input[CONF_PREFIX] = _short_mac(device.mac_address) else: user_input[CONF_PREFIX] = "" - if device.port != SECURE_PORT: - user_input[CONF_PROTOCOL] = DEFAULT_NON_SECURE_PROTOCOL errors, result = await self._async_create_or_error(user_input, False) if not errors: return result - base_schmea = BASE_SCHEMA.copy() - if device.port == SECURE_PORT: - base_schmea[ - vol.Required(CONF_PROTOCOL, default=DEFAULT_SECURE_PROTOCOL) - ] = vol.In(SECURE_PROTOCOLS) - + default_proto = PORT_PROTOCOL_MAP.get(device.port, DEFAULT_SECURE_PROTOCOL) return self.async_show_form( step_id="discovered_connection", - data_schema=vol.Schema(base_schmea), + data_schema=vol.Schema( + { + **BASE_SCHEMA, + vol.Required(CONF_PROTOCOL, default=default_proto): vol.In( + ALL_PROTOCOLS + ), + } + ), errors=errors, description_placeholders=_placeholders_from_device(device), ) @@ -334,7 +349,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) self._abort_if_unique_id_configured() - return (await self._async_create_or_error(user_input, True))[1] + errors, result = await self._async_create_or_error(user_input, True) + if errors: + return self.async_abort(reason=list(errors.values())[0]) + return result def _url_already_configured(self, url): """See if we already have a elkm1 matching user input configured.""" diff --git a/homeassistant/components/elkm1/strings.json b/homeassistant/components/elkm1/strings.json index 35672d5df80..d1871c7536c 100644 --- a/homeassistant/components/elkm1/strings.json +++ b/homeassistant/components/elkm1/strings.json @@ -38,6 +38,8 @@ "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { + "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", + "unknown": "[%key:common::config_flow::error::unknown%]", "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "already_configured": "An ElkM1 with this prefix is already configured", diff --git a/homeassistant/components/elkm1/translations/en.json b/homeassistant/components/elkm1/translations/en.json index 3b1993f3fed..0206859cf8e 100644 --- a/homeassistant/components/elkm1/translations/en.json +++ b/homeassistant/components/elkm1/translations/en.json @@ -4,7 +4,9 @@ "address_already_configured": "An ElkM1 with this address is already configured", "already_configured": "An ElkM1 with this prefix is already configured", "already_in_progress": "Configuration flow is already in progress", - "cannot_connect": "Failed to connect" + "cannot_connect": "Failed to connect", + "invalid_auth": "Invalid authentication", + "unknown": "Unexpected error" }, "error": { "cannot_connect": "Failed to connect", @@ -37,13 +39,7 @@ }, "user": { "data": { - "address": "The IP address or domain or serial port if connecting via serial.", - "device": "Device", - "password": "Password", - "prefix": "A unique prefix (leave blank if you only have one ElkM1).", - "protocol": "Protocol", - "temperature_unit": "The temperature unit ElkM1 uses.", - "username": "Username" + "device": "Device" }, "description": "Choose a discovered system or 'Manual Entry' if no devices have been discovered.", "title": "Connect to Elk-M1 Control" diff --git a/tests/components/elkm1/__init__.py b/tests/components/elkm1/__init__.py index 128d0a0d777..29cd2aa297d 100644 --- a/tests/components/elkm1/__init__.py +++ b/tests/components/elkm1/__init__.py @@ -9,6 +9,7 @@ MOCK_IP_ADDRESS = "127.0.0.1" MOCK_MAC = "aa:bb:cc:dd:ee:ff" ELK_DISCOVERY = ElkSystem(MOCK_MAC, MOCK_IP_ADDRESS, 2601) ELK_NON_SECURE_DISCOVERY = ElkSystem(MOCK_MAC, MOCK_IP_ADDRESS, 2101) +ELK_DISCOVERY_NON_STANDARD_PORT = ElkSystem(MOCK_MAC, MOCK_IP_ADDRESS, 444) def mock_elk(invalid_auth=None, sync_complete=None, exception=None): diff --git a/tests/components/elkm1/test_config_flow.py b/tests/components/elkm1/test_config_flow.py index 183ab90086c..8334d8b5825 100644 --- a/tests/components/elkm1/test_config_flow.py +++ b/tests/components/elkm1/test_config_flow.py @@ -12,6 +12,7 @@ from homeassistant.data_entry_flow import RESULT_TYPE_ABORT, RESULT_TYPE_FORM from . import ( ELK_DISCOVERY, + ELK_DISCOVERY_NON_STANDARD_PORT, ELK_NON_SECURE_DISCOVERY, MOCK_IP_ADDRESS, MOCK_MAC, @@ -24,6 +25,8 @@ from tests.common import MockConfigEntry DHCP_DISCOVERY = dhcp.DhcpServiceInfo(MOCK_IP_ADDRESS, "", MOCK_MAC) ELK_DISCOVERY_INFO = asdict(ELK_DISCOVERY) +ELK_DISCOVERY_INFO_NON_STANDARD_PORT = asdict(ELK_DISCOVERY_NON_STANDARD_PORT) + MODULE = "homeassistant.components.elkm1" @@ -301,7 +304,7 @@ async def test_form_user_with_secure_elk_with_discovery(hass): assert result3["title"] == "ElkM1 ddeeff" assert result3["data"] == { "auto_configure": True, - "host": "elks://127.0.0.1:2601", + "host": "elks://127.0.0.1", "password": "test-password", "prefix": "", "username": "test-username", @@ -801,6 +804,102 @@ async def test_form_import_device_discovered(hass): assert len(mock_setup_entry.mock_calls) == 1 +async def test_form_import_non_secure_device_discovered(hass): + """Test we can import non-secure with discovery.""" + + mocked_elk = mock_elk(invalid_auth=False, sync_complete=True) + with _patch_discovery(), _patch_elk(elk=mocked_elk), patch( + "homeassistant.components.elkm1.async_setup", return_value=True + ) as mock_setup, patch( + "homeassistant.components.elkm1.async_setup_entry", + return_value=True, + ) as mock_setup_entry: + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_IMPORT}, + data={ + "host": "elk://127.0.0.1:2101", + "username": "", + "password": "", + "auto_configure": True, + "prefix": "ohana", + }, + ) + await hass.async_block_till_done() + + assert result["type"] == "create_entry" + assert result["title"] == "ohana" + assert result["result"].unique_id == MOCK_MAC + assert result["data"] == { + "auto_configure": True, + "host": "elk://127.0.0.1:2101", + "password": "", + "prefix": "ohana", + "username": "", + } + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 + + +async def test_form_import_non_secure_non_stanadard_port_device_discovered(hass): + """Test we can import non-secure non standard port with discovery.""" + + mocked_elk = mock_elk(invalid_auth=False, sync_complete=True) + with _patch_discovery(), _patch_elk(elk=mocked_elk), patch( + "homeassistant.components.elkm1.async_setup", return_value=True + ) as mock_setup, patch( + "homeassistant.components.elkm1.async_setup_entry", + return_value=True, + ) as mock_setup_entry: + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_IMPORT}, + data={ + "host": "elk://127.0.0.1:444", + "username": "", + "password": "", + "auto_configure": True, + "prefix": "ohana", + }, + ) + await hass.async_block_till_done() + + assert result["type"] == "create_entry" + assert result["title"] == "ohana" + assert result["result"].unique_id == MOCK_MAC + assert result["data"] == { + "auto_configure": True, + "host": "elk://127.0.0.1:444", + "password": "", + "prefix": "ohana", + "username": "", + } + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 + + +async def test_form_import_non_secure_device_discovered_invalid_auth(hass): + """Test we abort import with invalid auth.""" + + mocked_elk = mock_elk(invalid_auth=True, sync_complete=False) + with _patch_discovery(), _patch_elk(elk=mocked_elk): + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_IMPORT}, + data={ + "host": "elks://127.0.0.1", + "username": "invalid", + "password": "", + "auto_configure": False, + "prefix": "ohana", + }, + ) + await hass.async_block_till_done() + + assert result["type"] == "abort" + assert result["reason"] == "invalid_auth" + + async def test_form_import_existing(hass): """Test we abort on existing import.""" config_entry = MockConfigEntry( @@ -978,7 +1077,52 @@ async def test_discovered_by_discovery(hass): assert result2["title"] == "ElkM1 ddeeff" assert result2["data"] == { "auto_configure": True, - "host": "elks://127.0.0.1:2601", + "host": "elks://127.0.0.1", + "password": "test-password", + "prefix": "", + "username": "test-username", + } + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 + + +async def test_discovered_by_discovery_non_standard_port(hass): + """Test we can setup when discovered from discovery with a non-standard port.""" + + with _patch_discovery(), _patch_elk(): + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_INTEGRATION_DISCOVERY}, + data=ELK_DISCOVERY_INFO_NON_STANDARD_PORT, + ) + await hass.async_block_till_done() + + assert result["type"] == RESULT_TYPE_FORM + assert result["step_id"] == "discovered_connection" + assert result["errors"] == {} + + mocked_elk = mock_elk(invalid_auth=False, sync_complete=True) + + with _patch_discovery(), _patch_elk(elk=mocked_elk), patch( + "homeassistant.components.elkm1.async_setup", return_value=True + ) as mock_setup, patch( + "homeassistant.components.elkm1.async_setup_entry", + return_value=True, + ) as mock_setup_entry: + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + "username": "test-username", + "password": "test-password", + }, + ) + await hass.async_block_till_done() + + assert result2["type"] == "create_entry" + assert result2["title"] == "ElkM1 ddeeff" + assert result2["data"] == { + "auto_configure": True, + "host": "elks://127.0.0.1:444", "password": "test-password", "prefix": "", "username": "test-username", @@ -1042,7 +1186,7 @@ async def test_discovered_by_dhcp_udp_responds(hass): assert result2["title"] == "ElkM1 ddeeff" assert result2["data"] == { "auto_configure": True, - "host": "elks://127.0.0.1:2601", + "host": "elks://127.0.0.1", "password": "test-password", "prefix": "", "username": "test-username", @@ -1077,8 +1221,7 @@ async def test_discovered_by_dhcp_udp_responds_with_nonsecure_port(hass): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { - "username": "test-username", - "password": "test-password", + "protocol": "non-secure", }, ) await hass.async_block_till_done() @@ -1087,10 +1230,10 @@ async def test_discovered_by_dhcp_udp_responds_with_nonsecure_port(hass): assert result2["title"] == "ElkM1 ddeeff" assert result2["data"] == { "auto_configure": True, - "host": "elk://127.0.0.1:2101", - "password": "test-password", + "host": "elk://127.0.0.1", + "password": "", "prefix": "", - "username": "test-username", + "username": "", } assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 @@ -1125,10 +1268,7 @@ async def test_discovered_by_dhcp_udp_responds_existing_config_entry(hass): ) as mock_setup_entry: result2 = await hass.config_entries.flow.async_configure( result["flow_id"], - { - "username": "test-username", - "password": "test-password", - }, + {"username": "test-username", "password": "test-password"}, ) await hass.async_block_till_done() @@ -1136,7 +1276,7 @@ async def test_discovered_by_dhcp_udp_responds_existing_config_entry(hass): assert result2["title"] == "ElkM1 ddeeff" assert result2["data"] == { "auto_configure": True, - "host": "elks://127.0.0.1:2601", + "host": "elks://127.0.0.1", "password": "test-password", "prefix": "ddeeff", "username": "test-username", From d1a6eb55b1de448e2a4c23ba3dde327a092e6064 Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Sun, 27 Mar 2022 12:29:59 +0200 Subject: [PATCH 05/10] Increase zwave_js add-on start attempts before timeout (#68736) --- homeassistant/components/zwave_js/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index 32f406d7476..60b13e135de 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -51,7 +51,7 @@ DEFAULT_URL = "ws://localhost:3000" TITLE = "Z-Wave JS" ADDON_SETUP_TIMEOUT = 5 -ADDON_SETUP_TIMEOUT_ROUNDS = 4 +ADDON_SETUP_TIMEOUT_ROUNDS = 40 CONF_EMULATE_HARDWARE = "emulate_hardware" CONF_LOG_LEVEL = "log_level" SERVER_VERSION_TIMEOUT = 10 From 9acd1471a072a88c52f515cbd913e85aac1cddd2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 27 Mar 2022 23:05:50 -1000 Subject: [PATCH 06/10] Fix ignoring elkm1 discovery (#68750) --- homeassistant/components/elkm1/config_flow.py | 3 +++ tests/components/elkm1/test_config_flow.py | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/homeassistant/components/elkm1/config_flow.py b/homeassistant/components/elkm1/config_flow.py index 865f9d2323f..e4f6dc7f083 100644 --- a/homeassistant/components/elkm1/config_flow.py +++ b/homeassistant/components/elkm1/config_flow.py @@ -181,6 +181,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): for progress in self._async_in_progress(): if progress.get("context", {}).get(CONF_HOST) == host: return self.async_abort(reason="already_in_progress") + # Handled ignored case since _async_current_entries + # is called with include_ignore=False + self._abort_if_unique_id_configured() if not device.port: if discovered_device := await async_discover_device(self.hass, host): self._discovered_device = discovered_device diff --git a/tests/components/elkm1/test_config_flow.py b/tests/components/elkm1/test_config_flow.py index 8334d8b5825..b8f9e51b6fc 100644 --- a/tests/components/elkm1/test_config_flow.py +++ b/tests/components/elkm1/test_config_flow.py @@ -30,6 +30,27 @@ ELK_DISCOVERY_INFO_NON_STANDARD_PORT = asdict(ELK_DISCOVERY_NON_STANDARD_PORT) MODULE = "homeassistant.components.elkm1" +async def test_discovery_ignored_entry(hass): + """Test we abort on ignored entry.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + data={CONF_HOST: f"elks://{MOCK_IP_ADDRESS}"}, + unique_id="aa:bb:cc:dd:ee:ff", + source=config_entries.SOURCE_IGNORE, + ) + config_entry.add_to_hass(hass) + + with _patch_discovery(), _patch_elk(): + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_INTEGRATION_DISCOVERY}, + data=ELK_DISCOVERY_INFO, + ) + await hass.async_block_till_done() + assert result["type"] == RESULT_TYPE_ABORT + assert result["reason"] == "already_configured" + + async def test_form_user_with_secure_elk_no_discovery(hass): """Test we can setup a secure elk.""" From fe36ff5fa93e912d02c1b81032214e1e913d55b2 Mon Sep 17 00:00:00 2001 From: Keilin Bickar Date: Tue, 29 Mar 2022 03:08:40 -0400 Subject: [PATCH 07/10] Update sense library to 0.10.4 (#68816) --- homeassistant/components/emulated_kasa/manifest.json | 2 +- homeassistant/components/sense/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/emulated_kasa/manifest.json b/homeassistant/components/emulated_kasa/manifest.json index c7f9175bc5e..31319a656cd 100644 --- a/homeassistant/components/emulated_kasa/manifest.json +++ b/homeassistant/components/emulated_kasa/manifest.json @@ -2,7 +2,7 @@ "domain": "emulated_kasa", "name": "Emulated Kasa", "documentation": "https://www.home-assistant.io/integrations/emulated_kasa", - "requirements": ["sense_energy==0.10.3"], + "requirements": ["sense_energy==0.10.4"], "codeowners": ["@kbickar"], "quality_scale": "internal", "iot_class": "local_push", diff --git a/homeassistant/components/sense/manifest.json b/homeassistant/components/sense/manifest.json index 04b0b451db4..192a0f6defe 100644 --- a/homeassistant/components/sense/manifest.json +++ b/homeassistant/components/sense/manifest.json @@ -2,7 +2,7 @@ "domain": "sense", "name": "Sense", "documentation": "https://www.home-assistant.io/integrations/sense", - "requirements": ["sense_energy==0.10.3"], + "requirements": ["sense_energy==0.10.4"], "codeowners": ["@kbickar"], "config_flow": true, "dhcp": [ diff --git a/requirements_all.txt b/requirements_all.txt index a5e7ea3852d..9351749148f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2179,7 +2179,7 @@ sense-hat==2.2.0 # homeassistant.components.emulated_kasa # homeassistant.components.sense -sense_energy==0.10.3 +sense_energy==0.10.4 # homeassistant.components.sentry sentry-sdk==1.5.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3d4c200d682..1a02fe43828 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1344,7 +1344,7 @@ screenlogicpy==0.5.4 # homeassistant.components.emulated_kasa # homeassistant.components.sense -sense_energy==0.10.3 +sense_energy==0.10.4 # homeassistant.components.sentry sentry-sdk==1.5.5 From 4041dd61c502202e2fb5b42d2efdd66a2bc25939 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 29 Mar 2022 00:11:29 -0700 Subject: [PATCH 08/10] Bumped version to 2022.3.8 --- homeassistant/const.py | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 1d123a851b7..e7adb5e18f8 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -7,7 +7,7 @@ from .backports.enum import StrEnum MAJOR_VERSION: Final = 2022 MINOR_VERSION: Final = 3 -PATCH_VERSION: Final = "7" +PATCH_VERSION: Final = "8" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0) diff --git a/setup.cfg b/setup.cfg index c08f865b17a..970a06fcab8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = homeassistant -version = 2022.3.7 +version = 2022.3.8 author = The Home Assistant Authors author_email = hello@home-assistant.io license = Apache-2.0 From 99c0ef9ab879c3dc45547c24b9dff21d3a48af14 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 29 Mar 2022 00:07:29 +0200 Subject: [PATCH 09/10] Pin click to fix typer issue (#68808) Co-authored-by: epenet --- homeassistant/package_constraints.txt | 4 ++++ script/gen_requirements_all.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 8ec6f3cc67d..ffc4f7da828 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -99,3 +99,7 @@ multidict>=6.0.2 # Required for compatibility with point integration - ensure_active_token # https://github.com/home-assistant/core/pull/68176 authlib<1.0 + +# Required for compatibility with typer, used by pyunifiprotect integration +# https://github.com/tiangolo/typer/pull/375 +click<=8.0.4" diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index a8d1d40a7d5..d5d67643b0d 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -128,6 +128,10 @@ multidict>=6.0.2 # Required for compatibility with point integration - ensure_active_token # https://github.com/home-assistant/core/pull/68176 authlib<1.0 + +# Required for compatibility with typer, used by pyunifiprotect integration +# https://github.com/tiangolo/typer/pull/375 +click<=8.0.4" """ IGNORE_PRE_COMMIT_HOOK_ID = ( From 826423d8ed428059fca5701a5c292c8a6287d53f Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 29 Mar 2022 11:44:19 +0200 Subject: [PATCH 10/10] Cleanup package constraints (#68833) Co-authored-by: epenet --- homeassistant/package_constraints.txt | 2 +- script/gen_requirements_all.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index ffc4f7da828..7db411585ef 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -102,4 +102,4 @@ authlib<1.0 # Required for compatibility with typer, used by pyunifiprotect integration # https://github.com/tiangolo/typer/pull/375 -click<=8.0.4" +click<=8.0.4 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index d5d67643b0d..5b61938a209 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -131,7 +131,7 @@ authlib<1.0 # Required for compatibility with typer, used by pyunifiprotect integration # https://github.com/tiangolo/typer/pull/375 -click<=8.0.4" +click<=8.0.4 """ IGNORE_PRE_COMMIT_HOOK_ID = (