Skip to content

Commit 7af6a4f

Browse files
frenckfredrikeIvanLHchemelli74zxdavb
authored
2025.4.1 (#142299)
* Fix blocking event loop - daikin (#141442) * fix blocking event loop * create ssl_context directly * update manifest * update manifest.json * Made Google Search enable dependent on Assist availability (#141712) * Made Google Search enable dependent on Assist availability * Show error instead of rendering again * Cleanup test code * Fix humidifier platform for Comelit (#141854) * Fix humidifier platform for Comelit * apply review comment * Bump evohome-async to 1.0.5 (#141871) bump client to 1.0.5 * Replace "to log into" with "to log in to" in `incomfort` (#142060) * Replace "to log into" with "to log in to" in `incomfort` Also fix one missing sentence-casing of "gateway". * Replace duplicate "data_description" strings with references * Avoid unnecessary reload in apple_tv reauth flow (#142079) * Add translation for hassio update entity name (#142090) * Bump pyenphase to 1.25.5 (#142107) * Hide broken ZBT-1 config entries on the hardware page (#142110) * Hide bad ZBT-1 config entries on the hardware page * Set up the bad config entry in the unit test * Roll into a list comprehension * Remove constant changes * Fix condition in unit test * Bump pysmhi to 1.0.1 (#142111) * Avoid logging a warning when replacing an ignored config entry (#142114) Replacing an ignored config entry with one from the user flow should not generate a warning. We should only warn if we are replacing a usable config entry. Followup to adjust the warning added in #130567 cc @epenet * Slow down polling in Tesla Fleet (#142130) * Slow down polling * Fix tests * Bump tesla-fleet-api to v1.0.17 (#142131) bump * Tado bump to 0.18.11 (#142175) * Bump to version 0.18.11 * Adding hassfest files * Add preset mode to SmartThings climate (#142180) * Add preset mode to SmartThings climate * Add preset mode to SmartThings climate * Do not create a HA mediaplayer for the builtin Music Assistant player (#142192) Do not create a HA mediaplayer for the builtin Music player * Do not fetch disconnected Home Connect appliances (#142200) * Do not fetch disconnected Home Connect appliances * Apply suggestions Co-authored-by: Martin Hjelmare <[email protected]> * Update docstring --------- Co-authored-by: Martin Hjelmare <[email protected]> * Fix fibaro setup (#142201) * Fix circular mean by always storing and using the weighted one (#142208) * Fix circular mean by always storing and using the weighted one * fix * Fix test * Bump pySmartThings to 3.0.2 (#142257) Co-authored-by: Robert Resch <[email protected]> * Update frontend to 20250404.0 (#142274) * Bump forecast-solar lib to v4.1.0 (#142280) Co-authored-by: Jan-Philipp Benecke <[email protected]> * Bump version to 2025.4.1 * Fix skyconnect tests (#142262) fix tests * Fix empty actions (#142292) * Apply fix * Add tests for alarm button cover lock * update light * add number tests * test select * add switch tests * test vacuum * update lock test --------- Co-authored-by: Fredrik Erlandsson <[email protected]> Co-authored-by: Ivan Lopez Hernandez <[email protected]> Co-authored-by: Simone Chemelli <[email protected]> Co-authored-by: David Bonnes <[email protected]> Co-authored-by: Norbert Rittel <[email protected]> Co-authored-by: Erik Montnemery <[email protected]> Co-authored-by: Paul Bottein <[email protected]> Co-authored-by: Arie Catsman <[email protected]> Co-authored-by: puddly <[email protected]> Co-authored-by: G Johansson <[email protected]> Co-authored-by: J. Nick Koston <[email protected]> Co-authored-by: Brett Adams <[email protected]> Co-authored-by: Erwin Douna <[email protected]> Co-authored-by: Joost Lekkerkerker <[email protected]> Co-authored-by: Marcel van der Veldt <[email protected]> Co-authored-by: J. Diego Rodríguez Royo <[email protected]> Co-authored-by: Martin Hjelmare <[email protected]> Co-authored-by: rappenze <[email protected]> Co-authored-by: Robert Resch <[email protected]> Co-authored-by: Bram Kragten <[email protected]> Co-authored-by: Klaas Schoute <[email protected]> Co-authored-by: Jan-Philipp Benecke <[email protected]> Co-authored-by: Josef Zweck <[email protected]> Co-authored-by: Petro31 <[email protected]>
2 parents e8b2a3d + c25f26a commit 7af6a4f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1102
-234
lines changed

homeassistant/components/apple_tv/config_flow.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from homeassistant.components import zeroconf
2121
from homeassistant.config_entries import (
2222
SOURCE_IGNORE,
23+
SOURCE_REAUTH,
2324
SOURCE_ZEROCONF,
2425
ConfigEntry,
2526
ConfigFlow,
@@ -381,7 +382,9 @@ async def async_find_device(self, allow_exist: bool = False) -> None:
381382
CONF_IDENTIFIERS: list(combined_identifiers),
382383
},
383384
)
384-
if entry.source != SOURCE_IGNORE:
385+
# Don't reload ignored entries or in the middle of reauth,
386+
# e.g. if the user is entering a new PIN
387+
if entry.source != SOURCE_IGNORE and self.source != SOURCE_REAUTH:
385388
self.hass.config_entries.async_schedule_reload(entry.entry_id)
386389
if not allow_exist:
387390
raise DeviceAlreadyConfigured

homeassistant/components/comelit/humidifier.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def _handle_coordinator_update(self) -> None:
162162

163163
async def async_set_humidity(self, humidity: int) -> None:
164164
"""Set new target humidity."""
165-
if self.mode == HumidifierComelitMode.OFF:
165+
if not self._attr_is_on:
166166
raise ServiceValidationError(
167167
translation_domain=DOMAIN,
168168
translation_key="humidity_while_off",
@@ -190,9 +190,13 @@ async def async_turn_on(self, **kwargs: Any) -> None:
190190
await self.coordinator.api.set_humidity_status(
191191
self._device.index, self._set_command
192192
)
193+
self._attr_is_on = True
194+
self.async_write_ha_state()
193195

194196
async def async_turn_off(self, **kwargs: Any) -> None:
195197
"""Turn off."""
196198
await self.coordinator.api.set_humidity_status(
197199
self._device.index, HumidifierComelitCommand.OFF
198200
)
201+
self._attr_is_on = False
202+
self.async_write_ha_state()

homeassistant/components/comelit/strings.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@
5252
"rest": "Rest",
5353
"sabotated": "Sabotated"
5454
}
55-
},
55+
}
56+
},
57+
"humidifier": {
5658
"humidifier": {
5759
"name": "Humidifier"
5860
},

homeassistant/components/daikin/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from homeassistant.helpers import device_registry as dr, entity_registry as er
2222
from homeassistant.helpers.aiohttp_client import async_get_clientsession
2323
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
24+
from homeassistant.util.ssl import client_context_no_verify
2425

2526
from .const import KEY_MAC, TIMEOUT
2627
from .coordinator import DaikinConfigEntry, DaikinCoordinator
@@ -48,6 +49,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: DaikinConfigEntry) -> bo
4849
key=entry.data.get(CONF_API_KEY),
4950
uuid=entry.data.get(CONF_UUID),
5051
password=entry.data.get(CONF_PASSWORD),
52+
ssl_context=client_context_no_verify(),
5153
)
5254
_LOGGER.debug("Connection to %s successful", host)
5355
except TimeoutError as err:

homeassistant/components/daikin/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
"documentation": "https://www.home-assistant.io/integrations/daikin",
77
"iot_class": "local_polling",
88
"loggers": ["pydaikin"],
9-
"requirements": ["pydaikin==2.14.1"],
9+
"requirements": ["pydaikin==2.15.0"],
1010
"zeroconf": ["_dkapi._tcp.local."]
1111
}

homeassistant/components/enphase_envoy/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"documentation": "https://www.home-assistant.io/integrations/enphase_envoy",
77
"iot_class": "local_polling",
88
"loggers": ["pyenphase"],
9-
"requirements": ["pyenphase==1.25.1"],
9+
"requirements": ["pyenphase==1.25.5"],
1010
"zeroconf": [
1111
{
1212
"type": "_enphase-envoy._tcp.local."

homeassistant/components/evohome/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"iot_class": "cloud_polling",
77
"loggers": ["evohome", "evohomeasync", "evohomeasync2"],
88
"quality_scale": "legacy",
9-
"requirements": ["evohome-async==1.0.4"]
9+
"requirements": ["evohome-async==1.0.5"]
1010
}

homeassistant/components/fibaro/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ def _read_devices(self) -> None:
301301
device.ha_id = (
302302
f"{slugify(room_name)}_{slugify(device.name)}_{device.fibaro_id}"
303303
)
304+
platform = None
304305
if device.enabled and (not device.is_plugin or self._import_plugins):
305306
platform = self._map_device_to_platform(device)
306307
if platform is None:

homeassistant/components/forecast_solar/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"documentation": "https://www.home-assistant.io/integrations/forecast_solar",
77
"integration_type": "service",
88
"iot_class": "cloud_polling",
9-
"requirements": ["forecast-solar==4.0.0"]
9+
"requirements": ["forecast-solar==4.1.0"]
1010
}

homeassistant/components/frontend/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
"documentation": "https://www.home-assistant.io/integrations/frontend",
2121
"integration_type": "system",
2222
"quality_scale": "internal",
23-
"requirements": ["home-assistant-frontend==20250401.0"]
23+
"requirements": ["home-assistant-frontend==20250404.0"]
2424
}

homeassistant/components/google_generative_ai_conversation/config_flow.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -179,28 +179,30 @@ async def async_step_init(
179179
) -> ConfigFlowResult:
180180
"""Manage the options."""
181181
options: dict[str, Any] | MappingProxyType[str, Any] = self.config_entry.options
182+
errors: dict[str, str] = {}
182183

183184
if user_input is not None:
184185
if user_input[CONF_RECOMMENDED] == self.last_rendered_recommended:
185186
if user_input[CONF_LLM_HASS_API] == "none":
186187
user_input.pop(CONF_LLM_HASS_API)
187-
return self.async_create_entry(title="", data=user_input)
188+
if not (
189+
user_input.get(CONF_LLM_HASS_API, "none") != "none"
190+
and user_input.get(CONF_USE_GOOGLE_SEARCH_TOOL, False) is True
191+
):
192+
# Don't allow to save options that enable the Google Seearch tool with an Assist API
193+
return self.async_create_entry(title="", data=user_input)
194+
errors[CONF_USE_GOOGLE_SEARCH_TOOL] = "invalid_google_search_option"
188195

189196
# Re-render the options again, now with the recommended options shown/hidden
190197
self.last_rendered_recommended = user_input[CONF_RECOMMENDED]
191198

192-
options = {
193-
CONF_RECOMMENDED: user_input[CONF_RECOMMENDED],
194-
CONF_PROMPT: user_input[CONF_PROMPT],
195-
CONF_LLM_HASS_API: user_input[CONF_LLM_HASS_API],
196-
}
199+
options = user_input
197200

198201
schema = await google_generative_ai_config_option_schema(
199202
self.hass, options, self._genai_client
200203
)
201204
return self.async_show_form(
202-
step_id="init",
203-
data_schema=vol.Schema(schema),
205+
step_id="init", data_schema=vol.Schema(schema), errors=errors
204206
)
205207

206208

homeassistant/components/google_generative_ai_conversation/strings.json

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
"prompt": "Instruct how the LLM should respond. This can be a template."
4444
}
4545
}
46+
},
47+
"error": {
48+
"invalid_google_search_option": "Google Search cannot be enabled alongside any Assist capability, this can only be used when Assist is set to \"No control\"."
4649
}
4750
},
4851
"services": {

homeassistant/components/hassio/strings.json

+5
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@
265265
"version_latest": {
266266
"name": "Newest version"
267267
}
268+
},
269+
"update": {
270+
"update": {
271+
"name": "[%key:component::update::title%]"
272+
}
268273
}
269274
},
270275
"services": {

homeassistant/components/hassio/update.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from .update_helper import update_addon, update_core
4040

4141
ENTITY_DESCRIPTION = UpdateEntityDescription(
42-
name="Update",
42+
translation_key="update",
4343
key=ATTR_VERSION_LATEST,
4444
)
4545

homeassistant/components/home_connect/coordinator.py

+23-9
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ def update(self, other: HomeConnectApplianceData) -> None:
7373
self.settings.update(other.settings)
7474
self.status.update(other.status)
7575

76+
@classmethod
77+
def empty(cls, appliance: HomeAppliance) -> HomeConnectApplianceData:
78+
"""Return empty data."""
79+
return cls(
80+
commands=set(),
81+
events={},
82+
info=appliance,
83+
options={},
84+
programs=[],
85+
settings={},
86+
status={},
87+
)
88+
7689

7790
class HomeConnectCoordinator(
7891
DataUpdateCoordinator[dict[str, HomeConnectApplianceData]]
@@ -358,15 +371,7 @@ async def _async_setup(self) -> None:
358371
model=appliance.vib,
359372
)
360373
if appliance.ha_id not in self.data:
361-
self.data[appliance.ha_id] = HomeConnectApplianceData(
362-
commands=set(),
363-
events={},
364-
info=appliance,
365-
options={},
366-
programs=[],
367-
settings={},
368-
status={},
369-
)
374+
self.data[appliance.ha_id] = HomeConnectApplianceData.empty(appliance)
370375
else:
371376
self.data[appliance.ha_id].info.connected = appliance.connected
372377
old_appliances.remove(appliance.ha_id)
@@ -402,6 +407,15 @@ async def _get_appliance_data(
402407
name=appliance.name,
403408
model=appliance.vib,
404409
)
410+
if not appliance.connected:
411+
_LOGGER.debug(
412+
"Appliance %s is not connected, skipping data fetch",
413+
appliance.ha_id,
414+
)
415+
if appliance_data_to_update:
416+
appliance_data_to_update.info.connected = False
417+
return appliance_data_to_update
418+
return HomeConnectApplianceData.empty(appliance)
405419
try:
406420
settings = {
407421
setting.key: setting

homeassistant/components/homeassistant_sky_connect/hardware.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@
55
from homeassistant.components.hardware.models import HardwareInfo, USBInfo
66
from homeassistant.core import HomeAssistant, callback
77

8+
from .config_flow import HomeAssistantSkyConnectConfigFlow
89
from .const import DOMAIN
910
from .util import get_hardware_variant
1011

1112
DOCUMENTATION_URL = "https://skyconnect.home-assistant.io/documentation/"
13+
EXPECTED_ENTRY_VERSION = (
14+
HomeAssistantSkyConnectConfigFlow.VERSION,
15+
HomeAssistantSkyConnectConfigFlow.MINOR_VERSION,
16+
)
1217

1318

1419
@callback
1520
def async_info(hass: HomeAssistant) -> list[HardwareInfo]:
1621
"""Return board info."""
1722
entries = hass.config_entries.async_entries(DOMAIN)
18-
1923
return [
2024
HardwareInfo(
2125
board=None,
@@ -31,4 +35,6 @@ def async_info(hass: HomeAssistant) -> list[HardwareInfo]:
3135
url=DOCUMENTATION_URL,
3236
)
3337
for entry in entries
38+
# Ignore unmigrated config entries in the hardware page
39+
if (entry.version, entry.minor_version) == EXPECTED_ENTRY_VERSION
3440
]

homeassistant/components/incomfort/strings.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
},
1111
"data_description": {
1212
"host": "Hostname or IP-address of the Intergas gateway.",
13-
"username": "The username to log into the gateway. This is `admin` in most cases.",
14-
"password": "The password to log into the gateway, is printed at the bottom of the gateway or is `intergas` for some older devices."
13+
"username": "The username to log in to the gateway. This is `admin` in most cases.",
14+
"password": "The password to log in to the gateway, is printed at the bottom of the gateway or is `intergas` for some older devices."
1515
}
1616
},
1717
"dhcp_auth": {
@@ -22,8 +22,8 @@
2222
"password": "[%key:common::config_flow::data::password%]"
2323
},
2424
"data_description": {
25-
"username": "The username to log into the gateway. This is `admin` in most cases.",
26-
"password": "The password to log into the gateway, is printed at the bottom of the Gateway or is `intergas` for some older devices."
25+
"username": "[%key:component::incomfort::config::step::user::data_description::username%]",
26+
"password": "[%key:component::incomfort::config::step::user::data_description::password%]"
2727
}
2828
},
2929
"dhcp_confirm": {

homeassistant/components/music_assistant/media_player.py

+4
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ async def handle_player_added(event: MassEvent) -> None:
151151
assert event.object_id is not None
152152
if event.object_id in added_ids:
153153
return
154+
if not player.expose_to_ha:
155+
return
154156
added_ids.add(event.object_id)
155157
async_add_entities([MusicAssistantPlayer(mass, event.object_id)])
156158

@@ -159,6 +161,8 @@ async def handle_player_added(event: MassEvent) -> None:
159161
mass_players = []
160162
# add all current players
161163
for player in mass.players:
164+
if not player.expose_to_ha:
165+
continue
162166
added_ids.add(player.player_id)
163167
mass_players.append(MusicAssistantPlayer(mass, player.player_id))
164168

0 commit comments

Comments
 (0)