From 990ecbba72243323ab9b197677c18911bb3213eb Mon Sep 17 00:00:00 2001 From: Jan Stienstra <65826735+j-stienstra@users.noreply.github.com> Date: Sun, 12 Mar 2023 19:31:10 +0100 Subject: [PATCH 01/40] Recode Home Assistant instance name to ascii for Jellyfin (#87368) Recode instance name to ascii --- homeassistant/components/jellyfin/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/jellyfin/__init__.py b/homeassistant/components/jellyfin/__init__.py index 39085317a54..95038d54f53 100644 --- a/homeassistant/components/jellyfin/__init__.py +++ b/homeassistant/components/jellyfin/__init__.py @@ -20,10 +20,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry_data[CONF_CLIENT_DEVICE_ID] = entry.entry_id hass.config_entries.async_update_entry(entry, data=entry_data) - client = create_client( - device_id=entry.data[CONF_CLIENT_DEVICE_ID], - device_name=hass.config.location_name, - ) + device_id = entry.data[CONF_CLIENT_DEVICE_ID] + device_name = ascii(hass.config.location_name) + + client = create_client(device_id=device_id, device_name=device_name) try: user_id, connect_result = await validate_input(hass, dict(entry.data), client) From 6ebd493c4d98b8a1462d277f2edf8f58b90cb9ce Mon Sep 17 00:00:00 2001 From: Arjan <44190435+vingerha@users.noreply.github.com> Date: Mon, 13 Mar 2023 11:57:49 +0100 Subject: [PATCH 02/40] Fix gtfs with 2023.3 (sqlachemy update) (#89175) --- homeassistant/components/gtfs/sensor.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/gtfs/sensor.py b/homeassistant/components/gtfs/sensor.py index 3a79d8d88a9..6cf1a6d4604 100644 --- a/homeassistant/components/gtfs/sensor.py +++ b/homeassistant/components/gtfs/sensor.py @@ -342,12 +342,14 @@ def get_next_departure( origin_stop_time.departure_time LIMIT :limit """ - result = schedule.engine.execute( + result = schedule.engine.connect().execute( text(sql_query), - origin_station_id=start_station_id, - end_station_id=end_station_id, - today=now_date, - limit=limit, + { + "origin_station_id": start_station_id, + "end_station_id": end_station_id, + "today": now_date, + "limit": limit, + }, ) # Create lookup timetable for today and possibly tomorrow, taking into @@ -357,7 +359,8 @@ def get_next_departure( yesterday_start = today_start = tomorrow_start = None yesterday_last = today_last = "" - for row in result: + for row_cursor in result: + row = row_cursor._asdict() if row["yesterday"] == 1 and yesterday_date >= row["start_date"]: extras = {"day": "yesterday", "first": None, "last": False} if yesterday_start is None: @@ -800,7 +803,10 @@ class GTFSDepartureSensor(SensorEntity): @staticmethod def dict_for_table(resource: Any) -> dict: """Return a dictionary for the SQLAlchemy resource given.""" - return {col: getattr(resource, col) for col in resource.__table__.columns} + _dict = {} + for column in resource.__table__.columns: + _dict[column.name] = str(getattr(resource, column.name)) + return _dict def append_keys(self, resource: dict, prefix: str | None = None) -> None: """Properly format key val pairs to append to attributes.""" From 8c2569d2cebee3fc794a87ac7bc30fa361274c5b Mon Sep 17 00:00:00 2001 From: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com> Date: Sat, 11 Mar 2023 14:27:33 -0500 Subject: [PATCH 03/40] Reconnect on any ScreenLogic exception (#89269) Co-authored-by: J. Nick Koston --- homeassistant/components/screenlogic/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/screenlogic/__init__.py b/homeassistant/components/screenlogic/__init__.py index fad4dc6509b..ad2f9c64f3e 100644 --- a/homeassistant/components/screenlogic/__init__.py +++ b/homeassistant/components/screenlogic/__init__.py @@ -159,11 +159,9 @@ class ScreenlogicDataUpdateCoordinator(DataUpdateCoordinator): """Fetch data from the Screenlogic gateway.""" try: await self._async_update_configured_data() - except ScreenLogicError as error: - _LOGGER.warning("Update error - attempting reconnect: %s", error) + except (ScreenLogicError, ScreenLogicWarning) as ex: + _LOGGER.warning("Update error - attempting reconnect: %s", ex) await self._async_reconnect_update_data() - except ScreenLogicWarning as warn: - raise UpdateFailed(f"Incomplete update: {warn}") from warn return None From 7cb462067106ddd914abaf57018c72b1a1930098 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 9 Mar 2023 16:03:41 -1000 Subject: [PATCH 04/40] Fix data migration never finishing when database has invalid datetimes (#89474) * Fix data migration never finishing when database has invalid datetimes If there were impossible datetime values in the database (likely from a manual sqlite to MySQL conversion) the conversion would never complete * Update homeassistant/components/recorder/migration.py --- homeassistant/components/recorder/migration.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/recorder/migration.py b/homeassistant/components/recorder/migration.py index 0b8fe9243ba..838cb181d07 100644 --- a/homeassistant/components/recorder/migration.py +++ b/homeassistant/components/recorder/migration.py @@ -1072,7 +1072,7 @@ def _migrate_columns_to_timestamp( result = session.connection().execute( text( "UPDATE events set time_fired_ts=" - "IF(time_fired is NULL,0," + "IF(time_fired is NULL or UNIX_TIMESTAMP(time_fired) is NULL,0," "UNIX_TIMESTAMP(time_fired)" ") " "where time_fired_ts is NULL " @@ -1085,7 +1085,7 @@ def _migrate_columns_to_timestamp( result = session.connection().execute( text( "UPDATE states set last_updated_ts=" - "IF(last_updated is NULL,0," + "IF(last_updated is NULL or UNIX_TIMESTAMP(last_updated) is NULL,0," "UNIX_TIMESTAMP(last_updated) " "), " "last_changed_ts=" @@ -1161,7 +1161,7 @@ def _migrate_statistics_columns_to_timestamp( result = session.connection().execute( text( f"UPDATE {table} set start_ts=" - "IF(start is NULL,0," + "IF(start is NULL or UNIX_TIMESTAMP(start) is NULL,0," "UNIX_TIMESTAMP(start) " "), " "created_ts=" From 1e7f58d85947b58c3f0b98b3efdf25ce33c9ea57 Mon Sep 17 00:00:00 2001 From: rappenze Date: Sat, 11 Mar 2023 09:15:05 +0100 Subject: [PATCH 05/40] Fix bug in fibaro cover (#89502) --- homeassistant/components/fibaro/cover.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/fibaro/cover.py b/homeassistant/components/fibaro/cover.py index e19c5c32e8a..c73c45d254c 100644 --- a/homeassistant/components/fibaro/cover.py +++ b/homeassistant/components/fibaro/cover.py @@ -94,9 +94,9 @@ class FibaroCover(FibaroDevice, CoverEntity): """Return if the cover is closed.""" if self._is_open_close_only(): state = self.fibaro_device.state - if not state.has_value or state.str_value.lower() == "unknown": + if not state.has_value or state.str_value().lower() == "unknown": return None - return state.str_value.lower() == "closed" + return state.str_value().lower() == "closed" if self.current_cover_position is None: return None From 950a1f6e9e8348b28131ccc756658b61ae51e285 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Sat, 11 Mar 2023 20:13:27 +0100 Subject: [PATCH 06/40] Bump pydeconz to v110 (#89527) * Bump pydeconz to v109 * Bump pydeconz to v110 for additional color modes --- homeassistant/components/deconz/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/deconz/manifest.json b/homeassistant/components/deconz/manifest.json index b0ad90857b5..5569f9d5e8a 100644 --- a/homeassistant/components/deconz/manifest.json +++ b/homeassistant/components/deconz/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_push", "loggers": ["pydeconz"], "quality_scale": "platinum", - "requirements": ["pydeconz==108"], + "requirements": ["pydeconz==110"], "ssdp": [ { "manufacturer": "Royal Philips Electronics", diff --git a/requirements_all.txt b/requirements_all.txt index 33e6d70f7e7..e67ca68c3d0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1573,7 +1573,7 @@ pydaikin==2.9.0 pydanfossair==0.1.0 # homeassistant.components.deconz -pydeconz==108 +pydeconz==110 # homeassistant.components.delijn pydelijn==1.0.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index e2f1b0f7513..bbc2053d1f7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1134,7 +1134,7 @@ pycoolmasternet-async==0.1.5 pydaikin==2.9.0 # homeassistant.components.deconz -pydeconz==108 +pydeconz==110 # homeassistant.components.dexcom pydexcom==0.2.3 From ca0304ffc4e227b3048c053614c691ae37319c4e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Mar 2023 10:37:00 -1000 Subject: [PATCH 07/40] Fix get_significant_states_with_session query looking at legacy columns (#89558) --- homeassistant/components/recorder/history.py | 8 +++++--- tests/components/recorder/test_history.py | 21 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/recorder/history.py b/homeassistant/components/recorder/history.py index b67790f9a42..a745716757f 100644 --- a/homeassistant/components/recorder/history.py +++ b/homeassistant/components/recorder/history.py @@ -282,9 +282,11 @@ def _significant_states_stmt( (States.last_changed_ts == States.last_updated_ts) | States.last_changed_ts.is_(None) ) - stmt += lambda q: q.filter( - (States.last_changed == States.last_updated) | States.last_changed.is_(None) - ) + else: + stmt += lambda q: q.filter( + (States.last_changed == States.last_updated) + | States.last_changed.is_(None) + ) elif significant_changes_only: if schema_version >= 31: stmt += lambda q: q.filter( diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index d082806f3da..2b4bed072a4 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -209,6 +209,27 @@ def test_significant_states_with_session_entity_minimal_response_no_matches( ) +def test_significant_states_with_session_single_entity( + hass_recorder: Callable[..., HomeAssistant], +) -> None: + """Test get_significant_states_with_session with a single entity.""" + hass = hass_recorder() + hass.states.set("demo.id", "any", {"attr": True}) + hass.states.set("demo.id", "any2", {"attr": True}) + wait_recording_done(hass) + now = dt_util.utcnow() + with session_scope(hass=hass) as session: + states = history.get_significant_states_with_session( + hass, + session, + now - timedelta(days=1), + now, + entity_ids=["demo.id"], + minimal_response=False, + ) + assert len(states["demo.id"]) == 2 + + @pytest.mark.parametrize( ("attributes", "no_attributes", "limit"), [ From 22922da60737c05122d641d56df2e11424abebba Mon Sep 17 00:00:00 2001 From: Eugenio Panadero Date: Mon, 13 Mar 2023 09:07:10 +0100 Subject: [PATCH 08/40] Bump aiopvpc to 4.1.0 (#89593) --- homeassistant/components/pvpc_hourly_pricing/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/pvpc_hourly_pricing/manifest.json b/homeassistant/components/pvpc_hourly_pricing/manifest.json index 89520f079a9..64e6e19086f 100644 --- a/homeassistant/components/pvpc_hourly_pricing/manifest.json +++ b/homeassistant/components/pvpc_hourly_pricing/manifest.json @@ -7,5 +7,5 @@ "iot_class": "cloud_polling", "loggers": ["aiopvpc"], "quality_scale": "platinum", - "requirements": ["aiopvpc==4.0.1"] + "requirements": ["aiopvpc==4.1.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index e67ca68c3d0..b387aac1970 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -241,7 +241,7 @@ aiopurpleair==2022.12.1 aiopvapi==2.0.4 # homeassistant.components.pvpc_hourly_pricing -aiopvpc==4.0.1 +aiopvpc==4.1.0 # homeassistant.components.lidarr # homeassistant.components.radarr diff --git a/requirements_test_all.txt b/requirements_test_all.txt index bbc2053d1f7..ef9c6d19160 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -219,7 +219,7 @@ aiopurpleair==2022.12.1 aiopvapi==2.0.4 # homeassistant.components.pvpc_hourly_pricing -aiopvpc==4.0.1 +aiopvpc==4.1.0 # homeassistant.components.lidarr # homeassistant.components.radarr From 65c614421adaea5e20a28ed40dbe19dc414213c1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 12 Mar 2023 16:57:22 -1000 Subject: [PATCH 09/40] Increase maximum aiohttp connections to 4096 (#89611) fixes #89408 --- homeassistant/helpers/aiohttp_client.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index d623de5e816..3ab583096cd 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -39,6 +39,20 @@ SERVER_SOFTWARE = "{0}/{1} aiohttp/{2} Python/{3[0]}.{3[1]}".format( WARN_CLOSE_MSG = "closes the Home Assistant aiohttp session" +# +# The default connection limit of 100 meant that you could only have +# 100 concurrent connections. +# +# This was effectively a limit of 100 devices and than +# the supervisor API would fail as soon as it was hit. +# +# We now apply the 100 limit per host, so that we can have 100 connections +# to a single host, but can have more than 4096 connections in total to +# prevent a single host from using all available connections. +# +MAXIMUM_CONNECTIONS = 4096 +MAXIMUM_CONNECTIONS_PER_HOST = 100 + class HassClientResponse(aiohttp.ClientResponse): """aiohttp.ClientResponse with a json method that uses json_loads by default.""" @@ -261,7 +275,12 @@ def _async_get_connector( else: ssl_context = False - connector = aiohttp.TCPConnector(enable_cleanup_closed=True, ssl=ssl_context) + connector = aiohttp.TCPConnector( + enable_cleanup_closed=True, + ssl=ssl_context, + limit=MAXIMUM_CONNECTIONS, + limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST, + ) hass.data[key] = connector async def _async_close_connector(event: Event) -> None: From d2f90236d11ff32c7c7f7eced4e03697967f3444 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 13 Mar 2023 09:44:20 +0100 Subject: [PATCH 10/40] Rename modules named repairs.py which are not repairs platforms (#89618) --- .../components/bayesian/binary_sensor.py | 2 +- .../bayesian/{repairs.py => issues.py} | 2 +- homeassistant/components/hassio/__init__.py | 10 ++++----- .../hassio/{repairs.py => issues.py} | 18 +++++++-------- tests/components/hassio/conftest.py | 2 +- .../{test_repairs.py => test_issues.py} | 22 +++++++++---------- 6 files changed, 28 insertions(+), 28 deletions(-) rename homeassistant/components/bayesian/{repairs.py => issues.py} (97%) rename homeassistant/components/hassio/{repairs.py => issues.py} (92%) rename tests/components/hassio/{test_repairs.py => test_issues.py} (96%) diff --git a/homeassistant/components/bayesian/binary_sensor.py b/homeassistant/components/bayesian/binary_sensor.py index 77571e1a80f..06baef1bd0e 100644 --- a/homeassistant/components/bayesian/binary_sensor.py +++ b/homeassistant/components/bayesian/binary_sensor.py @@ -60,7 +60,7 @@ from .const import ( DEFAULT_PROBABILITY_THRESHOLD, ) from .helpers import Observation -from .repairs import raise_mirrored_entries, raise_no_prob_given_false +from .issues import raise_mirrored_entries, raise_no_prob_given_false _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/bayesian/repairs.py b/homeassistant/components/bayesian/issues.py similarity index 97% rename from homeassistant/components/bayesian/repairs.py rename to homeassistant/components/bayesian/issues.py index 9a527636948..0f97b86b0e9 100644 --- a/homeassistant/components/bayesian/repairs.py +++ b/homeassistant/components/bayesian/issues.py @@ -1,4 +1,4 @@ -"""Helpers for generating repairs.""" +"""Helpers for generating issues.""" from __future__ import annotations from homeassistant.core import HomeAssistant diff --git a/homeassistant/components/hassio/__init__.py b/homeassistant/components/hassio/__init__.py index 4f5d8e9d31a..3ea42e331d4 100644 --- a/homeassistant/components/hassio/__init__.py +++ b/homeassistant/components/hassio/__init__.py @@ -96,7 +96,7 @@ from .handler import ( # noqa: F401 ) from .http import HassIOView from .ingress import async_setup_ingress_view -from .repairs import SupervisorRepairs +from .issues import SupervisorIssues from .websocket_api import async_load_websocket_api _LOGGER = logging.getLogger(__name__) @@ -123,7 +123,7 @@ DATA_SUPERVISOR_INFO = "hassio_supervisor_info" DATA_ADDONS_CHANGELOGS = "hassio_addons_changelogs" DATA_ADDONS_INFO = "hassio_addons_info" DATA_ADDONS_STATS = "hassio_addons_stats" -DATA_SUPERVISOR_REPAIRS = "supervisor_repairs" +DATA_SUPERVISOR_ISSUES = "supervisor_issues" HASSIO_UPDATE_INTERVAL = timedelta(minutes=5) ADDONS_COORDINATOR = "hassio_addons_coordinator" @@ -581,9 +581,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa: hass.config_entries.flow.async_init(DOMAIN, context={"source": "system"}) ) - # Start listening for problems with supervisor and making repairs - hass.data[DATA_SUPERVISOR_REPAIRS] = repairs = SupervisorRepairs(hass, hassio) - await repairs.setup() + # Start listening for problems with supervisor and making issues + hass.data[DATA_SUPERVISOR_ISSUES] = issues = SupervisorIssues(hass, hassio) + await issues.setup() return True diff --git a/homeassistant/components/hassio/repairs.py b/homeassistant/components/hassio/issues.py similarity index 92% rename from homeassistant/components/hassio/repairs.py rename to homeassistant/components/hassio/issues.py index 21120d8d522..a0d51c4806d 100644 --- a/homeassistant/components/hassio/repairs.py +++ b/homeassistant/components/hassio/issues.py @@ -70,11 +70,11 @@ UNHEALTHY_REASONS = { } -class SupervisorRepairs: - """Create repairs from supervisor events.""" +class SupervisorIssues: + """Create issues from supervisor events.""" def __init__(self, hass: HomeAssistant, client: HassIO) -> None: - """Initialize supervisor repairs.""" + """Initialize supervisor issues.""" self._hass = hass self._client = client self._unsupported_reasons: set[str] = set() @@ -87,7 +87,7 @@ class SupervisorRepairs: @unhealthy_reasons.setter def unhealthy_reasons(self, reasons: set[str]) -> None: - """Set unhealthy reasons. Create or delete repairs as necessary.""" + """Set unhealthy reasons. Create or delete issues as necessary.""" for unhealthy in reasons - self.unhealthy_reasons: if unhealthy in UNHEALTHY_REASONS: translation_key = f"unhealthy_{unhealthy}" @@ -119,7 +119,7 @@ class SupervisorRepairs: @unsupported_reasons.setter def unsupported_reasons(self, reasons: set[str]) -> None: - """Set unsupported reasons. Create or delete repairs as necessary.""" + """Set unsupported reasons. Create or delete issues as necessary.""" for unsupported in reasons - UNSUPPORTED_SKIP_REPAIR - self.unsupported_reasons: if unsupported in UNSUPPORTED_REASONS: translation_key = f"unsupported_{unsupported}" @@ -149,18 +149,18 @@ class SupervisorRepairs: await self.update() async_dispatcher_connect( - self._hass, EVENT_SUPERVISOR_EVENT, self._supervisor_events_to_repairs + self._hass, EVENT_SUPERVISOR_EVENT, self._supervisor_events_to_issues ) async def update(self) -> None: - """Update repairs from Supervisor resolution center.""" + """Update issuess from Supervisor resolution center.""" data = await self._client.get_resolution_info() self.unhealthy_reasons = set(data[ATTR_UNHEALTHY]) self.unsupported_reasons = set(data[ATTR_UNSUPPORTED]) @callback - def _supervisor_events_to_repairs(self, event: dict[str, Any]) -> None: - """Create repairs from supervisor events.""" + def _supervisor_events_to_issues(self, event: dict[str, Any]) -> None: + """Create issues from supervisor events.""" if ATTR_WS_EVENT not in event: return diff --git a/tests/components/hassio/conftest.py b/tests/components/hassio/conftest.py index 78ae9643d68..afe641405e3 100644 --- a/tests/components/hassio/conftest.py +++ b/tests/components/hassio/conftest.py @@ -52,7 +52,7 @@ def hassio_stubs(hassio_env, hass, hass_client, aioclient_mock): "homeassistant.components.hassio.HassIO.get_ingress_panels", return_value={"panels": []}, ), patch( - "homeassistant.components.hassio.repairs.SupervisorRepairs.setup" + "homeassistant.components.hassio.issues.SupervisorIssues.setup" ), patch( "homeassistant.components.hassio.HassIO.refresh_updates" ): diff --git a/tests/components/hassio/test_repairs.py b/tests/components/hassio/test_issues.py similarity index 96% rename from tests/components/hassio/test_repairs.py rename to tests/components/hassio/test_issues.py index 8806e641a5b..5b280d0c827 100644 --- a/tests/components/hassio/test_repairs.py +++ b/tests/components/hassio/test_issues.py @@ -1,4 +1,4 @@ -"""Test repairs from supervisor issues.""" +"""Test issues from supervisor issues.""" from __future__ import annotations import os @@ -145,12 +145,12 @@ def assert_repair_in_list(issues: list[dict[str, Any]], unhealthy: bool, reason: } in issues -async def test_unhealthy_repairs( +async def test_unhealthy_issues( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, hass_ws_client: WebSocketGenerator, ) -> None: - """Test repairs added for unhealthy systems.""" + """Test issues added for unhealthy systems.""" mock_resolution_info(aioclient_mock, unhealthy=["docker", "setup"]) result = await async_setup_component(hass, "hassio", {}) @@ -166,12 +166,12 @@ async def test_unhealthy_repairs( assert_repair_in_list(msg["result"]["issues"], unhealthy=True, reason="setup") -async def test_unsupported_repairs( +async def test_unsupported_issues( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, hass_ws_client: WebSocketGenerator, ) -> None: - """Test repairs added for unsupported systems.""" + """Test issues added for unsupported systems.""" mock_resolution_info(aioclient_mock, unsupported=["content_trust", "os"]) result = await async_setup_component(hass, "hassio", {}) @@ -189,12 +189,12 @@ async def test_unsupported_repairs( assert_repair_in_list(msg["result"]["issues"], unhealthy=False, reason="os") -async def test_unhealthy_repairs_add_remove( +async def test_unhealthy_issues_add_remove( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, hass_ws_client: WebSocketGenerator, ) -> None: - """Test unhealthy repairs added and removed from dispatches.""" + """Test unhealthy issues added and removed from dispatches.""" mock_resolution_info(aioclient_mock) result = await async_setup_component(hass, "hassio", {}) @@ -245,12 +245,12 @@ async def test_unhealthy_repairs_add_remove( assert msg["result"] == {"issues": []} -async def test_unsupported_repairs_add_remove( +async def test_unsupported_issues_add_remove( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, hass_ws_client: WebSocketGenerator, ) -> None: - """Test unsupported repairs added and removed from dispatches.""" + """Test unsupported issues added and removed from dispatches.""" mock_resolution_info(aioclient_mock) result = await async_setup_component(hass, "hassio", {}) @@ -301,12 +301,12 @@ async def test_unsupported_repairs_add_remove( assert msg["result"] == {"issues": []} -async def test_reset_repairs_supervisor_restart( +async def test_reset_issues_supervisor_restart( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, hass_ws_client: WebSocketGenerator, ) -> None: - """Unsupported/unhealthy repairs reset on supervisor restart.""" + """Unsupported/unhealthy issues reset on supervisor restart.""" mock_resolution_info(aioclient_mock, unsupported=["os"], unhealthy=["docker"]) result = await async_setup_component(hass, "hassio", {}) From f5562e93ac41e6a264fb5fdb8ac7c4299565a649 Mon Sep 17 00:00:00 2001 From: tomrennen Date: Mon, 13 Mar 2023 15:15:13 +0100 Subject: [PATCH 11/40] Improved "ON" state check for `Use room sensor for cooling` (#89634) --- homeassistant/components/nibe_heatpump/climate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/nibe_heatpump/climate.py b/homeassistant/components/nibe_heatpump/climate.py index 9c7d8641b6e..a68aabacf4b 100644 --- a/homeassistant/components/nibe_heatpump/climate.py +++ b/homeassistant/components/nibe_heatpump/climate.py @@ -139,7 +139,7 @@ class NibeClimateEntity(CoordinatorEntity[Coordinator], ClimateEntity): mode = HVACMode.OFF if _get_value(self._coil_use_room_sensor) == "ON": - if _get_value(self._coil_cooling_with_room_sensor) == "ON": + if _get_value(self._coil_cooling_with_room_sensor) != "OFF": mode = HVACMode.HEAT_COOL else: mode = HVACMode.HEAT From daa5718a80e3a3d84c59a50836bea73c594da29a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 13 Mar 2023 13:26:50 -0400 Subject: [PATCH 12/40] Bumped version to 2023.3.4 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 82b9fd1a31b..040794ed218 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -8,7 +8,7 @@ from .backports.enum import StrEnum APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2023 MINOR_VERSION: Final = 3 -PATCH_VERSION: Final = "3" +PATCH_VERSION: Final = "4" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 10, 0) diff --git a/pyproject.toml b/pyproject.toml index 0dcc14344ab..eed3a9b9673 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2023.3.3" +version = "2023.3.4" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" From 160518350fdf9601374d34d97b9d6bdf71d834bf Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 13 Mar 2023 14:51:01 -0400 Subject: [PATCH 13/40] Bump SQLAlchemy to 2.0.6 (#89650) --- homeassistant/components/recorder/manifest.json | 2 +- homeassistant/components/sql/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/recorder/manifest.json b/homeassistant/components/recorder/manifest.json index ed885127b1b..4f87c19ca7a 100644 --- a/homeassistant/components/recorder/manifest.json +++ b/homeassistant/components/recorder/manifest.json @@ -6,5 +6,5 @@ "integration_type": "system", "iot_class": "local_push", "quality_scale": "internal", - "requirements": ["sqlalchemy==2.0.5.post1", "fnvhash==0.1.0"] + "requirements": ["sqlalchemy==2.0.6", "fnvhash==0.1.0"] } diff --git a/homeassistant/components/sql/manifest.json b/homeassistant/components/sql/manifest.json index bdedbb9b207..7513bbd8c7f 100644 --- a/homeassistant/components/sql/manifest.json +++ b/homeassistant/components/sql/manifest.json @@ -5,5 +5,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sql", "iot_class": "local_polling", - "requirements": ["sqlalchemy==2.0.5.post1"] + "requirements": ["sqlalchemy==2.0.6"] } diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 0d3be634e77..e290d4730dd 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -42,7 +42,7 @@ pyudev==0.23.2 pyyaml==6.0 requests==2.28.2 scapy==2.5.0 -sqlalchemy==2.0.5.post1 +sqlalchemy==2.0.6 typing-extensions>=4.5.0,<5.0 voluptuous-serialize==2.6.0 voluptuous==0.13.1 diff --git a/requirements_all.txt b/requirements_all.txt index b387aac1970..d8280f48ddb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2398,7 +2398,7 @@ spotipy==2.22.1 # homeassistant.components.recorder # homeassistant.components.sql -sqlalchemy==2.0.5.post1 +sqlalchemy==2.0.6 # homeassistant.components.srp_energy srpenergy==1.3.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ef9c6d19160..b788f40b397 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1698,7 +1698,7 @@ spotipy==2.22.1 # homeassistant.components.recorder # homeassistant.components.sql -sqlalchemy==2.0.5.post1 +sqlalchemy==2.0.6 # homeassistant.components.srp_energy srpenergy==1.3.6 From 69582b7ecbced2cb0a07cb72b50c29c99d99382e Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:52:01 -0400 Subject: [PATCH 14/40] Bump ZHA dependencies (#89667) * Bump `zha-quirks` library and account for `setup_quirks` signature * Bump other ZHA dependencies * Revert zigpy bump --- homeassistant/components/zha/__init__.py | 2 +- homeassistant/components/zha/manifest.json | 4 ++-- requirements_all.txt | 4 ++-- requirements_test_all.txt | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py index d0496fe7b60..dd07d4da428 100644 --- a/homeassistant/components/zha/__init__.py +++ b/homeassistant/components/zha/__init__.py @@ -107,7 +107,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b zha_data.setdefault(platform, []) if config.get(CONF_ENABLE_QUIRKS, True): - setup_quirks(config) + setup_quirks(custom_quirks_path=config.get(CONF_CUSTOM_QUIRKS_PATH)) # temporary code to remove the ZHA storage file from disk. # this will be removed in 2022.10.0 diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index 44f88aa7339..3061d867b65 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -20,10 +20,10 @@ "zigpy_znp" ], "requirements": [ - "bellows==0.34.9", + "bellows==0.34.10", "pyserial==3.5", "pyserial-asyncio==0.6", - "zha-quirks==0.0.93", + "zha-quirks==0.0.94", "zigpy-deconz==0.19.2", "zigpy==0.53.2", "zigpy-xbee==0.16.2", diff --git a/requirements_all.txt b/requirements_all.txt index d8280f48ddb..38c26758151 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -422,7 +422,7 @@ beautifulsoup4==4.11.1 # beewi_smartclim==0.0.10 # homeassistant.components.zha -bellows==0.34.9 +bellows==0.34.10 # homeassistant.components.bmw_connected_drive bimmer_connected==0.12.1 @@ -2706,7 +2706,7 @@ zeroconf==0.47.3 zeversolar==0.3.1 # homeassistant.components.zha -zha-quirks==0.0.93 +zha-quirks==0.0.94 # homeassistant.components.zhong_hong zhong_hong_hvac==1.0.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b788f40b397..72fb11f485e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -352,7 +352,7 @@ base36==0.1.1 beautifulsoup4==4.11.1 # homeassistant.components.zha -bellows==0.34.9 +bellows==0.34.10 # homeassistant.components.bmw_connected_drive bimmer_connected==0.12.1 @@ -1922,7 +1922,7 @@ zeroconf==0.47.3 zeversolar==0.3.1 # homeassistant.components.zha -zha-quirks==0.0.93 +zha-quirks==0.0.94 # homeassistant.components.zha zigpy-deconz==0.19.2 From fdd9c5383f8f7c95626c163191f60f42ef1f5212 Mon Sep 17 00:00:00 2001 From: zhangshengdong29 <435878393@qq.com> Date: Thu, 16 Mar 2023 02:13:32 +0800 Subject: [PATCH 15/40] ArestData does not have available (#88631) --- homeassistant/components/arest/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/arest/sensor.py b/homeassistant/components/arest/sensor.py index 5c95fd63c3b..2e6012e0e6b 100644 --- a/homeassistant/components/arest/sensor.py +++ b/homeassistant/components/arest/sensor.py @@ -180,7 +180,7 @@ class ArestData: self._resource = resource self._pin = pin self.data = {} - self._attr_available = True + self.available = True @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): @@ -201,7 +201,7 @@ class ArestData: f"{self._resource}/digital/{self._pin}", timeout=10 ) self.data = {"value": response.json()["return_value"]} - self._attr_available = True + self.available = True except requests.exceptions.ConnectionError: _LOGGER.error("No route to device %s", self._resource) - self._attr_available = False + self.available = False From a9a6ff50ccfb228b07bb242a253a2a1057eaba5c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 6 Mar 2023 14:04:10 -1000 Subject: [PATCH 16/40] Bump aioesphomeapi to 13.5.0 (#89262) --- homeassistant/components/esphome/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/esphome/manifest.json b/homeassistant/components/esphome/manifest.json index e8e4e4876f0..54cdc23355f 100644 --- a/homeassistant/components/esphome/manifest.json +++ b/homeassistant/components/esphome/manifest.json @@ -14,6 +14,6 @@ "integration_type": "device", "iot_class": "local_push", "loggers": ["aioesphomeapi", "noiseprotocol"], - "requirements": ["aioesphomeapi==13.4.2", "esphome-dashboard-api==1.2.3"], + "requirements": ["aioesphomeapi==13.5.0", "esphome-dashboard-api==1.2.3"], "zeroconf": ["_esphomelib._tcp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 38c26758151..c657f0202a7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -156,7 +156,7 @@ aioecowitt==2023.01.0 aioemonitor==1.0.5 # homeassistant.components.esphome -aioesphomeapi==13.4.2 +aioesphomeapi==13.5.0 # homeassistant.components.flo aioflo==2021.11.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 72fb11f485e..b930f465c3c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -143,7 +143,7 @@ aioecowitt==2023.01.0 aioemonitor==1.0.5 # homeassistant.components.esphome -aioesphomeapi==13.4.2 +aioesphomeapi==13.5.0 # homeassistant.components.flo aioflo==2021.11.0 From 02738fb9d4cced2886085f559f9f21eae72e1889 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 16 Mar 2023 13:26:56 +0100 Subject: [PATCH 17/40] Handle int or mapping for off case in nibe cooling (#89680) Handle int or mapping for off case in nibe --- homeassistant/components/nibe_heatpump/climate.py | 10 +++++++--- homeassistant/components/nibe_heatpump/const.py | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/nibe_heatpump/climate.py b/homeassistant/components/nibe_heatpump/climate.py index a68aabacf4b..0df787de986 100644 --- a/homeassistant/components/nibe_heatpump/climate.py +++ b/homeassistant/components/nibe_heatpump/climate.py @@ -31,6 +31,7 @@ from . import Coordinator from .const import ( DOMAIN, LOGGER, + VALUES_COOL_WITH_ROOM_SENSOR_OFF, VALUES_MIXING_VALVE_CLOSED_STATE, VALUES_PRIORITY_COOLING, VALUES_PRIORITY_HEATING, @@ -139,10 +140,13 @@ class NibeClimateEntity(CoordinatorEntity[Coordinator], ClimateEntity): mode = HVACMode.OFF if _get_value(self._coil_use_room_sensor) == "ON": - if _get_value(self._coil_cooling_with_room_sensor) != "OFF": - mode = HVACMode.HEAT_COOL - else: + if ( + _get_value(self._coil_cooling_with_room_sensor) + in VALUES_COOL_WITH_ROOM_SENSOR_OFF + ): mode = HVACMode.HEAT + else: + mode = HVACMode.HEAT_COOL self._attr_hvac_mode = mode setpoint_heat = _get_float(self._coil_setpoint_heat) diff --git a/homeassistant/components/nibe_heatpump/const.py b/homeassistant/components/nibe_heatpump/const.py index 7d9bf58709c..dc6b4b18996 100644 --- a/homeassistant/components/nibe_heatpump/const.py +++ b/homeassistant/components/nibe_heatpump/const.py @@ -17,3 +17,4 @@ CONF_MODBUS_UNIT = "modbus_unit" VALUES_MIXING_VALVE_CLOSED_STATE = (30, "CLOSED", "SHUNT CLOSED") VALUES_PRIORITY_HEATING = (30, "HEAT") VALUES_PRIORITY_COOLING = (60, "COOLING") +VALUES_COOL_WITH_ROOM_SENSOR_OFF = (0, "OFF") From f120bac17f75724a8a9dc3005ca07b672baa741c Mon Sep 17 00:00:00 2001 From: jan iversen Date: Thu, 16 Mar 2023 04:48:00 +0100 Subject: [PATCH 18/40] Secure modbus hub_collect remains valid (#89684) Secure hub_collect remains valid. --- homeassistant/components/modbus/modbus.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/modbus/modbus.py b/homeassistant/components/modbus/modbus.py index 627950fe003..c40a05c1ef0 100644 --- a/homeassistant/components/modbus/modbus.py +++ b/homeassistant/components/modbus/modbus.py @@ -137,8 +137,10 @@ async def async_modbus_setup( for name in hubs: if not await hubs[name].async_setup(): return False + hub_collect = hass.data[DOMAIN] + else: + hass.data[DOMAIN] = hub_collect = {} - hass.data[DOMAIN] = hub_collect = {} for conf_hub in config[DOMAIN]: my_hub = ModbusHub(hass, conf_hub) hub_collect[conf_hub[CONF_NAME]] = my_hub From c3d7696c2e41fe4f55860c26bdcf3c75a67694aa Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Wed, 15 Mar 2023 06:01:34 +0100 Subject: [PATCH 19/40] Update to nibe 2.1.4 (#89686) --- homeassistant/components/nibe_heatpump/config_flow.py | 1 + homeassistant/components/nibe_heatpump/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/nibe_heatpump/config_flow.py b/homeassistant/components/nibe_heatpump/config_flow.py index 434a9a50ea6..6680ca6e325 100644 --- a/homeassistant/components/nibe_heatpump/config_flow.py +++ b/homeassistant/components/nibe_heatpump/config_flow.py @@ -89,6 +89,7 @@ async def validate_nibegw_input( """Validate the user input allows us to connect.""" heatpump = HeatPump(Model[data[CONF_MODEL]]) + heatpump.word_swap = True await heatpump.initialize() connection = NibeGW( diff --git a/homeassistant/components/nibe_heatpump/manifest.json b/homeassistant/components/nibe_heatpump/manifest.json index 5114cc222e9..81c23437bbc 100644 --- a/homeassistant/components/nibe_heatpump/manifest.json +++ b/homeassistant/components/nibe_heatpump/manifest.json @@ -5,5 +5,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/nibe_heatpump", "iot_class": "local_polling", - "requirements": ["nibe==2.0.0"] + "requirements": ["nibe==2.1.4"] } diff --git a/requirements_all.txt b/requirements_all.txt index c657f0202a7..4db6706449a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1201,7 +1201,7 @@ nextcord==2.0.0a8 nextdns==1.3.0 # homeassistant.components.nibe_heatpump -nibe==2.0.0 +nibe==2.1.4 # homeassistant.components.niko_home_control niko-home-control==0.2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b930f465c3c..5f79cfb759c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -891,7 +891,7 @@ nextcord==2.0.0a8 nextdns==1.3.0 # homeassistant.components.nibe_heatpump -nibe==2.0.0 +nibe==2.1.4 # homeassistant.components.nfandroidtv notifications-android-tv==0.1.5 From 52981699cf3348a38fef0df7bd14705d1c52096c Mon Sep 17 00:00:00 2001 From: Marcio Granzotto Rodrigues Date: Tue, 14 Mar 2023 15:44:55 -0300 Subject: [PATCH 20/40] Bump bond-async to 0.1.23 (#89697) --- homeassistant/components/bond/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/bond/manifest.json b/homeassistant/components/bond/manifest.json index bf343673fd6..fc91f8eb72e 100644 --- a/homeassistant/components/bond/manifest.json +++ b/homeassistant/components/bond/manifest.json @@ -7,6 +7,6 @@ "iot_class": "local_push", "loggers": ["bond_async"], "quality_scale": "platinum", - "requirements": ["bond-async==0.1.22"], + "requirements": ["bond-async==0.1.23"], "zeroconf": ["_bond._tcp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 4db6706449a..0b8a7d22074 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -467,7 +467,7 @@ bluetooth-auto-recovery==1.0.3 bluetooth-data-tools==0.3.1 # homeassistant.components.bond -bond-async==0.1.22 +bond-async==0.1.23 # homeassistant.components.bosch_shc boschshcpy==0.2.35 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5f79cfb759c..bd4f88b7a4d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -384,7 +384,7 @@ bluetooth-auto-recovery==1.0.3 bluetooth-data-tools==0.3.1 # homeassistant.components.bond -bond-async==0.1.22 +bond-async==0.1.23 # homeassistant.components.bosch_shc boschshcpy==0.2.35 From 90a4afb6faa358bf96eba12f6ae29dc746fa907f Mon Sep 17 00:00:00 2001 From: jan iversen Date: Wed, 15 Mar 2023 12:27:45 +0100 Subject: [PATCH 21/40] Correct modbus serial method parameter (#89738) --- homeassistant/components/modbus/modbus.py | 9 +++++++-- tests/components/modbus/test_init.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/modbus/modbus.py b/homeassistant/components/modbus/modbus.py index c40a05c1ef0..b53cfda104e 100644 --- a/homeassistant/components/modbus/modbus.py +++ b/homeassistant/components/modbus/modbus.py @@ -16,7 +16,7 @@ from pymodbus.client import ( from pymodbus.constants import Defaults from pymodbus.exceptions import ModbusException from pymodbus.pdu import ModbusResponse -from pymodbus.transaction import ModbusRtuFramer +from pymodbus.transaction import ModbusAsciiFramer, ModbusRtuFramer, ModbusSocketFramer import voluptuous as vol from homeassistant.const import ( @@ -281,9 +281,12 @@ class ModbusHub: } if self._config_type == SERIAL: # serial configuration + if client_config[CONF_METHOD] == "ascii": + self._pb_params["framer"] = ModbusAsciiFramer + else: + self._pb_params["framer"] = ModbusRtuFramer self._pb_params.update( { - "method": client_config[CONF_METHOD], "baudrate": client_config[CONF_BAUDRATE], "stopbits": client_config[CONF_STOPBITS], "bytesize": client_config[CONF_BYTESIZE], @@ -295,6 +298,8 @@ class ModbusHub: self._pb_params["host"] = client_config[CONF_HOST] if self._config_type == RTUOVERTCP: self._pb_params["framer"] = ModbusRtuFramer + else: + self._pb_params["framer"] = ModbusSocketFramer Defaults.Timeout = client_config[CONF_TIMEOUT] if CONF_MSG_WAIT in client_config: diff --git a/tests/components/modbus/test_init.py b/tests/components/modbus/test_init.py index 75f2f9d3e63..7a069234045 100644 --- a/tests/components/modbus/test_init.py +++ b/tests/components/modbus/test_init.py @@ -378,7 +378,7 @@ async def test_duplicate_entity_validator(do_config) -> None: CONF_TYPE: SERIAL, CONF_BAUDRATE: 9600, CONF_BYTESIZE: 8, - CONF_METHOD: "rtu", + CONF_METHOD: "ascii", CONF_PORT: TEST_PORT_SERIAL, CONF_PARITY: "E", CONF_STOPBITS: 1, From abda7b8a5bf95fcdb787decd1bc9541c8424f158 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Wed, 15 Mar 2023 21:22:13 +0100 Subject: [PATCH 22/40] Fix imap server push holding HA startup (#89750) --- homeassistant/components/imap/coordinator.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/imap/coordinator.py b/homeassistant/components/imap/coordinator.py index 8a716fe4786..e170f79e7f4 100644 --- a/homeassistant/components/imap/coordinator.py +++ b/homeassistant/components/imap/coordinator.py @@ -77,7 +77,9 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int]): f"Invalid response for search '{self.config_entry.data[CONF_SEARCH]}': {result} / {lines[0]}" ) if self.support_push: - self.hass.async_create_task(self.async_wait_server_push()) + self.hass.async_create_background_task( + self.async_wait_server_push(), "Wait for IMAP data push" + ) return len(lines[0].split()) async def async_wait_server_push(self) -> None: @@ -100,5 +102,7 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int]): async def shutdown(self, *_) -> None: """Close resources.""" if self.imap_client: + if self.imap_client.has_pending_idle(): + self.imap_client.idle_done() await self.imap_client.stop_wait_server_push() await self.imap_client.logout() From 9fa73fe3a9218b66905c9ffb91ba8cc3c3b3e7c3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 15 Mar 2023 20:00:47 -1000 Subject: [PATCH 23/40] Bump aioesphomeapi to 13.5.1 (#89777) --- homeassistant/components/esphome/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/esphome/manifest.json b/homeassistant/components/esphome/manifest.json index 54cdc23355f..95b6c091d5f 100644 --- a/homeassistant/components/esphome/manifest.json +++ b/homeassistant/components/esphome/manifest.json @@ -14,6 +14,6 @@ "integration_type": "device", "iot_class": "local_push", "loggers": ["aioesphomeapi", "noiseprotocol"], - "requirements": ["aioesphomeapi==13.5.0", "esphome-dashboard-api==1.2.3"], + "requirements": ["aioesphomeapi==13.5.1", "esphome-dashboard-api==1.2.3"], "zeroconf": ["_esphomelib._tcp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 0b8a7d22074..9bda92bc7f2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -156,7 +156,7 @@ aioecowitt==2023.01.0 aioemonitor==1.0.5 # homeassistant.components.esphome -aioesphomeapi==13.5.0 +aioesphomeapi==13.5.1 # homeassistant.components.flo aioflo==2021.11.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index bd4f88b7a4d..7e16fea8772 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -143,7 +143,7 @@ aioecowitt==2023.01.0 aioemonitor==1.0.5 # homeassistant.components.esphome -aioesphomeapi==13.5.0 +aioesphomeapi==13.5.1 # homeassistant.components.flo aioflo==2021.11.0 From e651ca747bc5ea34920397dbe7aa347a3da38e77 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 16 Mar 2023 18:32:07 +0100 Subject: [PATCH 24/40] Update frontend to 20230309.1 (#89802) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index a4d97201c5f..2c13e81ee3c 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -20,5 +20,5 @@ "documentation": "https://www.home-assistant.io/integrations/frontend", "integration_type": "system", "quality_scale": "internal", - "requirements": ["home-assistant-frontend==20230309.0"] + "requirements": ["home-assistant-frontend==20230309.1"] } diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index e290d4730dd..39b1a1b3dd5 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -23,7 +23,7 @@ fnvhash==0.1.0 hass-nabucasa==0.61.0 hassil==1.0.6 home-assistant-bluetooth==1.9.3 -home-assistant-frontend==20230309.0 +home-assistant-frontend==20230309.1 home-assistant-intents==2023.2.28 httpx==0.23.3 ifaddr==0.1.7 diff --git a/requirements_all.txt b/requirements_all.txt index 9bda92bc7f2..cdffe860f75 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -907,7 +907,7 @@ hole==0.8.0 holidays==0.18.0 # homeassistant.components.frontend -home-assistant-frontend==20230309.0 +home-assistant-frontend==20230309.1 # homeassistant.components.conversation home-assistant-intents==2023.2.28 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7e16fea8772..c8f2b57a764 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -690,7 +690,7 @@ hole==0.8.0 holidays==0.18.0 # homeassistant.components.frontend -home-assistant-frontend==20230309.0 +home-assistant-frontend==20230309.1 # homeassistant.components.conversation home-assistant-intents==2023.2.28 From 7e18e15cacc4bd00db1165de995f2b1c2ce68565 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 16 Mar 2023 18:48:17 +0100 Subject: [PATCH 25/40] Bumped version to 2023.3.5 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 040794ed218..f8e7859bf40 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -8,7 +8,7 @@ from .backports.enum import StrEnum APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2023 MINOR_VERSION: Final = 3 -PATCH_VERSION: Final = "4" +PATCH_VERSION: Final = "5" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 10, 0) diff --git a/pyproject.toml b/pyproject.toml index eed3a9b9673..a9c70089c7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2023.3.4" +version = "2023.3.5" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" From a5aa5c0c012b73a454948a4faa9174ff40488367 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Mon, 20 Mar 2023 04:35:45 +0100 Subject: [PATCH 26/40] Fix imap_email_content unknown status and replaying stale states (#89563) --- .../components/imap_email_content/sensor.py | 74 ++++++++++++------- .../imap_email_content/test_sensor.py | 26 +++++-- 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/imap_email_content/sensor.py b/homeassistant/components/imap_email_content/sensor.py index b14de632687..53cb921860c 100644 --- a/homeassistant/components/imap_email_content/sensor.py +++ b/homeassistant/components/imap_email_content/sensor.py @@ -95,9 +95,25 @@ class EmailReader: self._folder = folder self._verify_ssl = verify_ssl self._last_id = None + self._last_message = None self._unread_ids = deque([]) self.connection = None + @property + def last_id(self) -> int | None: + """Return last email uid that was processed.""" + return self._last_id + + @property + def last_unread_id(self) -> int | None: + """Return last email uid received.""" + # We assume the last id in the list is the last unread id + # We cannot know if that is the newest one, because it could arrive later + # https://stackoverflow.com/questions/12409862/python-imap-the-order-of-uids + if self._unread_ids: + return int(self._unread_ids[-1]) + return self._last_id + def connect(self): """Login and setup the connection.""" ssl_context = client_context() if self._verify_ssl else None @@ -128,21 +144,21 @@ class EmailReader: try: self.connection.select(self._folder, readonly=True) - if not self._unread_ids: - search = f"SINCE {datetime.date.today():%d-%b-%Y}" - if self._last_id is not None: - search = f"UID {self._last_id}:*" - - _, data = self.connection.uid("search", None, search) - self._unread_ids = deque(data[0].split()) + if self._last_id is None: + # search for today and yesterday + time_from = datetime.datetime.now() - datetime.timedelta(days=1) + search = f"SINCE {time_from:%d-%b-%Y}" + else: + search = f"UID {self._last_id}:*" + _, data = self.connection.uid("search", None, search) + self._unread_ids = deque(data[0].split()) while self._unread_ids: message_uid = self._unread_ids.popleft() if self._last_id is None or int(message_uid) > self._last_id: self._last_id = int(message_uid) - return self._fetch_message(message_uid) - - return self._fetch_message(str(self._last_id)) + self._last_message = self._fetch_message(message_uid) + return self._last_message except imaplib.IMAP4.error: _LOGGER.info("Connection to %s lost, attempting to reconnect", self._server) @@ -254,22 +270,30 @@ class EmailContentSensor(SensorEntity): def update(self) -> None: """Read emails and publish state change.""" email_message = self._email_reader.read_next() + while ( + self._last_id is None or self._last_id != self._email_reader.last_unread_id + ): + if email_message is None: + self._message = None + self._state_attributes = {} + return - if email_message is None: - self._message = None - self._state_attributes = {} - return + self._last_id = self._email_reader.last_id - if self.sender_allowed(email_message): - message = EmailContentSensor.get_msg_subject(email_message) + if self.sender_allowed(email_message): + message = EmailContentSensor.get_msg_subject(email_message) - if self._value_template is not None: - message = self.render_template(email_message) + if self._value_template is not None: + message = self.render_template(email_message) - self._message = message - self._state_attributes = { - ATTR_FROM: EmailContentSensor.get_msg_sender(email_message), - ATTR_SUBJECT: EmailContentSensor.get_msg_subject(email_message), - ATTR_DATE: email_message["Date"], - ATTR_BODY: EmailContentSensor.get_msg_text(email_message), - } + self._message = message + self._state_attributes = { + ATTR_FROM: EmailContentSensor.get_msg_sender(email_message), + ATTR_SUBJECT: EmailContentSensor.get_msg_subject(email_message), + ATTR_DATE: email_message["Date"], + ATTR_BODY: EmailContentSensor.get_msg_text(email_message), + } + + if self._last_id == self._email_reader.last_unread_id: + break + email_message = self._email_reader.read_next() diff --git a/tests/components/imap_email_content/test_sensor.py b/tests/components/imap_email_content/test_sensor.py index afa6116ff42..ba2b362af73 100644 --- a/tests/components/imap_email_content/test_sensor.py +++ b/tests/components/imap_email_content/test_sensor.py @@ -14,9 +14,16 @@ from homeassistant.helpers.template import Template class FakeEMailReader: """A test class for sending test emails.""" - def __init__(self, messages): + def __init__(self, messages) -> None: """Set up the fake email reader.""" self._messages = messages + self.last_id = 0 + self.last_unread_id = len(messages) + + def add_test_message(self, message): + """Add a new message.""" + self.last_unread_id += 1 + self._messages.append(message) def connect(self): """Stay always Connected.""" @@ -26,6 +33,7 @@ class FakeEMailReader: """Get the next email.""" if len(self._messages) == 0: return None + self.last_id += 1 return self._messages.popleft() @@ -146,7 +154,7 @@ async def test_multi_part_only_other_text(hass: HomeAssistant) -> None: async def test_multiple_emails(hass: HomeAssistant) -> None: - """Test multiple emails.""" + """Test multiple emails, discarding stale states.""" states = [] test_message1 = email.message.Message() @@ -158,9 +166,15 @@ async def test_multiple_emails(hass: HomeAssistant) -> None: test_message2 = email.message.Message() test_message2["From"] = "sender@test.com" test_message2["Subject"] = "Test 2" - test_message2["Date"] = datetime.datetime(2016, 1, 1, 12, 44, 57) + test_message2["Date"] = datetime.datetime(2016, 1, 1, 12, 44, 58) test_message2.set_payload("Test Message 2") + test_message3 = email.message.Message() + test_message3["From"] = "sender@test.com" + test_message3["Subject"] = "Test 3" + test_message3["Date"] = datetime.datetime(2016, 1, 1, 12, 50, 1) + test_message3.set_payload("Test Message 2") + def state_changed_listener(entity_id, from_s, to_s): states.append(to_s) @@ -178,11 +192,13 @@ async def test_multiple_emails(hass: HomeAssistant) -> None: sensor.async_schedule_update_ha_state(True) await hass.async_block_till_done() + # Fake a new received message + sensor._email_reader.add_test_message(test_message3) sensor.async_schedule_update_ha_state(True) await hass.async_block_till_done() - assert states[0].state == "Test" - assert states[1].state == "Test 2" + assert states[0].state == "Test 2" + assert states[1].state == "Test 3" assert sensor.extra_state_attributes["body"] == "Test Message 2" From 1e03ff68a2604b78db53092cabd30f47b753c753 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 16 Mar 2023 16:44:49 -1000 Subject: [PATCH 27/40] Bump aioharmony to 0.2.10 (#89831) fixes #89823 --- homeassistant/components/harmony/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/harmony/manifest.json b/homeassistant/components/harmony/manifest.json index 2603ee613ae..c6a6327046d 100644 --- a/homeassistant/components/harmony/manifest.json +++ b/homeassistant/components/harmony/manifest.json @@ -13,7 +13,7 @@ "documentation": "https://www.home-assistant.io/integrations/harmony", "iot_class": "local_push", "loggers": ["aioharmony", "slixmpp"], - "requirements": ["aioharmony==0.2.9"], + "requirements": ["aioharmony==0.2.10"], "ssdp": [ { "manufacturer": "Logitech", diff --git a/requirements_all.txt b/requirements_all.txt index cdffe860f75..3fcf96ccb5e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -171,7 +171,7 @@ aiogithubapi==22.10.1 aioguardian==2022.07.0 # homeassistant.components.harmony -aioharmony==0.2.9 +aioharmony==0.2.10 # homeassistant.components.homekit_controller aiohomekit==2.6.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c8f2b57a764..7061c3bf624 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -155,7 +155,7 @@ aiogithubapi==22.10.1 aioguardian==2022.07.0 # homeassistant.components.harmony -aioharmony==0.2.9 +aioharmony==0.2.10 # homeassistant.components.homekit_controller aiohomekit==2.6.1 From 713d3025f20b8649d823804bd669b778723f72ea Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Mon, 20 Mar 2023 12:08:27 +0100 Subject: [PATCH 28/40] Correct missing wordswap for S series nibe (#89866) Correct missing wordswap for nibe --- homeassistant/components/nibe_heatpump/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/nibe_heatpump/__init__.py b/homeassistant/components/nibe_heatpump/__init__.py index fd77b5e2344..89aac6bed61 100644 --- a/homeassistant/components/nibe_heatpump/__init__.py +++ b/homeassistant/components/nibe_heatpump/__init__.py @@ -62,13 +62,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Nibe Heat Pump from a config entry.""" heatpump = HeatPump(Model[entry.data[CONF_MODEL]]) + heatpump.word_swap = entry.data.get(CONF_WORD_SWAP, True) await heatpump.initialize() connection: Connection connection_type = entry.data[CONF_CONNECTION_TYPE] if connection_type == CONF_CONNECTION_TYPE_NIBEGW: - heatpump.word_swap = entry.data[CONF_WORD_SWAP] connection = NibeGW( heatpump, entry.data[CONF_IP_ADDRESS], From de6f55dcfb994929753d419bedee5056676d7f7d Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Sun, 19 Mar 2023 01:57:40 +0100 Subject: [PATCH 29/40] Fix blocking MQTT entry unload (#89922) * Remove unneeded async_block_till_done * use await asyncio.sleep(0) instead --- homeassistant/components/mqtt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index a1b194284c7..ff126a22603 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -706,7 +706,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: for component in PLATFORMS ) ) - await hass.async_block_till_done() + await asyncio.sleep(0) # Unsubscribe reload dispatchers while reload_dispatchers := mqtt_data.reload_dispatchers: reload_dispatchers.pop()() From 127f2289a1af45ac123e733947f11b7ba40df3f1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 18 Mar 2023 20:59:05 -1000 Subject: [PATCH 30/40] Remove async_block_till_done in freebox (#89928) async_block_till_done() is not meant to be called in integrations --- homeassistant/components/freebox/config_flow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/freebox/config_flow.py b/homeassistant/components/freebox/config_flow.py index fd9252aaa17..dbee01c4e7d 100644 --- a/homeassistant/components/freebox/config_flow.py +++ b/homeassistant/components/freebox/config_flow.py @@ -77,7 +77,6 @@ class FreeboxFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): # Check permissions await fbx.system.get_config() await fbx.lan.get_hosts_list() - await self.hass.async_block_till_done() # Close connection await fbx.close() From 92fb978a0377e6cea5c848c6a7265ab2f62a5657 Mon Sep 17 00:00:00 2001 From: micha91 Date: Mon, 20 Mar 2023 11:59:27 +0100 Subject: [PATCH 31/40] Bump aiomusiccast to 0.14.8 (#89978) --- homeassistant/components/yamaha_musiccast/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/yamaha_musiccast/manifest.json b/homeassistant/components/yamaha_musiccast/manifest.json index 9a19f61eb44..48b8de20608 100644 --- a/homeassistant/components/yamaha_musiccast/manifest.json +++ b/homeassistant/components/yamaha_musiccast/manifest.json @@ -7,7 +7,7 @@ "documentation": "https://www.home-assistant.io/integrations/yamaha_musiccast", "iot_class": "local_push", "loggers": ["aiomusiccast"], - "requirements": ["aiomusiccast==0.14.7"], + "requirements": ["aiomusiccast==0.14.8"], "ssdp": [ { "manufacturer": "Yamaha Corporation" diff --git a/requirements_all.txt b/requirements_all.txt index 3fcf96ccb5e..27eb15772e6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -214,7 +214,7 @@ aiolyric==1.0.9 aiomodernforms==0.1.8 # homeassistant.components.yamaha_musiccast -aiomusiccast==0.14.7 +aiomusiccast==0.14.8 # homeassistant.components.nanoleaf aionanoleaf==0.2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7061c3bf624..2168b2b42f7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -195,7 +195,7 @@ aiolyric==1.0.9 aiomodernforms==0.1.8 # homeassistant.components.yamaha_musiccast -aiomusiccast==0.14.7 +aiomusiccast==0.14.8 # homeassistant.components.nanoleaf aionanoleaf==0.2.1 From 1f71068740a6947acaa485af86b2acb2bad36b46 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 20 Mar 2023 17:49:59 -1000 Subject: [PATCH 32/40] Handle cancelation of wait_for_ble_connections_free in esphome bluetooth (#90014) Handle cancelation in wait_for_ble_connections_free If `wait_for_ble_connections_free` was canceled due to timeout or the esp disconnecting from Home Assistant the future would get canceled. When we reconnect and get the next callback we need to handle it being done. fixes ``` 2023-03-21 02:34:36.876 ERROR (MainThread) [homeassistant] Error doing job: Fatal error: protocol.data_received() call failed. Traceback (most recent call last): File "/usr/local/lib/python3.10/asyncio/selector_events.py", line 868, in _read_ready__data_received self._protocol.data_received(data) File "/usr/local/lib/python3.10/site-packages/aioesphomeapi/_frame_helper.py", line 195, in data_received self._callback_packet(msg_type_int, bytes(packet_data)) File "/usr/local/lib/python3.10/site-packages/aioesphomeapi/_frame_helper.py", line 110, in _callback_packet self._on_pkt(Packet(type_, data)) File "/usr/local/lib/python3.10/site-packages/aioesphomeapi/connection.py", line 688, in _process_packet handler(msg) File "/usr/local/lib/python3.10/site-packages/aioesphomeapi/client.py", line 482, in on_msg on_bluetooth_connections_free_update(resp.free, resp.limit) File "/usr/src/homeassistant/homeassistant/components/esphome/entry_data.py", line 136, in async_update_ble_connection_limits fut.set_result(free) asyncio.exceptions.InvalidStateError: invalid state ``` --- homeassistant/components/esphome/entry_data.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/esphome/entry_data.py b/homeassistant/components/esphome/entry_data.py index 0aed6ce43a7..a389d746435 100644 --- a/homeassistant/components/esphome/entry_data.py +++ b/homeassistant/components/esphome/entry_data.py @@ -130,10 +130,15 @@ class RuntimeEntryData: ) self.ble_connections_free = free self.ble_connections_limit = limit - if free: - for fut in self._ble_connection_free_futures: + if not free: + return + for fut in self._ble_connection_free_futures: + # If wait_for_ble_connections_free gets cancelled, it will + # leave a future in the list. We need to check if it's done + # before setting the result. + if not fut.done(): fut.set_result(free) - self._ble_connection_free_futures.clear() + self._ble_connection_free_futures.clear() async def wait_for_ble_connections_free(self) -> int: """Wait until there are free BLE connections.""" From 2a18261efb4b476b38e774740d59d04f09f9c8fc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 15 Mar 2023 17:47:26 -1000 Subject: [PATCH 33/40] Bump yalexs_ble to 2.1.0 (#89772) switches to using cryptography to reduce the number of deps changelog: https://github.com/bdraco/yalexs-ble/compare/v2.0.4...v2.1.0 --- homeassistant/components/august/manifest.json | 2 +- homeassistant/components/yalexs_ble/manifest.json | 2 +- requirements_all.txt | 4 ++-- requirements_test_all.txt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index dedfc9127a3..eba6e2c1b39 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==1.2.7", "yalexs_ble==2.0.4"] + "requirements": ["yalexs==1.2.7", "yalexs_ble==2.1.0"] } diff --git a/homeassistant/components/yalexs_ble/manifest.json b/homeassistant/components/yalexs_ble/manifest.json index e34ace05e15..e793fe27286 100644 --- a/homeassistant/components/yalexs_ble/manifest.json +++ b/homeassistant/components/yalexs_ble/manifest.json @@ -12,5 +12,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/yalexs_ble", "iot_class": "local_push", - "requirements": ["yalexs-ble==2.0.4"] + "requirements": ["yalexs-ble==2.1.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index 27eb15772e6..debc7d480cc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2670,13 +2670,13 @@ xs1-api-client==3.0.0 yalesmartalarmclient==0.3.9 # homeassistant.components.yalexs_ble -yalexs-ble==2.0.4 +yalexs-ble==2.1.0 # homeassistant.components.august yalexs==1.2.7 # homeassistant.components.august -yalexs_ble==2.0.4 +yalexs_ble==2.1.0 # homeassistant.components.yeelight yeelight==0.7.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2168b2b42f7..09afa5970ba 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1895,13 +1895,13 @@ xmltodict==0.13.0 yalesmartalarmclient==0.3.9 # homeassistant.components.yalexs_ble -yalexs-ble==2.0.4 +yalexs-ble==2.1.0 # homeassistant.components.august yalexs==1.2.7 # homeassistant.components.august -yalexs_ble==2.0.4 +yalexs_ble==2.1.0 # homeassistant.components.yeelight yeelight==0.7.10 From 53d400ca9679650f24bafac61f3e3fa8f2102fc3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 20 Mar 2023 17:49:30 -1000 Subject: [PATCH 34/40] Bump yalexs-ble to 2.1.1 (#90015) * Bump yalexs-ble to 2.1.1 There was another task that could be prematurely GCed changelog: https://github.com/bdraco/yalexs-ble/compare/v2.1.0...v2.1.1 * fixes --- homeassistant/components/august/manifest.json | 2 +- homeassistant/components/yalexs_ble/manifest.json | 2 +- requirements_all.txt | 6 ++---- requirements_test_all.txt | 6 ++---- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index eba6e2c1b39..213f0237e12 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==1.2.7", "yalexs_ble==2.1.0"] + "requirements": ["yalexs==1.2.7", "yalexs-ble==2.1.1"] } diff --git a/homeassistant/components/yalexs_ble/manifest.json b/homeassistant/components/yalexs_ble/manifest.json index e793fe27286..6bb58752a00 100644 --- a/homeassistant/components/yalexs_ble/manifest.json +++ b/homeassistant/components/yalexs_ble/manifest.json @@ -12,5 +12,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/yalexs_ble", "iot_class": "local_push", - "requirements": ["yalexs-ble==2.1.0"] + "requirements": ["yalexs-ble==2.1.1"] } diff --git a/requirements_all.txt b/requirements_all.txt index debc7d480cc..e763e3037ab 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2669,15 +2669,13 @@ xs1-api-client==3.0.0 # homeassistant.components.yale_smart_alarm yalesmartalarmclient==0.3.9 +# homeassistant.components.august # homeassistant.components.yalexs_ble -yalexs-ble==2.1.0 +yalexs-ble==2.1.1 # homeassistant.components.august yalexs==1.2.7 -# homeassistant.components.august -yalexs_ble==2.1.0 - # homeassistant.components.yeelight yeelight==0.7.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 09afa5970ba..73feda7628e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1894,15 +1894,13 @@ xmltodict==0.13.0 # homeassistant.components.yale_smart_alarm yalesmartalarmclient==0.3.9 +# homeassistant.components.august # homeassistant.components.yalexs_ble -yalexs-ble==2.1.0 +yalexs-ble==2.1.1 # homeassistant.components.august yalexs==1.2.7 -# homeassistant.components.august -yalexs_ble==2.1.0 - # homeassistant.components.yeelight yeelight==0.7.10 From 3747fd5dcb74842b6eab31630238bceccc54fc0d Mon Sep 17 00:00:00 2001 From: Klaas Schoute Date: Mon, 13 Mar 2023 15:00:50 +0100 Subject: [PATCH 35/40] Bump easyEnergy to v0.2.1 (#89630) --- homeassistant/components/easyenergy/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/easyenergy/manifest.json b/homeassistant/components/easyenergy/manifest.json index 6b88dd84c89..fc0a4fd7739 100644 --- a/homeassistant/components/easyenergy/manifest.json +++ b/homeassistant/components/easyenergy/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/easyenergy", "iot_class": "cloud_polling", "quality_scale": "platinum", - "requirements": ["easyenergy==0.1.2"] + "requirements": ["easyenergy==0.2.1"] } diff --git a/requirements_all.txt b/requirements_all.txt index e763e3037ab..ba96fabc1a8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -625,7 +625,7 @@ dynalite_devices==0.1.47 eagle100==0.1.1 # homeassistant.components.easyenergy -easyenergy==0.1.2 +easyenergy==0.2.1 # homeassistant.components.ebusd ebusdpy==0.0.17 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 73feda7628e..0331bdf76e7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -490,7 +490,7 @@ dynalite_devices==0.1.47 eagle100==0.1.1 # homeassistant.components.easyenergy -easyenergy==0.1.2 +easyenergy==0.2.1 # homeassistant.components.elgato elgato==4.0.1 From 146347e31aba16345f2ecc51496601e80d24d7c1 Mon Sep 17 00:00:00 2001 From: Klaas Schoute Date: Wed, 22 Mar 2023 10:46:17 +0100 Subject: [PATCH 36/40] Bump easyEnergy to v0.2.2 (#90080) --- homeassistant/components/easyenergy/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/easyenergy/manifest.json b/homeassistant/components/easyenergy/manifest.json index fc0a4fd7739..0954269628a 100644 --- a/homeassistant/components/easyenergy/manifest.json +++ b/homeassistant/components/easyenergy/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/easyenergy", "iot_class": "cloud_polling", "quality_scale": "platinum", - "requirements": ["easyenergy==0.2.1"] + "requirements": ["easyenergy==0.2.2"] } diff --git a/requirements_all.txt b/requirements_all.txt index ba96fabc1a8..f282e59eebf 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -625,7 +625,7 @@ dynalite_devices==0.1.47 eagle100==0.1.1 # homeassistant.components.easyenergy -easyenergy==0.2.1 +easyenergy==0.2.2 # homeassistant.components.ebusd ebusdpy==0.0.17 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0331bdf76e7..6200c913d38 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -490,7 +490,7 @@ dynalite_devices==0.1.47 eagle100==0.1.1 # homeassistant.components.easyenergy -easyenergy==0.2.1 +easyenergy==0.2.2 # homeassistant.components.elgato elgato==4.0.1 From 406e92511bb489cf8dbd80e7c37090a2721ab942 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 21 Mar 2023 23:09:38 -0400 Subject: [PATCH 37/40] Bump to oralb-ble 0.17.6 (#90081) --- homeassistant/components/oralb/manifest.json | 3 ++- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/oralb/manifest.json b/homeassistant/components/oralb/manifest.json index 37b043e5436..a1071cc0a11 100644 --- a/homeassistant/components/oralb/manifest.json +++ b/homeassistant/components/oralb/manifest.json @@ -11,5 +11,6 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/oralb", "iot_class": "local_push", - "requirements": ["oralb-ble==0.17.5"] + "loggers": ["oralb-ble"], + "requirements": ["oralb-ble==0.17.6"] } diff --git a/requirements_all.txt b/requirements_all.txt index f282e59eebf..fe86666d9c4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1299,7 +1299,7 @@ openwrt-luci-rpc==1.1.11 openwrt-ubus-rpc==0.0.2 # homeassistant.components.oralb -oralb-ble==0.17.5 +oralb-ble==0.17.6 # homeassistant.components.oru oru==0.1.11 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6200c913d38..87663416f00 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -947,7 +947,7 @@ openai==0.26.2 openerz-api==0.2.0 # homeassistant.components.oralb -oralb-ble==0.17.5 +oralb-ble==0.17.6 # homeassistant.components.ovo_energy ovoenergy==1.2.0 From a7b5a0297ef913ab305b22d2ebaf0cbdf0f0c4b9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 22 Mar 2023 16:10:47 -1000 Subject: [PATCH 38/40] Bump PySwitchbot to 0.37.4 (#90146) fixes #90090 fixes #89061 changelog: https://github.com/Danielhiversen/pySwitchbot/compare/0.37.3...0.37.4 --- homeassistant/components/switchbot/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/switchbot/manifest.json b/homeassistant/components/switchbot/manifest.json index 2637f578b8f..ada24bcee57 100644 --- a/homeassistant/components/switchbot/manifest.json +++ b/homeassistant/components/switchbot/manifest.json @@ -40,5 +40,5 @@ "documentation": "https://www.home-assistant.io/integrations/switchbot", "iot_class": "local_push", "loggers": ["switchbot"], - "requirements": ["PySwitchbot==0.37.3"] + "requirements": ["PySwitchbot==0.37.4"] } diff --git a/requirements_all.txt b/requirements_all.txt index fe86666d9c4..9b63f54a60e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -40,7 +40,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.37.3 +PySwitchbot==0.37.4 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 87663416f00..e71f661b4ea 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -36,7 +36,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.37.3 +PySwitchbot==0.37.4 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 From 174342860b828040b7018210861d98d1ae503de9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 22 Mar 2023 22:54:09 -0400 Subject: [PATCH 39/40] Always enforce URL param ordering for signed URLs (#90148) Always enforce URL param ordering --- homeassistant/components/http/auth.py | 15 +++++++------- tests/components/http/test_auth.py | 28 ++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/http/auth.py b/homeassistant/components/http/auth.py index 5213cd1b072..d10bd677e41 100644 --- a/homeassistant/components/http/auth.py +++ b/homeassistant/components/http/auth.py @@ -60,9 +60,7 @@ def async_sign_path( url = URL(path) now = dt_util.utcnow() - params = dict(sorted(url.query.items())) - for param in SAFE_QUERY_PARAMS: - params.pop(param, None) + params = [itm for itm in url.query.items() if itm[0] not in SAFE_QUERY_PARAMS] encoded = jwt.encode( { "iss": refresh_token_id, @@ -75,7 +73,7 @@ def async_sign_path( algorithm="HS256", ) - params[SIGN_QUERY_PARAM] = encoded + params.append((SIGN_QUERY_PARAM, encoded)) url = url.with_query(params) return f"{url.path}?{url.query_string}" @@ -184,10 +182,11 @@ async def async_setup_auth(hass: HomeAssistant, app: Application) -> None: if claims["path"] != request.path: return False - params = dict(sorted(request.query.items())) - del params[SIGN_QUERY_PARAM] - for param in SAFE_QUERY_PARAMS: - params.pop(param, None) + params = [ + list(itm) # claims stores tuples as lists + for itm in request.query.items() + if itm[0] not in SAFE_QUERY_PARAMS and itm[0] != SIGN_QUERY_PARAM + ] if claims["params"] != params: return False diff --git a/tests/components/http/test_auth.py b/tests/components/http/test_auth.py index fb00640cdc5..246572e64f8 100644 --- a/tests/components/http/test_auth.py +++ b/tests/components/http/test_auth.py @@ -352,6 +352,12 @@ async def test_auth_access_signed_path_with_query_param( data = await req.json() assert data["user_id"] == refresh_token.user.id + # Without query params not allowed + url = yarl.URL(signed_path) + signed_path = f"{url.path}?{SIGN_QUERY_PARAM}={url.query.get(SIGN_QUERY_PARAM)}" + req = await client.get(signed_path) + assert req.status == HTTPStatus.UNAUTHORIZED + async def test_auth_access_signed_path_with_query_param_order( hass: HomeAssistant, @@ -374,12 +380,24 @@ async def test_auth_access_signed_path_with_query_param_order( refresh_token_id=refresh_token.id, ) url = yarl.URL(signed_path) - signed_path = f"{url.path}?{SIGN_QUERY_PARAM}={url.query.get(SIGN_QUERY_PARAM)}&foo=bar&test=test" - req = await client.get(signed_path) - assert req.status == HTTPStatus.OK - data = await req.json() - assert data["user_id"] == refresh_token.user.id + # Change order + req = await client.get( + f"{url.path}?{SIGN_QUERY_PARAM}={url.query.get(SIGN_QUERY_PARAM)}&foo=bar&test=test" + ) + assert req.status == HTTPStatus.UNAUTHORIZED + + # Duplicate a param + req = await client.get( + f"{url.path}?{SIGN_QUERY_PARAM}={url.query.get(SIGN_QUERY_PARAM)}&test=test&foo=aaa&foo=bar" + ) + assert req.status == HTTPStatus.UNAUTHORIZED + + # Remove a param + req = await client.get( + f"{url.path}?{SIGN_QUERY_PARAM}={url.query.get(SIGN_QUERY_PARAM)}&test=test" + ) + assert req.status == HTTPStatus.UNAUTHORIZED async def test_auth_access_signed_path_with_query_param_safe_param( From 117113cdfc4c81f6df6a1ef71d53ac3e58ade025 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 22 Mar 2023 22:59:47 -0400 Subject: [PATCH 40/40] Bumped version to 2023.3.6 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index f8e7859bf40..ed959488ddb 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -8,7 +8,7 @@ from .backports.enum import StrEnum APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2023 MINOR_VERSION: Final = 3 -PATCH_VERSION: Final = "5" +PATCH_VERSION: Final = "6" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 10, 0) diff --git a/pyproject.toml b/pyproject.toml index a9c70089c7d..6702915a85b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2023.3.5" +version = "2023.3.6" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst"