Skip to content

[pull] dev from home-assistant:dev #647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 1, 2025
1 change: 1 addition & 0 deletions .strict-typing
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ homeassistant.components.media_player.*
homeassistant.components.media_source.*
homeassistant.components.met_eireann.*
homeassistant.components.metoffice.*
homeassistant.components.miele.*
homeassistant.components.mikrotik.*
homeassistant.components.min_max.*
homeassistant.components.minecraft_server.*
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/components/esphome/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from homeassistant.components import zeroconf
from homeassistant.config_entries import (
SOURCE_IGNORE,
SOURCE_REAUTH,
SOURCE_RECONFIGURE,
ConfigEntry,
Expand All @@ -31,6 +32,7 @@
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT
from homeassistant.core import callback
from homeassistant.data_entry_flow import AbortFlow
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
from homeassistant.helpers.service_info.hassio import HassioServiceInfo
Expand Down Expand Up @@ -302,7 +304,15 @@ async def _async_validate_mac_abort_configured(
)
):
return
if entry.source == SOURCE_IGNORE:
# Don't call _fetch_device_info() for ignored entries
raise AbortFlow("already_configured")
configured_host: str | None = entry.data.get(CONF_HOST)
configured_port: int | None = entry.data.get(CONF_PORT)
if configured_host == host and configured_port == port:
# Don't probe to verify the mac is correct since
# the host and port matches.
raise AbortFlow("already_configured")
configured_psk: str | None = entry.data.get(CONF_NOISE_PSK)
await self._fetch_device_info(host, port or configured_port, configured_psk)
updates: dict[str, Any] = {}
Expand Down
3 changes: 1 addition & 2 deletions homeassistant/components/esphome/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from .const import DOMAIN
from .coordinator import ESPHomeDashboardCoordinator
from .dashboard import async_get_dashboard
from .domain_data import DomainData
from .entity import (
EsphomeEntity,
convert_api_error_ha_error,
Expand Down Expand Up @@ -62,7 +61,7 @@ async def async_setup_entry(

if (dashboard := async_get_dashboard(hass)) is None:
return
entry_data = DomainData.get(hass).get_entry_data(entry)
entry_data = entry.runtime_data
assert entry_data.device_info is not None
device_name = entry_data.device_info.name
unsubs: list[CALLBACK_TYPE] = []
Expand Down
60 changes: 0 additions & 60 deletions homeassistant/components/husqvarna_automower/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,18 @@
from collections.abc import Callable
from dataclasses import dataclass
import logging
from typing import TYPE_CHECKING

from aioautomower.model import MowerActivities, MowerAttributes

from homeassistant.components.automation import automations_with_entity
from homeassistant.components.binary_sensor import (
DOMAIN as BINARY_SENSOR_DOMAIN,
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.components.script import scripts_with_entity
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.issue_registry import (
IssueSeverity,
async_create_issue,
async_delete_issue,
)

from . import AutomowerConfigEntry
from .const import DOMAIN
from .coordinator import AutomowerDataUpdateCoordinator
from .entity import AutomowerBaseEntity

Expand All @@ -34,13 +23,6 @@
PARALLEL_UPDATES = 0


def entity_used_in(hass: HomeAssistant, entity_id: str) -> list[str]:
"""Get list of related automations and scripts."""
used_in = automations_with_entity(hass, entity_id)
used_in += scripts_with_entity(hass, entity_id)
return used_in


@dataclass(frozen=True, kw_only=True)
class AutomowerBinarySensorEntityDescription(BinarySensorEntityDescription):
"""Describes Automower binary sensor entity."""
Expand All @@ -59,12 +41,6 @@ class AutomowerBinarySensorEntityDescription(BinarySensorEntityDescription):
translation_key="leaving_dock",
value_fn=lambda data: data.mower.activity == MowerActivities.LEAVING,
),
AutomowerBinarySensorEntityDescription(
key="returning_to_dock",
translation_key="returning_to_dock",
value_fn=lambda data: data.mower.activity == MowerActivities.GOING_HOME,
entity_registry_enabled_default=False,
),
)


Expand Down Expand Up @@ -107,39 +83,3 @@ def __init__(
def is_on(self) -> bool:
"""Return the state of the binary sensor."""
return self.entity_description.value_fn(self.mower_attributes)

async def async_added_to_hass(self) -> None:
"""Raise issue when entity is registered and was not disabled."""
if TYPE_CHECKING:
assert self.unique_id
if not (
entity_id := er.async_get(self.hass).async_get_entity_id(
BINARY_SENSOR_DOMAIN, DOMAIN, self.unique_id
)
):
return
if (
self.enabled
and self.entity_description.key == "returning_to_dock"
and entity_used_in(self.hass, entity_id)
):
async_create_issue(
self.hass,
DOMAIN,
f"deprecated_entity_{self.entity_description.key}",
breaks_in_ha_version="2025.6.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_entity",
translation_placeholders={
"entity_name": str(self.name),
"entity": entity_id,
},
)
else:
async_delete_issue(
self.hass,
DOMAIN,
f"deprecated_task_entity_{self.entity_description.key}",
)
await super().async_added_to_hass()
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ rules:
reconfiguration-flow:
status: exempt
comment: no configuration possible
repair-issues: done
repair-issues:
status: exempt
comment: no issues available
stale-devices: done

# Platinum
Expand Down
9 changes: 0 additions & 9 deletions homeassistant/components/husqvarna_automower/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@
"binary_sensor": {
"leaving_dock": {
"name": "Leaving dock"
},
"returning_to_dock": {
"name": "Returning to dock"
}
},
"button": {
Expand Down Expand Up @@ -323,12 +320,6 @@
}
}
},
"issues": {
"deprecated_entity": {
"title": "The Husqvarna Automower {entity_name} sensor is deprecated",
"description": "The Husqvarna Automower entity `{entity}` is deprecated and will be removed in a future release.\nYou can use the new returning state of the lawn mower entity instead.\nPlease update your automations and scripts to replace the sensor entity with the newly added lawn mower entity.\nWhen you are done migrating you can disable `{entity}`."
}
},
"services": {
"override_schedule": {
"name": "Override schedule",
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/inkbird/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
"local_name": "ITH-21-B",
"connectable": false
},
{
"local_name": "IBS-P02B",
"connectable": false
},
{
"local_name": "Ink@IAM-T1",
"connectable": true
Expand All @@ -49,5 +53,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/inkbird",
"iot_class": "local_push",
"requirements": ["inkbird-ble==0.15.0"]
"requirements": ["inkbird-ble==0.16.1"]
}
7 changes: 4 additions & 3 deletions homeassistant/components/lamarzocco/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,15 @@ async def _internal_async_update_data(self) -> None:
self.config_entry.async_create_background_task(
hass=self.hass,
target=self.device.connect_dashboard_websocket(
update_callback=lambda _: self.async_set_updated_data(None)
update_callback=lambda _: self.async_set_updated_data(None),
connect_callback=self.async_update_listeners,
disconnect_callback=self.async_update_listeners,
),
name="lm_websocket_task",
)

async def websocket_close(_: Any | None = None) -> None:
if self.device.websocket.connected:
await self.device.websocket.disconnect()
await self.device.websocket.disconnect()

self.config_entry.async_on_unload(
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, websocket_close)
Expand Down
12 changes: 11 additions & 1 deletion homeassistant/components/lamarzocco/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from typing import Any

from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_MAC, CONF_TOKEN
from homeassistant.core import HomeAssistant

from .const import CONF_USE_BLUETOOTH
from .coordinator import LaMarzoccoConfigEntry

TO_REDACT = {
Expand All @@ -21,4 +23,12 @@ async def async_get_config_entry_diagnostics(
"""Return diagnostics for a config entry."""
coordinator = entry.runtime_data.config_coordinator
device = coordinator.device
return async_redact_data(device.to_dict(), TO_REDACT)
data = {
"device": device.to_dict(),
"bluetooth_available": {
"options_enabled": entry.options.get(CONF_USE_BLUETOOTH, True),
CONF_MAC: CONF_MAC in entry.data,
CONF_TOKEN: CONF_TOKEN in entry.data,
},
}
return async_redact_data(data, TO_REDACT)
2 changes: 1 addition & 1 deletion homeassistant/components/opower/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ async def _async_maybe_migrate_statistics(
1,
target_id,
True,
{},
set(),
)
if not last_target_stat:
need_migration_source_ids.add(source_id)
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
is_rpc_momentary_input,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class BlockBinarySensorDescription(
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator
from .utils import get_device_entry_gen, get_rpc_key_ids

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class ShellyButtonDescription[
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
is_rpc_thermostat_internal_actuator,
)

PARALLEL_UPDATES = 0


async def async_setup_entry(
hass: HomeAssistant,
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from .entity import ShellyBlockEntity, ShellyRpcEntity
from .utils import get_device_entry_gen, get_rpc_key_ids

PARALLEL_UPDATES = 0


async def async_setup_entry(
hass: HomeAssistant,
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
is_rpc_momentary_input,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class ShellyBlockEventDescription(EventEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
percentage_to_brightness,
)

PARALLEL_UPDATES = 0


async def async_setup_entry(
hass: HomeAssistant,
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
get_virtual_component_ids,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class BlockNumberDescription(BlockEntityDescription, NumberEntityDescription):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/shelly/quality_scale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ rules:
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: todo
parallel-updates: done
reauthentication-flow: done
test-coverage: done

Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
get_virtual_component_ids,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class RpcSelectDescription(RpcEntityDescription, SelectEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
is_rpc_wifi_stations_disabled,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class BlockSensorDescription(BlockEntityDescription, SensorEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
is_rpc_exclude_from_relay,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class BlockSwitchDescription(BlockEntityDescription, SwitchEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
get_virtual_component_ids,
)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class RpcTextDescription(RpcEntityDescription, TextEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

LOGGER = logging.getLogger(__name__)

PARALLEL_UPDATES = 0


@dataclass(frozen=True, kw_only=True)
class RpcUpdateDescription(RpcEntityDescription, UpdateEntityDescription):
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/shelly/valve.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
)
from .utils import async_remove_shelly_entity, get_device_entry_gen

PARALLEL_UPDATES = 0


@dataclass(kw_only=True, frozen=True)
class BlockValveDescription(BlockEntityDescription, ValveEntityDescription):
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/generated/bluetooth.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading