Skip to content
Merged

2025.8.3 #151008

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c30d778
Bump to zcc-helper==3.6 (#150608)
markhannon Aug 19, 2025
4e52826
fix(amberelectric): add request timeouts (#150613)
JP-Ellis Aug 20, 2025
932c5cc
Bump renault-api to 0.4.0 (#150624)
epenet Aug 19, 2025
3dd091d
Update hassfest package exceptions (#150744)
cdce8p Aug 16, 2025
122af46
Bump boschshcpy to 0.2.107 (#150754)
tschamm Aug 16, 2025
199b7e8
Fix for bosch_shc: 'device_registry.async_get_or_create' referencing …
tschamm Aug 17, 2025
332996c
Fix volume step error in Squeezebox media player (#150760)
peteS-UK Aug 17, 2025
27b32c5
Show charging power as 0 when not charging for the Volvo integration …
thomasddn Aug 19, 2025
38aba81
Pin gql to 3.5.3 (#150800)
joostlek Aug 17, 2025
81377be
Bump opower to 0.15.2 (#150809)
tronikos Aug 17, 2025
1ca6c4b
Include device data in Withings diagnostics (#150816)
joostlek Aug 18, 2025
92b988a
Abort Nanoleaf discovery flows with user flow (#150818)
joostlek Aug 18, 2025
4b2a149
Bump yt-dlp to 2025.08.11 (#150821)
joostlek Aug 18, 2025
7639e12
Initialize the coordinator's data to include data.options. (#150839)
LG-ThinQ-Integration Aug 21, 2025
fe71b54
Handle Z-Wave RssiErrorReceived (#150846)
MartinHjelmare Aug 18, 2025
59d7313
Use correct unit and class for the Imeon inverter sensors (#150847)
Imeon-Energy Aug 19, 2025
9457710
Bump holidays to 0.79 (#150857)
gjohansson-ST Aug 18, 2025
a3f5c3f
Bump aiorussound to 4.8.1 (#150858)
noahhusby Aug 19, 2025
d169822
Add missing unsupported reasons to list (#150866)
agners Aug 19, 2025
cb8669c
Fix icloud service calls (#150881)
epenet Aug 19, 2025
6383f93
Bump pysmartthings to 3.2.9 (#150892)
joostlek Aug 20, 2025
0cd28e7
Fix PWA theme color to match darker blue color scheme in 2025.8 (#150…
balloob Aug 19, 2025
9414356
Bump bleak-retry-connector to 4.0.2 (#150899)
bdraco Aug 19, 2025
e4329ab
update pyatmo to v9.2.3 (#150900)
cgtobi Aug 20, 2025
1bd5aa0
Fix structured output object selector conversion for OpenAI (#150916)
balloob Aug 19, 2025
bb96602
Matter valve Open command doesn't support TargetLevel=0 (#150922)
kepstin Aug 21, 2025
2e7821d
Bump ESPHome minimum stable BLE version to 2025.8.0 (#150924)
bdraco Aug 20, 2025
9194ddd
Bump imgw-pib to version 1.5.4 (#150930)
bieniu Aug 20, 2025
add75e0
Fix update retry for Imeon inverter integration (#150936)
Imeon-Energy Aug 21, 2025
2f4e29b
Bump python-mystrom to 2.5.0 (#150947)
elsi06 Aug 21, 2025
2dad6fa
Ask user for Z-Wave RF region if country is missing (#150959)
MartinHjelmare Aug 21, 2025
edc1989
Bump onvif-zeep-async to 4.0.4 (#150969)
bdraco Aug 21, 2025
71b2d46
Except ujson from license check (#150980)
emontnemery Aug 21, 2025
82f94de
Enable country site autodetection in Alexa Devices (#150989)
chemelli74 Aug 21, 2025
61a50e7
Update frontend to 20250811.1 (#151005)
bramkragten Aug 21, 2025
bb4f8ad
Bump version to 2025.8.3
balloob Aug 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ on:
type: boolean

env:
CACHE_VERSION: 4
CACHE_VERSION: 6
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2025.8"
Expand Down
30 changes: 28 additions & 2 deletions homeassistant/components/alexa_devices/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Alexa Devices integration."""

from homeassistant.const import Platform
from homeassistant.const import CONF_COUNTRY, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.typing import ConfigType

from .const import DOMAIN
from .const import _LOGGER, COUNTRY_DOMAINS, DOMAIN
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
from .services import async_setup_services

Expand Down Expand Up @@ -40,6 +40,32 @@ async def async_setup_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bo
return True


async def async_migrate_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bool:
"""Migrate old entry."""
if entry.version == 1 and entry.minor_version == 0:
_LOGGER.debug(
"Migrating from version %s.%s", entry.version, entry.minor_version
)

# Convert country in domain
country = entry.data[CONF_COUNTRY]
domain = COUNTRY_DOMAINS.get(country, country)

# Save domain and remove country
new_data = entry.data.copy()
new_data.update({"site": f"https://www.amazon.{domain}"})

hass.config_entries.async_update_entry(
entry, data=new_data, version=1, minor_version=1
)

_LOGGER.info(
"Migration to version %s.%s successful", entry.version, entry.minor_version
)

return True


async def async_unload_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
13 changes: 4 additions & 9 deletions homeassistant/components/alexa_devices/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@
CannotAuthenticate,
CannotConnect,
CannotRetrieveData,
WrongCountry,
)
import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_CODE, CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_CODE, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.selector import CountrySelector

from .const import CONF_LOGIN_DATA, DOMAIN

Expand All @@ -37,7 +35,6 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
session = aiohttp_client.async_create_clientsession(hass)
api = AmazonEchoApi(
session,
data[CONF_COUNTRY],
data[CONF_USERNAME],
data[CONF_PASSWORD],
)
Expand All @@ -48,6 +45,9 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Alexa Devices."""

VERSION = 1
MINOR_VERSION = 1

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
Expand All @@ -62,8 +62,6 @@ async def async_step_user(
errors["base"] = "invalid_auth"
except CannotRetrieveData:
errors["base"] = "cannot_retrieve_data"
except WrongCountry:
errors["base"] = "wrong_country"
else:
await self.async_set_unique_id(data["customer_info"]["user_id"])
self._abort_if_unique_id_configured()
Expand All @@ -78,9 +76,6 @@ async def async_step_user(
errors=errors,
data_schema=vol.Schema(
{
vol.Required(
CONF_COUNTRY, default=self.hass.config.country
): CountrySelector(),
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_CODE): cv.string,
Expand Down
19 changes: 19 additions & 0 deletions homeassistant/components/alexa_devices/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,22 @@

DOMAIN = "alexa_devices"
CONF_LOGIN_DATA = "login_data"

DEFAULT_DOMAIN = {"domain": "com"}
COUNTRY_DOMAINS = {
"ar": DEFAULT_DOMAIN,
"at": DEFAULT_DOMAIN,
"au": {"domain": "com.au"},
"be": {"domain": "com.be"},
"br": DEFAULT_DOMAIN,
"gb": {"domain": "co.uk"},
"il": DEFAULT_DOMAIN,
"jp": {"domain": "co.jp"},
"mx": {"domain": "com.mx"},
"no": DEFAULT_DOMAIN,
"nz": {"domain": "com.au"},
"pl": DEFAULT_DOMAIN,
"tr": {"domain": "com.tr"},
"us": DEFAULT_DOMAIN,
"za": {"domain": "co.za"},
}
3 changes: 1 addition & 2 deletions homeassistant/components/alexa_devices/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from aiohttp import ClientSession

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
Expand Down Expand Up @@ -44,7 +44,6 @@ def __init__(
)
self.api = AmazonEchoApi(
session,
entry.data[CONF_COUNTRY],
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
entry.data[CONF_LOGIN_DATA],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/alexa_devices/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "cloud_polling",
"loggers": ["aioamazondevices"],
"quality_scale": "silver",
"requirements": ["aioamazondevices==4.0.0"]
"requirements": ["aioamazondevices==5.0.0"]
}
4 changes: 0 additions & 4 deletions homeassistant/components/alexa_devices/strings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"common": {
"data_code": "One-time password (OTP code)",
"data_description_country": "The country where your Amazon account is registered.",
"data_description_username": "The email address of your Amazon account.",
"data_description_password": "The password of your Amazon account.",
"data_description_code": "The one-time password to log in to your account. Currently, only tokens from OTP applications are supported.",
Expand All @@ -12,13 +11,11 @@
"step": {
"user": {
"data": {
"country": "[%key:common::config_flow::data::country%]",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]",
"code": "[%key:component::alexa_devices::common::data_code%]"
},
"data_description": {
"country": "[%key:component::alexa_devices::common::data_description_country%]",
"username": "[%key:component::alexa_devices::common::data_description_username%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
Expand Down Expand Up @@ -46,7 +43,6 @@
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"cannot_retrieve_data": "Unable to retrieve data from Amazon. Please try again later.",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"wrong_country": "Wrong country selected. Please select the country where your Amazon account is registered.",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/amberelectric/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
SelectSelectorMode,
)

from .const import CONF_SITE_ID, CONF_SITE_NAME, DOMAIN
from .const import CONF_SITE_ID, CONF_SITE_NAME, DOMAIN, REQUEST_TIMEOUT

API_URL = "https://app.amber.com.au/developers"

Expand Down Expand Up @@ -64,7 +64,9 @@ def _fetch_sites(self, token: str) -> list[Site] | None:
api = amberelectric.AmberApi(api_client)

try:
sites: list[Site] = filter_sites(api.get_sites())
sites: list[Site] = filter_sites(
api.get_sites(_request_timeout=REQUEST_TIMEOUT)
)
except amberelectric.ApiException as api_exception:
if api_exception.status == 403:
self._errors[CONF_API_TOKEN] = "invalid_api_token"
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/amberelectric/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@
GENERAL_CHANNEL = "general"
CONTROLLED_LOAD_CHANNEL = "controlled_load"
FEED_IN_CHANNEL = "feed_in"

REQUEST_TIMEOUT = 15
8 changes: 6 additions & 2 deletions homeassistant/components/amberelectric/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import LOGGER
from .const import LOGGER, REQUEST_TIMEOUT
from .helpers import normalize_descriptor

type AmberConfigEntry = ConfigEntry[AmberUpdateCoordinator]
Expand Down Expand Up @@ -82,7 +82,11 @@ def update_price_data(self) -> dict[str, dict[str, Any]]:
"grid": {},
}
try:
data = self._api.get_current_prices(self.site_id, next=288)
data = self._api.get_current_prices(
self.site_id,
next=288,
_request_timeout=REQUEST_TIMEOUT,
)
intervals = [interval.actual_instance for interval in data]
except ApiException as api_exception:
raise UpdateFailed("Missing price data, skipping update") from api_exception
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/bluetooth/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"quality_scale": "internal",
"requirements": [
"bleak==1.0.1",
"bleak-retry-connector==4.0.1",
"bleak-retry-connector==4.0.2",
"bluetooth-adapters==2.0.0",
"bluetooth-auto-recovery==1.5.2",
"bluetooth-data-tools==1.28.2",
Expand Down
7 changes: 1 addition & 6 deletions homeassistant/components/bosch_shc/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,7 @@ def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
manufacturer=device.manufacturer,
model=device.device_model,
name=device.name,
via_device=(
DOMAIN,
device.parent_device_id
if device.parent_device_id is not None
else parent_id,
),
via_device=(DOMAIN, device.root_device_id),
)
super().__init__(device=device, parent_id=parent_id, entry_id=entry_id)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/bosch_shc/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"documentation": "https://www.home-assistant.io/integrations/bosch_shc",
"iot_class": "local_push",
"loggers": ["boschshcpy"],
"requirements": ["boschshcpy==0.2.91"],
"requirements": ["boschshcpy==0.2.107"],
"zeroconf": [
{
"type": "_http._tcp.local.",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/esphome/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

DEFAULT_PORT: Final = 6053

STABLE_BLE_VERSION_STR = "2025.5.0"
STABLE_BLE_VERSION_STR = "2025.8.0"
STABLE_BLE_VERSION = AwesomeVersion(STABLE_BLE_VERSION_STR)
PROJECT_URLS = {
"esphome.bluetooth-proxy": "https://esphome.github.io/bluetooth-proxies/",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
CONF_FRONTEND_REPO = "development_repo"
CONF_JS_VERSION = "javascript_version"

DEFAULT_THEME_COLOR = "#03A9F4"
DEFAULT_THEME_COLOR = "#2980b9"


DATA_PANELS: HassKey[dict[str, Panel]] = HassKey("frontend_panels")
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20250811.0"]
"requirements": ["home-assistant-frontend==20250811.1"]
}
4 changes: 3 additions & 1 deletion homeassistant/components/hassio/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,27 @@

UNSUPPORTED_REASONS = {
"apparmor",
"cgroup_version",
"connectivity_check",
"content_trust",
"dbus",
"dns_server",
"docker_configuration",
"docker_version",
"cgroup_version",
"job_conditions",
"lxc",
"network_manager",
"os",
"os_agent",
"os_version",
"restart_policy",
"software",
"source_mods",
"supervisor_version",
"systemd",
"systemd_journal",
"systemd_resolved",
"virtualization_image",
}
# Some unsupported reasons also mark the system as unhealthy. If the unsupported reason
# provides no additional information beyond the unhealthy one then skip that repair.
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/holiday/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/holiday",
"iot_class": "local_polling",
"requirements": ["holidays==0.78", "babel==2.15.0"]
"requirements": ["holidays==0.79", "babel==2.15.0"]
}
25 changes: 11 additions & 14 deletions homeassistant/components/icloud/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from homeassistant.helpers import config_validation as cv
from homeassistant.util import slugify

from .account import IcloudAccount
from .account import IcloudAccount, IcloudConfigEntry
from .const import (
ATTR_ACCOUNT,
ATTR_DEVICE_NAME,
Expand Down Expand Up @@ -92,8 +92,10 @@ def lost_device(service: ServiceCall) -> None:
def update_account(service: ServiceCall) -> None:
"""Call the update function of an iCloud account."""
if (account := service.data.get(ATTR_ACCOUNT)) is None:
for account in service.hass.data[DOMAIN].values():
account.keep_alive()
# Update all accounts when no specific account is provided
entry: IcloudConfigEntry
for entry in service.hass.config_entries.async_loaded_entries(DOMAIN):
entry.runtime_data.keep_alive()
else:
_get_account(service.hass, account).keep_alive()

Expand All @@ -102,17 +104,12 @@ def _get_account(hass: HomeAssistant, account_identifier: str) -> IcloudAccount:
if account_identifier is None:
return None

icloud_account: IcloudAccount | None = hass.data[DOMAIN].get(account_identifier)
if icloud_account is None:
for account in hass.data[DOMAIN].values():
if account.username == account_identifier:
icloud_account = account

if icloud_account is None:
raise ValueError(
f"No iCloud account with username or name {account_identifier}"
)
return icloud_account
entry: IcloudConfigEntry
for entry in hass.config_entries.async_loaded_entries(DOMAIN):
if entry.runtime_data.username == account_identifier:
return entry.runtime_data

raise ValueError(f"No iCloud account with username or name {account_identifier}")


@callback
Expand Down
10 changes: 4 additions & 6 deletions homeassistant/components/imeon_inverter/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,11 @@ async def _async_update_data(self) -> dict[str, str | float | int]:
data: dict[str, str | float | int] = {}

async with timeout(TIMEOUT):
await self._api.login(
self.config_entry.data[CONF_USERNAME],
self.config_entry.data[CONF_PASSWORD],
)

# Fetch data using distant API
try:
await self._api.login(
self.config_entry.data[CONF_USERNAME],
self.config_entry.data[CONF_PASSWORD],
)
await self._api.update()
except (ValueError, ClientError) as e:
raise UpdateFailed(e) from e
Expand Down
Loading
Loading