From 41ab7b346cf5d126c3ea7f9a911ea9b6092e3f76 Mon Sep 17 00:00:00 2001 From: Thomas55555 <59625598+Thomas55555@users.noreply.github.com> Date: Thu, 3 Jul 2025 19:08:58 +0200 Subject: [PATCH 01/14] Set timeout for remote calendar (#147024) --- .../components/remote_calendar/client.py | 12 ++++++++++++ .../components/remote_calendar/config_flow.py | 12 +++++++++--- .../components/remote_calendar/coordinator.py | 15 +++++++++++---- .../components/remote_calendar/strings.json | 6 +++++- .../remote_calendar/test_config_flow.py | 12 +++++++----- tests/components/remote_calendar/test_init.py | 7 ++++--- 6 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 homeassistant/components/remote_calendar/client.py diff --git a/homeassistant/components/remote_calendar/client.py b/homeassistant/components/remote_calendar/client.py new file mode 100644 index 00000000000..f0f243ca386 --- /dev/null +++ b/homeassistant/components/remote_calendar/client.py @@ -0,0 +1,12 @@ +"""Specifies the parameter for the httpx download.""" + +from httpx import AsyncClient, Response, Timeout + + +async def get_calendar(client: AsyncClient, url: str) -> Response: + """Make an HTTP GET request using Home Assistant's async HTTPX client with timeout.""" + return await client.get( + url, + follow_redirects=True, + timeout=Timeout(5, read=30, write=5, pool=5), + ) diff --git a/homeassistant/components/remote_calendar/config_flow.py b/homeassistant/components/remote_calendar/config_flow.py index 558a3d668ae..3f835b5d82b 100644 --- a/homeassistant/components/remote_calendar/config_flow.py +++ b/homeassistant/components/remote_calendar/config_flow.py @@ -4,13 +4,14 @@ from http import HTTPStatus import logging from typing import Any -from httpx import HTTPError, InvalidURL +from httpx import HTTPError, InvalidURL, TimeoutException import voluptuous as vol from homeassistant.config_entries import ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_URL from homeassistant.helpers.httpx_client import get_async_client +from .client import get_calendar from .const import CONF_CALENDAR_NAME, DOMAIN from .ics import InvalidIcsException, parse_calendar @@ -49,7 +50,7 @@ class RemoteCalendarConfigFlow(ConfigFlow, domain=DOMAIN): self._async_abort_entries_match({CONF_URL: user_input[CONF_URL]}) client = get_async_client(self.hass) try: - res = await client.get(user_input[CONF_URL], follow_redirects=True) + res = await get_calendar(client, user_input[CONF_URL]) if res.status_code == HTTPStatus.FORBIDDEN: errors["base"] = "forbidden" return self.async_show_form( @@ -58,9 +59,14 @@ class RemoteCalendarConfigFlow(ConfigFlow, domain=DOMAIN): errors=errors, ) res.raise_for_status() + except TimeoutException as err: + errors["base"] = "timeout_connect" + _LOGGER.debug( + "A timeout error occurred: %s", str(err) or type(err).__name__ + ) except (HTTPError, InvalidURL) as err: errors["base"] = "cannot_connect" - _LOGGER.debug("An error occurred: %s", err) + _LOGGER.debug("An error occurred: %s", str(err) or type(err).__name__) else: try: await parse_calendar(self.hass, res.text) diff --git a/homeassistant/components/remote_calendar/coordinator.py b/homeassistant/components/remote_calendar/coordinator.py index 1eead7682d3..26876b53224 100644 --- a/homeassistant/components/remote_calendar/coordinator.py +++ b/homeassistant/components/remote_calendar/coordinator.py @@ -3,7 +3,7 @@ from datetime import timedelta import logging -from httpx import HTTPError, InvalidURL +from httpx import HTTPError, InvalidURL, TimeoutException from ical.calendar import Calendar from homeassistant.config_entries import ConfigEntry @@ -12,6 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +from .client import get_calendar from .const import DOMAIN from .ics import InvalidIcsException, parse_calendar @@ -36,7 +37,7 @@ class RemoteCalendarDataUpdateCoordinator(DataUpdateCoordinator[Calendar]): super().__init__( hass, _LOGGER, - name=DOMAIN, + name=f"{DOMAIN}_{config_entry.title}", update_interval=SCAN_INTERVAL, always_update=True, ) @@ -46,13 +47,19 @@ class RemoteCalendarDataUpdateCoordinator(DataUpdateCoordinator[Calendar]): async def _async_update_data(self) -> Calendar: """Update data from the url.""" try: - res = await self._client.get(self._url, follow_redirects=True) + res = await get_calendar(self._client, self._url) res.raise_for_status() + except TimeoutException as err: + _LOGGER.debug("%s: %s", self._url, str(err) or type(err).__name__) + raise UpdateFailed( + translation_domain=DOMAIN, + translation_key="timeout", + ) from err except (HTTPError, InvalidURL) as err: + _LOGGER.debug("%s: %s", self._url, str(err) or type(err).__name__) raise UpdateFailed( translation_domain=DOMAIN, translation_key="unable_to_fetch", - translation_placeholders={"err": str(err)}, ) from err try: self.ics = res.text diff --git a/homeassistant/components/remote_calendar/strings.json b/homeassistant/components/remote_calendar/strings.json index ef7f20d4699..48ef6080bdb 100644 --- a/homeassistant/components/remote_calendar/strings.json +++ b/homeassistant/components/remote_calendar/strings.json @@ -18,14 +18,18 @@ "already_configured": "[%key:common::config_flow::abort::already_configured_service%]" }, "error": { + "timeout_connect": "[%key:common::config_flow::error::timeout_connect%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "forbidden": "The server understood the request but refuses to authorize it.", "invalid_ics_file": "There was a problem reading the calendar information. See the error log for additional details." } }, "exceptions": { + "timeout": { + "message": "The connection timed out. See the debug log for additional details." + }, "unable_to_fetch": { - "message": "Unable to fetch calendar data: {err}" + "message": "Unable to fetch calendar data. See the debug log for additional details." }, "unable_to_parse": { "message": "Unable to parse calendar data: {err}" diff --git a/tests/components/remote_calendar/test_config_flow.py b/tests/components/remote_calendar/test_config_flow.py index 9aff1594db3..9bea46ab27e 100644 --- a/tests/components/remote_calendar/test_config_flow.py +++ b/tests/components/remote_calendar/test_config_flow.py @@ -1,6 +1,6 @@ """Test the Remote Calendar config flow.""" -from httpx import ConnectError, Response, UnsupportedProtocol +from httpx import HTTPError, InvalidURL, Response, TimeoutException import pytest import respx @@ -75,10 +75,11 @@ async def test_form_import_webcal(hass: HomeAssistant, ics_content: str) -> None @pytest.mark.parametrize( - ("side_effect"), + ("side_effect", "base_error"), [ - ConnectError("Connection failed"), - UnsupportedProtocol("Unsupported protocol"), + (TimeoutException("Connection timed out"), "timeout_connect"), + (HTTPError("Connection failed"), "cannot_connect"), + (InvalidURL("Unsupported protocol"), "cannot_connect"), ], ) @respx.mock @@ -86,6 +87,7 @@ async def test_form_inavild_url( hass: HomeAssistant, side_effect: Exception, ics_content: str, + base_error: str, ) -> None: """Test we get the import form.""" result = await hass.config_entries.flow.async_init( @@ -102,7 +104,7 @@ async def test_form_inavild_url( }, ) assert result2["type"] is FlowResultType.FORM - assert result2["errors"] == {"base": "cannot_connect"} + assert result2["errors"] == {"base": base_error} respx.get(CALENDER_URL).mock( return_value=Response( status_code=200, diff --git a/tests/components/remote_calendar/test_init.py b/tests/components/remote_calendar/test_init.py index f4ca500b2e1..d3e6b439805 100644 --- a/tests/components/remote_calendar/test_init.py +++ b/tests/components/remote_calendar/test_init.py @@ -1,6 +1,6 @@ """Tests for init platform of Remote Calendar.""" -from httpx import ConnectError, Response, UnsupportedProtocol +from httpx import HTTPError, InvalidURL, Response, TimeoutException import pytest import respx @@ -56,8 +56,9 @@ async def test_raise_for_status( @pytest.mark.parametrize( "side_effect", [ - ConnectError("Connection failed"), - UnsupportedProtocol("Unsupported protocol"), + TimeoutException("Connection timed out"), + HTTPError("Connection failed"), + InvalidURL("Unsupported protocol"), ValueError("Invalid response"), ], ) From 9a4959560e0330d2523f074679a16dfb2ab55d3b Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:51:38 +0200 Subject: [PATCH 02/14] Fix missing port in samsungtv (#147962) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: AbĂ­lio Costa --- .../components/samsungtv/config_flow.py | 25 +++++++++++-------- .../components/samsungtv/test_config_flow.py | 17 +++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/samsungtv/config_flow.py b/homeassistant/components/samsungtv/config_flow.py index dbde1ee1ef3..e2b9f8631d8 100644 --- a/homeassistant/components/samsungtv/config_flow.py +++ b/homeassistant/components/samsungtv/config_flow.py @@ -124,6 +124,7 @@ class SamsungTVConfigFlow(ConfigFlow, domain=DOMAIN): self._model: str | None = None self._connect_result: str | None = None self._method: str | None = None + self._port: int | None = None self._name: str | None = None self._title: str = "" self._id: int | None = None @@ -199,33 +200,37 @@ class SamsungTVConfigFlow(ConfigFlow, domain=DOMAIN): async def _async_create_bridge(self) -> None: """Create the bridge.""" - result, method, _info = await self._async_get_device_info_and_method() + result = await self._async_load_device_info() if result not in SUCCESSFUL_RESULTS: LOGGER.debug("No working config found for %s", self._host) raise AbortFlow(result) - assert method is not None - self._bridge = SamsungTVBridge.get_bridge(self.hass, method, self._host) + assert self._method is not None + self._bridge = SamsungTVBridge.get_bridge( + self.hass, self._method, self._host, self._port + ) - async def _async_get_device_info_and_method( + async def _async_load_device_info( self, - ) -> tuple[str, str | None, dict[str, Any] | None]: + ) -> str: """Get device info and method only once.""" if self._connect_result is None: - result, _, method, info = await async_get_device_info(self.hass, self._host) + result, port, method, info = await async_get_device_info( + self.hass, self._host + ) self._connect_result = result self._method = method + self._port = port self._device_info = info if not method: LOGGER.debug("Host:%s did not return device info", self._host) - return result, None, None - return self._connect_result, self._method, self._device_info + return self._connect_result async def _async_get_and_check_device_info(self) -> bool: """Try to get the device info.""" - result, _method, info = await self._async_get_device_info_and_method() + result = await self._async_load_device_info() if result not in SUCCESSFUL_RESULTS: raise AbortFlow(result) - if not info: + if not (info := self._device_info): return False dev_info = info.get("device", {}) assert dev_info is not None diff --git a/tests/components/samsungtv/test_config_flow.py b/tests/components/samsungtv/test_config_flow.py index d63e5a7ae2a..dd6b21ab5e5 100644 --- a/tests/components/samsungtv/test_config_flow.py +++ b/tests/components/samsungtv/test_config_flow.py @@ -161,6 +161,7 @@ async def test_user_legacy(hass: HomeAssistant) -> None: assert result["data"][CONF_METHOD] == METHOD_LEGACY assert result["data"][CONF_MANUFACTURER] == DEFAULT_MANUFACTURER assert result["data"][CONF_MODEL] is None + assert result["data"][CONF_PORT] == 55000 assert result["result"].unique_id is None @@ -195,6 +196,7 @@ async def test_user_legacy_does_not_ok_first_time(hass: HomeAssistant) -> None: assert result3["data"][CONF_METHOD] == METHOD_LEGACY assert result3["data"][CONF_MANUFACTURER] == DEFAULT_MANUFACTURER assert result3["data"][CONF_MODEL] is None + assert result3["data"][CONF_PORT] == 55000 assert result3["result"].unique_id is None @@ -224,6 +226,7 @@ async def test_user_websocket(hass: HomeAssistant) -> None: assert result["data"][CONF_METHOD] == "websocket" assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["data"][CONF_MODEL] == "82GXARRS" + assert result["data"][CONF_PORT] == 8002 assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4" @@ -272,6 +275,7 @@ async def test_user_encrypted_websocket( assert result4["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result4["data"][CONF_MANUFACTURER] == "Samsung" assert result4["data"][CONF_MODEL] == "UE48JU6400" + assert result4["data"][CONF_PORT] == 8000 assert result4["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION] is None assert result4["data"][CONF_TOKEN] == "037739871315caef138547b03e348b72" assert result4["data"][CONF_SESSION_ID] == "1" @@ -402,6 +406,7 @@ async def test_user_websocket_auth_retry(hass: HomeAssistant) -> None: assert result["data"][CONF_HOST] == "10.20.43.21" assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["data"][CONF_MODEL] == "82GXARRS" + assert result["data"][CONF_PORT] == 8002 assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4" @@ -464,6 +469,7 @@ async def test_ssdp(hass: HomeAssistant) -> None: assert result["data"][CONF_HOST] == "10.10.12.34" assert result["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result["data"][CONF_MODEL] == "UE55H6400" + assert result["data"][CONF_PORT] == 55000 assert result["result"].unique_id == "068e7781-006e-1000-bbbf-84a4668d8423" @@ -522,6 +528,7 @@ async def test_ssdp_noprefix(hass: HomeAssistant) -> None: assert result["data"][CONF_HOST] == "10.10.12.34" assert result["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result["data"][CONF_MODEL] == "UE55H6400" + assert result["data"][CONF_PORT] == 55000 assert result["result"].unique_id == "068e7781-006e-1000-bbbf-84a4668d8423" @@ -557,6 +564,7 @@ async def test_ssdp_legacy_missing_auth(hass: HomeAssistant) -> None: assert result["data"][CONF_HOST] == "10.10.12.34" assert result["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result["data"][CONF_MODEL] == "UE55H6400" + assert result["data"][CONF_PORT] == 55000 assert result["result"].unique_id == "068e7781-006e-1000-bbbf-84a4668d8423" @@ -599,6 +607,7 @@ async def test_ssdp_websocket_success_populates_mac_address_and_ssdp_location( assert result["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result["data"][CONF_MODEL] == "82GXARRS" + assert result["data"][CONF_PORT] == 8002 assert ( result["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION] == "http://10.10.12.34:7676/smp_15_" @@ -630,6 +639,7 @@ async def test_ssdp_websocket_success_populates_mac_address_and_main_tv_ssdp_loc assert result["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result["data"][CONF_MODEL] == "82GXARRS" + assert result["data"][CONF_PORT] == 8002 assert ( result["data"][CONF_SSDP_MAIN_TV_AGENT_LOCATION] == "http://10.10.12.34:7676/smp_2_" @@ -681,6 +691,7 @@ async def test_ssdp_encrypted_websocket_success_populates_mac_address_and_ssdp_l assert result4["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result4["data"][CONF_MANUFACTURER] == "Samsung Electronics" assert result4["data"][CONF_MODEL] == "UE48JU6400" + assert result4["data"][CONF_PORT] == 8000 assert ( result4["data"][CONF_SSDP_RENDERING_CONTROL_LOCATION] == "http://10.10.12.34:7676/smp_15_" @@ -887,6 +898,7 @@ async def test_dhcp_wireless(hass: HomeAssistant) -> None: assert result["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["data"][CONF_MODEL] == "UE48JU6400" + assert result["data"][CONF_PORT] == 8002 assert result["result"].unique_id == "223da676-497a-4e06-9507-5e27ec4f0fb3" @@ -919,6 +931,7 @@ async def test_dhcp_wired(hass: HomeAssistant, rest_api: Mock) -> None: assert result["data"][CONF_MAC] == "aa:ee:tt:hh:ee:rr" assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["data"][CONF_MODEL] == "UE43LS003" + assert result["data"][CONF_PORT] == 8002 assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4" @@ -1020,6 +1033,7 @@ async def test_zeroconf(hass: HomeAssistant) -> None: assert result["data"][CONF_MAC] == "aa:bb:aa:aa:aa:aa" assert result["data"][CONF_MANUFACTURER] == "Samsung" assert result["data"][CONF_MODEL] == "82GXARRS" + assert result["data"][CONF_PORT] == 8002 assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4" @@ -1129,6 +1143,7 @@ async def test_autodetect_websocket(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"][CONF_METHOD] == "websocket" assert result["data"][CONF_TOKEN] == "123456789" + assert result["data"][CONF_PORT] == 8002 remote_websocket.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL) rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL) await hass.async_block_till_done() @@ -1180,6 +1195,7 @@ async def test_websocket_no_mac(hass: HomeAssistant, mac_address: Mock) -> None: assert result["data"][CONF_METHOD] == "websocket" assert result["data"][CONF_TOKEN] == "123456789" assert result["data"][CONF_MAC] == "gg:ee:tt:mm:aa:cc" + assert result["data"][CONF_PORT] == 8002 remote_websocket.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL) rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL) await hass.async_block_till_done() @@ -2091,6 +2107,7 @@ async def test_ssdp_update_mac(hass: HomeAssistant) -> None: assert entry.data[CONF_MANUFACTURER] == DEFAULT_MANUFACTURER assert entry.data[CONF_MODEL] == "fake_model" assert entry.data[CONF_MAC] is None + assert entry.data[CONF_PORT] == 8002 assert entry.unique_id == "123" device_info = deepcopy(MOCK_DEVICE_INFO) From 0f32b6331d8928a5ed814eb39955e0181bcaebe9 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Wed, 2 Jul 2025 15:19:32 -0400 Subject: [PATCH 03/14] Bump ZHA to 0.0.62 (#147966) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../zha/snapshots/test_diagnostics.ambr | 51 ------------------- 4 files changed, 3 insertions(+), 54 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index 4fb5f57320f..2cbc962a305 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -21,7 +21,7 @@ "zha", "universal_silabs_flasher" ], - "requirements": ["zha==0.0.61"], + "requirements": ["zha==0.0.62"], "usb": [ { "vid": "10C4", diff --git a/requirements_all.txt b/requirements_all.txt index 04b3f0eaa2f..4a4454e9dab 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -3190,7 +3190,7 @@ zeroconf==0.147.0 zeversolar==0.3.2 # homeassistant.components.zha -zha==0.0.61 +zha==0.0.62 # homeassistant.components.zhong_hong zhong-hong-hvac==1.0.13 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ea925412def..c40ea6e17fc 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2634,7 +2634,7 @@ zeroconf==0.147.0 zeversolar==0.3.2 # homeassistant.components.zha -zha==0.0.61 +zha==0.0.62 # homeassistant.components.zwave_js zwave-js-server-python==0.65.0 diff --git a/tests/components/zha/snapshots/test_diagnostics.ambr b/tests/components/zha/snapshots/test_diagnostics.ambr index 44fb913489d..35eb320893f 100644 --- a/tests/components/zha/snapshots/test_diagnostics.ambr +++ b/tests/components/zha/snapshots/test_diagnostics.ambr @@ -168,7 +168,6 @@ dict({ 'id': '0x0010', 'name': 'cie_addr', - 'unsupported': False, 'value': list([ 50, 79, @@ -181,68 +180,18 @@ ]), 'zcl_type': 'EUI64', }), - dict({ - 'id': '0x0013', - 'name': 'current_zone_sensitivity_level', - 'unsupported': False, - 'value': None, - 'zcl_type': 'uint8', - }), dict({ 'id': '0x0012', 'name': 'num_zone_sensitivity_levels_supported', 'unsupported': True, - 'value': None, 'zcl_type': 'uint8', }), - dict({ - 'id': '0x0011', - 'name': 'zone_id', - 'unsupported': False, - 'value': None, - 'zcl_type': 'uint8', - }), - dict({ - 'id': '0x0000', - 'name': 'zone_state', - 'unsupported': False, - 'value': None, - 'zcl_type': 'enum8', - }), - dict({ - 'id': '0x0002', - 'name': 'zone_status', - 'unsupported': False, - 'value': None, - 'zcl_type': 'map16', - }), - dict({ - 'id': '0x0001', - 'name': 'zone_type', - 'unsupported': False, - 'value': None, - 'zcl_type': 'uint16', - }), ]), 'cluster_id': '0x0500', 'endpoint_attribute': 'ias_zone', }), dict({ 'attributes': list([ - dict({ - 'id': '0xfffd', - 'name': 'cluster_revision', - 'unsupported': False, - 'value': None, - 'zcl_type': 'uint16', - }), - dict({ - 'id': '0xfffe', - 'name': 'reporting_status', - 'unsupported': False, - 'value': None, - 'zcl_type': 'enum8', - }), ]), 'cluster_id': '0x0501', 'endpoint_attribute': 'ias_ace', From a2ffe32b025e3ecf2150c48f409d609f9bc22ecd Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Wed, 2 Jul 2025 23:10:21 +0200 Subject: [PATCH 04/14] Bump aiounifi to v84 (#147987) --- homeassistant/components/unifi/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/unifi/manifest.json b/homeassistant/components/unifi/manifest.json index dd255c57c13..d13b180d62d 100644 --- a/homeassistant/components/unifi/manifest.json +++ b/homeassistant/components/unifi/manifest.json @@ -7,7 +7,7 @@ "integration_type": "hub", "iot_class": "local_push", "loggers": ["aiounifi"], - "requirements": ["aiounifi==83"], + "requirements": ["aiounifi==84"], "ssdp": [ { "manufacturer": "Ubiquiti Networks", diff --git a/requirements_all.txt b/requirements_all.txt index 4a4454e9dab..2fece9385aa 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -414,7 +414,7 @@ aiotedee==0.2.25 aiotractive==0.6.0 # homeassistant.components.unifi -aiounifi==83 +aiounifi==84 # homeassistant.components.usb aiousbwatcher==1.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c40ea6e17fc..6118a3ede0b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -396,7 +396,7 @@ aiotedee==0.2.25 aiotractive==0.6.0 # homeassistant.components.unifi -aiounifi==83 +aiounifi==84 # homeassistant.components.usb aiousbwatcher==1.1.1 From c23bfb1b39d083ce2fae27f0545d7061b8608736 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Thu, 3 Jul 2025 08:50:41 +0200 Subject: [PATCH 05/14] Fix state being incorrectly reported in some situations on Music Assistant players (#147997) --- homeassistant/components/music_assistant/manifest.json | 2 +- homeassistant/components/music_assistant/media_player.py | 2 -- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/music_assistant/manifest.json b/homeassistant/components/music_assistant/manifest.json index e29491e2b21..4b28a1029a4 100644 --- a/homeassistant/components/music_assistant/manifest.json +++ b/homeassistant/components/music_assistant/manifest.json @@ -7,6 +7,6 @@ "documentation": "https://www.home-assistant.io/integrations/music_assistant", "iot_class": "local_push", "loggers": ["music_assistant"], - "requirements": ["music-assistant-client==1.2.3"], + "requirements": ["music-assistant-client==1.2.4"], "zeroconf": ["_mass._tcp.local."] } diff --git a/homeassistant/components/music_assistant/media_player.py b/homeassistant/components/music_assistant/media_player.py index b748aad241c..3a210856391 100644 --- a/homeassistant/components/music_assistant/media_player.py +++ b/homeassistant/components/music_assistant/media_player.py @@ -248,8 +248,6 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity): player = self.player active_queue = self.active_queue # update generic attributes - if player.powered and active_queue is not None: - self._attr_state = MediaPlayerState(active_queue.state.value) if player.powered and player.playback_state is not None: self._attr_state = MediaPlayerState(player.playback_state.value) else: diff --git a/requirements_all.txt b/requirements_all.txt index 2fece9385aa..e67b8687e5d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1467,7 +1467,7 @@ mozart-api==4.1.1.116.4 mullvad-api==1.0.0 # homeassistant.components.music_assistant -music-assistant-client==1.2.3 +music-assistant-client==1.2.4 # homeassistant.components.tts mutagen==1.47.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6118a3ede0b..ca114781c23 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1259,7 +1259,7 @@ mozart-api==4.1.1.116.4 mullvad-api==1.0.0 # homeassistant.components.music_assistant -music-assistant-client==1.2.3 +music-assistant-client==1.2.4 # homeassistant.components.tts mutagen==1.47.0 From f806e6ba49687105249baed3a242d74adbd29eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 3 Jul 2025 13:24:51 +0100 Subject: [PATCH 06/14] Bump hass-nabucasa from 0.104.0 to 0.105.0 (#148040) --- homeassistant/components/cloud/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/cloud/manifest.json b/homeassistant/components/cloud/manifest.json index 70cf6a2c072..0d44d57ac5e 100644 --- a/homeassistant/components/cloud/manifest.json +++ b/homeassistant/components/cloud/manifest.json @@ -13,6 +13,6 @@ "integration_type": "system", "iot_class": "cloud_push", "loggers": ["acme", "hass_nabucasa", "snitun"], - "requirements": ["hass-nabucasa==0.104.0"], + "requirements": ["hass-nabucasa==0.105.0"], "single_config_entry": true } diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index f0fa428fbb3..e666f06c5f2 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -35,7 +35,7 @@ fnv-hash-fast==1.5.0 go2rtc-client==0.2.1 ha-ffmpeg==3.2.2 habluetooth==3.49.0 -hass-nabucasa==0.104.0 +hass-nabucasa==0.105.0 hassil==2.2.3 home-assistant-bluetooth==1.13.1 home-assistant-frontend==20250702.0 diff --git a/pyproject.toml b/pyproject.toml index c34a268e347..77d788a1dd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ dependencies = [ "fnv-hash-fast==1.5.0", # hass-nabucasa is imported by helpers which don't depend on the cloud # integration - "hass-nabucasa==0.104.0", + "hass-nabucasa==0.105.0", # When bumping httpx, please check the version pins of # httpcore, anyio, and h11 in gen_requirements_all "httpx==0.28.1", diff --git a/requirements.txt b/requirements.txt index 1791d12268b..011d76e66b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ certifi>=2021.5.30 ciso8601==2.3.2 cronsim==2.6 fnv-hash-fast==1.5.0 -hass-nabucasa==0.104.0 +hass-nabucasa==0.105.0 httpx==0.28.1 home-assistant-bluetooth==1.13.1 ifaddr==0.2.0 diff --git a/requirements_all.txt b/requirements_all.txt index e67b8687e5d..dd663763a54 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1127,7 +1127,7 @@ habiticalib==0.4.0 habluetooth==3.49.0 # homeassistant.components.cloud -hass-nabucasa==0.104.0 +hass-nabucasa==0.105.0 # homeassistant.components.splunk hass-splunk==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ca114781c23..f624e1d552b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -988,7 +988,7 @@ habiticalib==0.4.0 habluetooth==3.49.0 # homeassistant.components.cloud -hass-nabucasa==0.104.0 +hass-nabucasa==0.105.0 # homeassistant.components.assist_satellite # homeassistant.components.conversation From 898ef43750b1c7bd2e304f01f635e2603b1d61ee Mon Sep 17 00:00:00 2001 From: hanwg Date: Fri, 4 Jul 2025 22:32:46 +0800 Subject: [PATCH 07/14] Fix Telegram bots using plain text parser failing to load on restart (#148050) --- homeassistant/components/telegram_bot/bot.py | 6 +++--- homeassistant/components/telegram_bot/config_flow.py | 2 -- homeassistant/components/telegram_bot/services.yaml | 5 +++++ tests/components/telegram_bot/test_config_flow.py | 2 +- tests/components/telegram_bot/test_telegram_bot.py | 5 ++++- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/telegram_bot/bot.py b/homeassistant/components/telegram_bot/bot.py index a3feb120460..c57648c9551 100644 --- a/homeassistant/components/telegram_bot/bot.py +++ b/homeassistant/components/telegram_bot/bot.py @@ -374,9 +374,7 @@ class TelegramNotificationService: } if data is not None: if ATTR_PARSER in data: - params[ATTR_PARSER] = self._parsers.get( - data[ATTR_PARSER], self.parse_mode - ) + params[ATTR_PARSER] = data[ATTR_PARSER] if ATTR_TIMEOUT in data: params[ATTR_TIMEOUT] = data[ATTR_TIMEOUT] if ATTR_DISABLE_NOTIF in data: @@ -408,6 +406,8 @@ class TelegramNotificationService: params[ATTR_REPLYMARKUP] = InlineKeyboardMarkup( [_make_row_inline_keyboard(row) for row in keys] ) + if params[ATTR_PARSER] == PARSER_PLAIN_TEXT: + params[ATTR_PARSER] = None return params async def _send_msg( diff --git a/homeassistant/components/telegram_bot/config_flow.py b/homeassistant/components/telegram_bot/config_flow.py index 41f26ccd48d..8d3d9b0cd7b 100644 --- a/homeassistant/components/telegram_bot/config_flow.py +++ b/homeassistant/components/telegram_bot/config_flow.py @@ -159,8 +159,6 @@ class OptionsFlowHandler(OptionsFlow): """Manage the options.""" if user_input is not None: - if user_input[ATTR_PARSER] == PARSER_PLAIN_TEXT: - user_input[ATTR_PARSER] = None return self.async_create_entry(data=user_input) return self.async_show_form( diff --git a/homeassistant/components/telegram_bot/services.yaml b/homeassistant/components/telegram_bot/services.yaml index d5fc0e134d5..b1d94d381ac 100644 --- a/homeassistant/components/telegram_bot/services.yaml +++ b/homeassistant/components/telegram_bot/services.yaml @@ -109,6 +109,7 @@ send_photo: - "markdown" - "markdownv2" - "plain_text" + translation_key: "parse_mode" disable_notification: selector: boolean: @@ -261,6 +262,7 @@ send_animation: - "markdown" - "markdownv2" - "plain_text" + translation_key: "parse_mode" disable_notification: selector: boolean: @@ -341,6 +343,7 @@ send_video: - "markdown" - "markdownv2" - "plain_text" + translation_key: "parse_mode" disable_notification: selector: boolean: @@ -493,6 +496,7 @@ send_document: - "markdown" - "markdownv2" - "plain_text" + translation_key: "parse_mode" disable_notification: selector: boolean: @@ -670,6 +674,7 @@ edit_message: - "markdown" - "markdownv2" - "plain_text" + translation_key: "parse_mode" disable_web_page_preview: selector: boolean: diff --git a/tests/components/telegram_bot/test_config_flow.py b/tests/components/telegram_bot/test_config_flow.py index 2586761b584..9a076016a32 100644 --- a/tests/components/telegram_bot/test_config_flow.py +++ b/tests/components/telegram_bot/test_config_flow.py @@ -63,7 +63,7 @@ async def test_options_flow( await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY - assert result["data"][ATTR_PARSER] is None + assert result["data"][ATTR_PARSER] == PARSER_PLAIN_TEXT async def test_reconfigure_flow_broadcast( diff --git a/tests/components/telegram_bot/test_telegram_bot.py b/tests/components/telegram_bot/test_telegram_bot.py index 6590bbed1cf..73dd9e27763 100644 --- a/tests/components/telegram_bot/test_telegram_bot.py +++ b/tests/components/telegram_bot/test_telegram_bot.py @@ -50,6 +50,7 @@ from homeassistant.components.telegram_bot.const import ( ATTR_VERIFY_SSL, CONF_CONFIG_ENTRY_ID, DOMAIN, + PARSER_PLAIN_TEXT, PLATFORM_BROADCAST, SECTION_ADVANCED_SETTINGS, SERVICE_ANSWER_CALLBACK_QUERY, @@ -183,6 +184,7 @@ async def test_send_message( ( { ATTR_MESSAGE: "test_message", + ATTR_PARSER: PARSER_PLAIN_TEXT, ATTR_KEYBOARD_INLINE: "command1:/cmd1,/cmd2,mock_link:https://mock_link", }, InlineKeyboardMarkup( @@ -199,6 +201,7 @@ async def test_send_message( ( { ATTR_MESSAGE: "test_message", + ATTR_PARSER: PARSER_PLAIN_TEXT, ATTR_KEYBOARD_INLINE: [ [["command1", "/cmd1"]], [["mock_link", "https://mock_link"]], @@ -250,7 +253,7 @@ async def test_send_message_with_inline_keyboard( mock_send_message.assert_called_once_with( 12345678, "test_message", - parse_mode=ParseMode.MARKDOWN, + parse_mode=None, disable_web_page_preview=None, disable_notification=False, reply_to_message_id=None, From f42e7d982f78d2c4ee99fa813d14d600f1a4cf40 Mon Sep 17 00:00:00 2001 From: Arie Catsman <120491684+catsmanac@users.noreply.github.com> Date: Thu, 3 Jul 2025 21:04:13 +0200 Subject: [PATCH 08/14] Bump pyenphase to 2.2.0 (#148070) --- homeassistant/components/enphase_envoy/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/enphase_envoy/manifest.json b/homeassistant/components/enphase_envoy/manifest.json index 5f74da954a0..8387ecc9c9f 100644 --- a/homeassistant/components/enphase_envoy/manifest.json +++ b/homeassistant/components/enphase_envoy/manifest.json @@ -7,7 +7,7 @@ "iot_class": "local_polling", "loggers": ["pyenphase"], "quality_scale": "platinum", - "requirements": ["pyenphase==2.1.0"], + "requirements": ["pyenphase==2.2.0"], "zeroconf": [ { "type": "_enphase-envoy._tcp.local." diff --git a/requirements_all.txt b/requirements_all.txt index dd663763a54..fb548289de5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1962,7 +1962,7 @@ pyeiscp==0.0.7 pyemoncms==0.1.1 # homeassistant.components.enphase_envoy -pyenphase==2.1.0 +pyenphase==2.2.0 # homeassistant.components.envisalink pyenvisalink==4.7 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f624e1d552b..e3b58a5dfe8 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1637,7 +1637,7 @@ pyeiscp==0.0.7 pyemoncms==0.1.1 # homeassistant.components.enphase_envoy -pyenphase==2.1.0 +pyenphase==2.2.0 # homeassistant.components.everlights pyeverlights==0.1.0 From eb58c10e5ee87d0d0098c868de2acba3a4284ac0 Mon Sep 17 00:00:00 2001 From: Arie Catsman <120491684+catsmanac@users.noreply.github.com> Date: Thu, 3 Jul 2025 22:06:38 +0200 Subject: [PATCH 09/14] Cancel enphase mac verification on unload. (#148072) --- homeassistant/components/enphase_envoy/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/enphase_envoy/__init__.py b/homeassistant/components/enphase_envoy/__init__.py index eee6cb85e6d..f43d89aa098 100644 --- a/homeassistant/components/enphase_envoy/__init__.py +++ b/homeassistant/components/enphase_envoy/__init__.py @@ -63,6 +63,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: EnphaseConfigEntry) -> coordinator = entry.runtime_data coordinator.async_cancel_token_refresh() coordinator.async_cancel_firmware_refresh() + coordinator.async_cancel_mac_verification() return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) From 342b4c344249340a9f3f44538d164325e6cb6dea Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Fri, 4 Jul 2025 17:33:16 +0300 Subject: [PATCH 10/14] Bump aioamazondevices to 3.2.3 (#148082) --- homeassistant/components/alexa_devices/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/alexa_devices/manifest.json b/homeassistant/components/alexa_devices/manifest.json index 7c23edd92ce..70281390436 100644 --- a/homeassistant/components/alexa_devices/manifest.json +++ b/homeassistant/components/alexa_devices/manifest.json @@ -8,5 +8,5 @@ "iot_class": "cloud_polling", "loggers": ["aioamazondevices"], "quality_scale": "bronze", - "requirements": ["aioamazondevices==3.2.2"] + "requirements": ["aioamazondevices==3.2.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index fb548289de5..cae697cdfe9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -185,7 +185,7 @@ aioairzone-cloud==0.6.12 aioairzone==1.0.0 # homeassistant.components.alexa_devices -aioamazondevices==3.2.2 +aioamazondevices==3.2.3 # homeassistant.components.ambient_network # homeassistant.components.ambient_station diff --git a/requirements_test_all.txt b/requirements_test_all.txt index e3b58a5dfe8..de092158c7e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -173,7 +173,7 @@ aioairzone-cloud==0.6.12 aioairzone==1.0.0 # homeassistant.components.alexa_devices -aioamazondevices==3.2.2 +aioamazondevices==3.2.3 # homeassistant.components.ambient_network # homeassistant.components.ambient_station From c646658643a8d2e056d229498b0e70385f90a11d Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 4 Jul 2025 16:25:28 +0200 Subject: [PATCH 11/14] Update frontend to 20250702.1 (#148131) --- 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 bfd868a5334..748d8f0c6f0 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==20250702.0"] + "requirements": ["home-assistant-frontend==20250702.1"] } diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index e666f06c5f2..824c3d945fe 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -38,7 +38,7 @@ habluetooth==3.49.0 hass-nabucasa==0.105.0 hassil==2.2.3 home-assistant-bluetooth==1.13.1 -home-assistant-frontend==20250702.0 +home-assistant-frontend==20250702.1 home-assistant-intents==2025.6.23 httpx==0.28.1 ifaddr==0.2.0 diff --git a/requirements_all.txt b/requirements_all.txt index cae697cdfe9..04ed2500e01 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1168,7 +1168,7 @@ hole==0.8.0 holidays==0.75 # homeassistant.components.frontend -home-assistant-frontend==20250702.0 +home-assistant-frontend==20250702.1 # homeassistant.components.conversation home-assistant-intents==2025.6.23 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index de092158c7e..fede2337353 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1017,7 +1017,7 @@ hole==0.8.0 holidays==0.75 # homeassistant.components.frontend -home-assistant-frontend==20250702.0 +home-assistant-frontend==20250702.1 # homeassistant.components.conversation home-assistant-intents==2025.6.23 From 3ffec2a655f74ac805d32f78164a14cad25678b3 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 4 Jul 2025 16:22:38 +0200 Subject: [PATCH 12/14] [ci] Fix typing issue with aiohttp and aiosignal (#148141) --- .github/workflows/ci.yaml | 2 +- homeassistant/components/http/ban.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 19cc8bd3af7..c5491df0021 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,7 +37,7 @@ on: type: boolean env: - CACHE_VERSION: 3 + CACHE_VERSION: 4 UV_CACHE_VERSION: 1 MYPY_CACHE_VERSION: 1 HA_SHORT_VERSION: "2025.7" diff --git a/homeassistant/components/http/ban.py b/homeassistant/components/http/ban.py index 71f3d54bef6..7e55191639b 100644 --- a/homeassistant/components/http/ban.py +++ b/homeassistant/components/http/ban.py @@ -64,7 +64,7 @@ def setup_bans(hass: HomeAssistant, app: Application, login_threshold: int) -> N """Initialize bans when app starts up.""" await app[KEY_BAN_MANAGER].async_load() - app.on_startup.append(ban_startup) + app.on_startup.append(ban_startup) # type: ignore[arg-type] @middleware From 4e163c4591529f09b90f1fb4d299a00663fac563 Mon Sep 17 00:00:00 2001 From: Michael Freeman Date: Fri, 4 Jul 2025 11:46:59 -0400 Subject: [PATCH 13/14] Bump venstarcolortouch to 0.21 (#148152) --- homeassistant/components/venstar/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/venstar/manifest.json b/homeassistant/components/venstar/manifest.json index f3045fe49e8..5991dc8fe51 100644 --- a/homeassistant/components/venstar/manifest.json +++ b/homeassistant/components/venstar/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/venstar", "iot_class": "local_polling", "loggers": ["venstarcolortouch"], - "requirements": ["venstarcolortouch==0.19"] + "requirements": ["venstarcolortouch==0.21"] } diff --git a/requirements_all.txt b/requirements_all.txt index 04ed2500e01..fcd97e305fc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -3041,7 +3041,7 @@ vehicle==2.2.2 velbus-aio==2025.5.0 # homeassistant.components.venstar -venstarcolortouch==0.19 +venstarcolortouch==0.21 # homeassistant.components.vilfo vilfo-api-client==0.5.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fede2337353..a234822689c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2509,7 +2509,7 @@ vehicle==2.2.2 velbus-aio==2025.5.0 # homeassistant.components.venstar -venstarcolortouch==0.19 +venstarcolortouch==0.21 # homeassistant.components.vilfo vilfo-api-client==0.5.0 From a274961593b41bd2a2aa950427a437da55914b4e Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 4 Jul 2025 19:22:41 +0000 Subject: [PATCH 14/14] Bump version to 2025.7.1 --- 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 f1a9f7f79c2..258a9c9a48f 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2025 MINOR_VERSION: Final = 7 -PATCH_VERSION: Final = "0" +PATCH_VERSION: Final = "1" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 13, 2) diff --git a/pyproject.toml b/pyproject.toml index 77d788a1dd0..b4478a69d53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2025.7.0" +version = "2025.7.1" license = "Apache-2.0" license-files = ["LICENSE*", "homeassistant/backports/LICENSE*"] description = "Open-source home automation platform running on Python 3."