diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c1272759acc..a4469cde0d8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,11 +24,11 @@ jobs: uses: actions/checkout@v4.2.2 - name: Initialize CodeQL - uses: github/codeql-action/init@v3.28.8 + uses: github/codeql-action/init@v3.28.9 with: languages: python - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3.28.8 + uses: github/codeql-action/analyze@v3.28.9 with: category: "/language:python" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7425e7a2533..b699ed44b96 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -148,7 +148,7 @@ { "label": "Install all Test Requirements", "type": "shell", - "command": "uv pip install -r requirements_test_all.txt", + "command": "uv pip install -r requirements.txt -r requirements_test_all.txt", "group": { "kind": "build", "isDefault": true diff --git a/CODEOWNERS b/CODEOWNERS index e510eec6dfa..3d8159560bc 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1138,6 +1138,8 @@ build.json @home-assistant/supervisor /tests/components/permobil/ @IsakNyberg /homeassistant/components/persistent_notification/ @home-assistant/core /tests/components/persistent_notification/ @home-assistant/core +/homeassistant/components/pglab/ @pglab-electronics +/tests/components/pglab/ @pglab-electronics /homeassistant/components/philips_js/ @elupus /tests/components/philips_js/ @elupus /homeassistant/components/pi_hole/ @shenxn diff --git a/homeassistant/components/abode/alarm_control_panel.py b/homeassistant/components/abode/alarm_control_panel.py index 4ec59ca4c39..554cf932fca 100644 --- a/homeassistant/components/abode/alarm_control_panel.py +++ b/homeassistant/components/abode/alarm_control_panel.py @@ -11,7 +11,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -19,7 +19,9 @@ from .entity import AbodeDevice async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode alarm control panel device.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/binary_sensor.py b/homeassistant/components/abode/binary_sensor.py index ca9679a5aaa..6f64fa46c0a 100644 --- a/homeassistant/components/abode/binary_sensor.py +++ b/homeassistant/components/abode/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from . import AbodeSystem @@ -21,7 +21,9 @@ from .entity import AbodeDevice async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode binary sensor devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/camera.py b/homeassistant/components/abode/camera.py index 58107f16462..3587c8c1799 100644 --- a/homeassistant/components/abode/camera.py +++ b/homeassistant/components/abode/camera.py @@ -15,7 +15,7 @@ from homeassistant.components.camera import Camera from homeassistant.config_entries import ConfigEntry from homeassistant.core import Event, HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from . import AbodeSystem @@ -26,7 +26,9 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode camera devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/cover.py b/homeassistant/components/abode/cover.py index b5b1e878b96..bc9df9d4a25 100644 --- a/homeassistant/components/abode/cover.py +++ b/homeassistant/components/abode/cover.py @@ -7,7 +7,7 @@ from jaraco.abode.devices.cover import Cover from homeassistant.components.cover import CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -15,7 +15,9 @@ from .entity import AbodeDevice async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode cover devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/light.py b/homeassistant/components/abode/light.py index e2d0a331f0a..9614e84ebad 100644 --- a/homeassistant/components/abode/light.py +++ b/homeassistant/components/abode/light.py @@ -18,7 +18,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -26,7 +26,9 @@ from .entity import AbodeDevice async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode light devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/lock.py b/homeassistant/components/abode/lock.py index ceff263e6b5..94832ed41f9 100644 --- a/homeassistant/components/abode/lock.py +++ b/homeassistant/components/abode/lock.py @@ -7,7 +7,7 @@ from jaraco.abode.devices.lock import Lock from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -15,7 +15,9 @@ from .entity import AbodeDevice async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode lock devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/sensor.py b/homeassistant/components/abode/sensor.py index d6a5389029b..ee168c16509 100644 --- a/homeassistant/components/abode/sensor.py +++ b/homeassistant/components/abode/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import LIGHT_LUX, PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -61,7 +61,9 @@ SENSOR_TYPES: tuple[AbodeSensorDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode sensor devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/abode/switch.py b/homeassistant/components/abode/switch.py index 7dad750c8d5..f6018d99fc8 100644 --- a/homeassistant/components/abode/switch.py +++ b/homeassistant/components/abode/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AbodeSystem from .const import DOMAIN @@ -20,7 +20,9 @@ DEVICE_TYPES = ["switch", "valve"] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Abode switch devices.""" data: AbodeSystem = hass.data[DOMAIN] diff --git a/homeassistant/components/acaia/binary_sensor.py b/homeassistant/components/acaia/binary_sensor.py index ecb7ac06eb5..d720488faa0 100644 --- a/homeassistant/components/acaia/binary_sensor.py +++ b/homeassistant/components/acaia/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AcaiaConfigEntry from .entity import AcaiaEntity @@ -40,7 +40,7 @@ BINARY_SENSORS: tuple[AcaiaBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AcaiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors.""" diff --git a/homeassistant/components/acaia/button.py b/homeassistant/components/acaia/button.py index a41233bfc17..446f6134789 100644 --- a/homeassistant/components/acaia/button.py +++ b/homeassistant/components/acaia/button.py @@ -8,7 +8,7 @@ from aioacaia.acaiascale import AcaiaScale from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AcaiaConfigEntry from .entity import AcaiaEntity @@ -45,7 +45,7 @@ BUTTONS: tuple[AcaiaButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AcaiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button entities and services.""" diff --git a/homeassistant/components/acaia/sensor.py b/homeassistant/components/acaia/sensor.py index 7ba44958eca..f62b93ddf1d 100644 --- a/homeassistant/components/acaia/sensor.py +++ b/homeassistant/components/acaia/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfMass, UnitOfVolumeFlowRate from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AcaiaConfigEntry from .entity import AcaiaEntity @@ -77,7 +77,7 @@ RESTORE_SENSORS: tuple[AcaiaSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AcaiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" diff --git a/homeassistant/components/accuweather/sensor.py b/homeassistant/components/accuweather/sensor.py index 001edc5f197..f14584cf08c 100644 --- a/homeassistant/components/accuweather/sensor.py +++ b/homeassistant/components/accuweather/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -375,7 +375,7 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AccuWeatherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add AccuWeather entities from a config_entry.""" observation_coordinator: AccuWeatherObservationDataUpdateCoordinator = ( diff --git a/homeassistant/components/accuweather/weather.py b/homeassistant/components/accuweather/weather.py index 7d754278d91..770f2b64f20 100644 --- a/homeassistant/components/accuweather/weather.py +++ b/homeassistant/components/accuweather/weather.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utc_from_timestamp from .const import ( @@ -54,7 +54,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: AccuWeatherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a AccuWeather weather entity from a config_entry.""" async_add_entities([AccuWeatherEntity(entry.runtime_data)]) diff --git a/homeassistant/components/acmeda/cover.py b/homeassistant/components/acmeda/cover.py index 77099e86adc..d09ba4bac08 100644 --- a/homeassistant/components/acmeda/cover.py +++ b/homeassistant/components/acmeda/cover.py @@ -11,7 +11,7 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AcmedaConfigEntry from .const import ACMEDA_HUB_UPDATE @@ -22,7 +22,7 @@ from .helpers import async_add_acmeda_entities async def async_setup_entry( hass: HomeAssistant, config_entry: AcmedaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Acmeda Rollers from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/acmeda/helpers.py b/homeassistant/components/acmeda/helpers.py index 52af7d586de..4c0f9b32cff 100644 --- a/homeassistant/components/acmeda/helpers.py +++ b/homeassistant/components/acmeda/helpers.py @@ -9,7 +9,7 @@ from aiopulse import Roller from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LOGGER @@ -23,7 +23,7 @@ def async_add_acmeda_entities( entity_class: type, config_entry: AcmedaConfigEntry, current: set[int], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add any new entities.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/acmeda/sensor.py b/homeassistant/components/acmeda/sensor.py index f5df1bf013d..515146f3d1a 100644 --- a/homeassistant/components/acmeda/sensor.py +++ b/homeassistant/components/acmeda/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AcmedaConfigEntry from .const import ACMEDA_HUB_UPDATE @@ -17,7 +17,7 @@ from .helpers import async_add_acmeda_entities async def async_setup_entry( hass: HomeAssistant, config_entry: AcmedaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Acmeda Rollers from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/adax/climate.py b/homeassistant/components/adax/climate.py index 15022ba3c9f..078640cd367 100644 --- a/homeassistant/components/adax/climate.py +++ b/homeassistant/components/adax/climate.py @@ -25,7 +25,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ACCOUNT_ID, CONNECTION_TYPE, DOMAIN, LOCAL @@ -33,7 +33,7 @@ from .const import ACCOUNT_ID, CONNECTION_TYPE, DOMAIN, LOCAL async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Adax thermostat with config flow.""" if entry.data.get(CONNECTION_TYPE) == LOCAL: diff --git a/homeassistant/components/adguard/sensor.py b/homeassistant/components/adguard/sensor.py index b2404a88278..f1af8ac32a4 100644 --- a/homeassistant/components/adguard/sensor.py +++ b/homeassistant/components/adguard/sensor.py @@ -12,7 +12,7 @@ from adguardhome import AdGuardHome from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import PERCENTAGE, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdGuardConfigEntry, AdGuardData from .const import DOMAIN @@ -85,7 +85,7 @@ SENSORS: tuple[AdGuardHomeEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AdGuardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdGuard Home sensor based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/adguard/switch.py b/homeassistant/components/adguard/switch.py index 3ea4f9d1d93..5128102a955 100644 --- a/homeassistant/components/adguard/switch.py +++ b/homeassistant/components/adguard/switch.py @@ -11,7 +11,7 @@ from adguardhome import AdGuardHome, AdGuardHomeError from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdGuardConfigEntry, AdGuardData from .const import DOMAIN, LOGGER @@ -79,7 +79,7 @@ SWITCHES: tuple[AdGuardHomeSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AdGuardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdGuard Home switch based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/advantage_air/binary_sensor.py b/homeassistant/components/advantage_air/binary_sensor.py index 601b10aeb4a..dd306b82c8a 100644 --- a/homeassistant/components/advantage_air/binary_sensor.py +++ b/homeassistant/components/advantage_air/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .entity import AdvantageAirAcEntity, AdvantageAirZoneEntity @@ -20,7 +20,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir Binary Sensor platform.""" diff --git a/homeassistant/components/advantage_air/climate.py b/homeassistant/components/advantage_air/climate.py index d07a3182ed7..c023d4cf8f3 100644 --- a/homeassistant/components/advantage_air/climate.py +++ b/homeassistant/components/advantage_air/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import ( @@ -76,7 +76,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir climate platform.""" diff --git a/homeassistant/components/advantage_air/cover.py b/homeassistant/components/advantage_air/cover.py index b091f0077a1..b5b982597f0 100644 --- a/homeassistant/components/advantage_air/cover.py +++ b/homeassistant/components/advantage_air/cover.py @@ -9,7 +9,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import ADVANTAGE_AIR_STATE_CLOSE, ADVANTAGE_AIR_STATE_OPEN @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir cover platform.""" diff --git a/homeassistant/components/advantage_air/light.py b/homeassistant/components/advantage_air/light.py index 7dd0a0a183b..ffd502663b0 100644 --- a/homeassistant/components/advantage_air/light.py +++ b/homeassistant/components/advantage_air/light.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import ADVANTAGE_AIR_STATE_ON, DOMAIN as ADVANTAGE_AIR_DOMAIN @@ -16,7 +16,7 @@ from .models import AdvantageAirData async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir light platform.""" diff --git a/homeassistant/components/advantage_air/select.py b/homeassistant/components/advantage_air/select.py index 84c37f38d7f..320bfd35aba 100644 --- a/homeassistant/components/advantage_air/select.py +++ b/homeassistant/components/advantage_air/select.py @@ -2,7 +2,7 @@ from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .entity import AdvantageAirAcEntity @@ -14,7 +14,7 @@ ADVANTAGE_AIR_INACTIVE = "Inactive" async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir select platform.""" diff --git a/homeassistant/components/advantage_air/sensor.py b/homeassistant/components/advantage_air/sensor.py index ab1a1c4f9a0..2abcc3b5a68 100644 --- a/homeassistant/components/advantage_air/sensor.py +++ b/homeassistant/components/advantage_air/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import ADVANTAGE_AIR_STATE_OPEN @@ -32,7 +32,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir sensor platform.""" diff --git a/homeassistant/components/advantage_air/switch.py b/homeassistant/components/advantage_air/switch.py index 876875a2510..5c4528b44c6 100644 --- a/homeassistant/components/advantage_air/switch.py +++ b/homeassistant/components/advantage_air/switch.py @@ -4,7 +4,7 @@ from typing import Any from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import ( @@ -19,7 +19,7 @@ from .models import AdvantageAirData async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir switch platform.""" diff --git a/homeassistant/components/advantage_air/update.py b/homeassistant/components/advantage_air/update.py index b639e4df867..92a162303dd 100644 --- a/homeassistant/components/advantage_air/update.py +++ b/homeassistant/components/advantage_air/update.py @@ -3,7 +3,7 @@ from homeassistant.components.update import UpdateEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AdvantageAirDataConfigEntry from .const import DOMAIN as ADVANTAGE_AIR_DOMAIN @@ -14,7 +14,7 @@ from .models import AdvantageAirData async def async_setup_entry( hass: HomeAssistant, config_entry: AdvantageAirDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AdvantageAir update platform.""" diff --git a/homeassistant/components/aemet/image.py b/homeassistant/components/aemet/image.py index ffc53022e4c..ba9986a5ccc 100644 --- a/homeassistant/components/aemet/image.py +++ b/homeassistant/components/aemet/image.py @@ -9,7 +9,7 @@ from aemet_opendata.helpers import dict_nested_value from homeassistant.components.image import Image, ImageEntity, ImageEntityDescription from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator from .entity import AemetEntity @@ -25,7 +25,7 @@ AEMET_IMAGES: Final[tuple[ImageEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AemetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AEMET OpenData image entities based on a config entry.""" domain_data = config_entry.runtime_data diff --git a/homeassistant/components/aemet/sensor.py b/homeassistant/components/aemet/sensor.py index 88eb34b6f84..9077b2bc44d 100644 --- a/homeassistant/components/aemet/sensor.py +++ b/homeassistant/components/aemet/sensor.py @@ -52,7 +52,7 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import ( @@ -358,7 +358,7 @@ WEATHER_SENSORS: Final[tuple[AemetSensorEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AemetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AEMET OpenData sensor entities based on a config entry.""" domain_data = config_entry.runtime_data diff --git a/homeassistant/components/aemet/weather.py b/homeassistant/components/aemet/weather.py index a156652eadd..3a17430300d 100644 --- a/homeassistant/components/aemet/weather.py +++ b/homeassistant/components/aemet/weather.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONDITIONS_MAP from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator @@ -35,7 +35,7 @@ from .entity import AemetEntity async def async_setup_entry( hass: HomeAssistant, config_entry: AemetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AEMET OpenData weather entity based on a config entry.""" domain_data = config_entry.runtime_data diff --git a/homeassistant/components/aftership/sensor.py b/homeassistant/components/aftership/sensor.py index 085be2499d4..7e0c6f524ab 100644 --- a/homeassistant/components/aftership/sensor.py +++ b/homeassistant/components/aftership/sensor.py @@ -14,7 +14,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from . import AfterShipConfigEntry @@ -42,7 +42,7 @@ PLATFORM_SCHEMA: Final = cv.removed(DOMAIN, raise_if_present=False) async def async_setup_entry( hass: HomeAssistant, config_entry: AfterShipConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AfterShip sensor entities based on a config entry.""" aftership = config_entry.runtime_data diff --git a/homeassistant/components/agent_dvr/alarm_control_panel.py b/homeassistant/components/agent_dvr/alarm_control_panel.py index 23328315e42..1ac808c87ad 100644 --- a/homeassistant/components/agent_dvr/alarm_control_panel.py +++ b/homeassistant/components/agent_dvr/alarm_control_panel.py @@ -9,7 +9,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AgentDVRConfigEntry from .const import DOMAIN as AGENT_DOMAIN @@ -24,7 +24,7 @@ CONST_ALARM_CONTROL_PANEL_NAME = "Alarm Panel" async def async_setup_entry( hass: HomeAssistant, config_entry: AgentDVRConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Agent DVR Alarm Control Panels.""" async_add_entities([AgentBaseStation(config_entry.runtime_data)]) diff --git a/homeassistant/components/agent_dvr/camera.py b/homeassistant/components/agent_dvr/camera.py index 933d0c6b40b..3de7f095b13 100644 --- a/homeassistant/components/agent_dvr/camera.py +++ b/homeassistant/components/agent_dvr/camera.py @@ -10,7 +10,7 @@ from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -39,7 +39,7 @@ CAMERA_SERVICES = { async def async_setup_entry( hass: HomeAssistant, config_entry: AgentDVRConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Agent cameras.""" filter_urllib3_logging() diff --git a/homeassistant/components/airgradient/button.py b/homeassistant/components/airgradient/button.py index ea7b12062e8..5e6f857f686 100644 --- a/homeassistant/components/airgradient/button.py +++ b/homeassistant/components/airgradient/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirGradientConfigEntry from .const import DOMAIN @@ -47,7 +47,7 @@ LED_BAR_TEST = AirGradientButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirGradient button entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airgradient/number.py b/homeassistant/components/airgradient/number.py index 4265215fa25..eeb24867845 100644 --- a/homeassistant/components/airgradient/number.py +++ b/homeassistant/components/airgradient/number.py @@ -14,7 +14,7 @@ from homeassistant.components.number import ( from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirGradientConfigEntry from .const import DOMAIN @@ -60,7 +60,7 @@ LED_BAR_BRIGHTNESS = AirGradientNumberEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirGradient number entities based on a config entry.""" diff --git a/homeassistant/components/airgradient/select.py b/homeassistant/components/airgradient/select.py index 8c15102ad3a..f288055ebf4 100644 --- a/homeassistant/components/airgradient/select.py +++ b/homeassistant/components/airgradient/select.py @@ -14,7 +14,7 @@ from homeassistant.components.select import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirGradientConfigEntry from .const import DOMAIN, PM_STANDARD, PM_STANDARD_REVERSE @@ -142,7 +142,7 @@ CONTROL_ENTITIES: tuple[AirGradientSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirGradient select entities based on a config entry.""" diff --git a/homeassistant/components/airgradient/sensor.py b/homeassistant/components/airgradient/sensor.py index 3b20b31f923..a4944a6196e 100644 --- a/homeassistant/components/airgradient/sensor.py +++ b/homeassistant/components/airgradient/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import AirGradientConfigEntry @@ -225,7 +225,7 @@ CONFIG_DISPLAY_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ... async def async_setup_entry( hass: HomeAssistant, entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirGradient sensor entities based on a config entry.""" diff --git a/homeassistant/components/airgradient/switch.py b/homeassistant/components/airgradient/switch.py index 55835fa30a6..0d404ed0f15 100644 --- a/homeassistant/components/airgradient/switch.py +++ b/homeassistant/components/airgradient/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirGradientConfigEntry from .const import DOMAIN @@ -45,7 +45,7 @@ POST_DATA_TO_AIRGRADIENT = AirGradientSwitchEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirGradient switch entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airgradient/update.py b/homeassistant/components/airgradient/update.py index 12cec65f791..97cb8576e79 100644 --- a/homeassistant/components/airgradient/update.py +++ b/homeassistant/components/airgradient/update.py @@ -6,7 +6,7 @@ from propcache.api import cached_property from homeassistant.components.update import UpdateDeviceClass, UpdateEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirGradientConfigEntry, AirGradientCoordinator from .entity import AirGradientEntity @@ -18,7 +18,7 @@ SCAN_INTERVAL = timedelta(hours=1) async def async_setup_entry( hass: HomeAssistant, config_entry: AirGradientConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Airgradient update platform.""" diff --git a/homeassistant/components/airly/sensor.py b/homeassistant/components/airly/sensor.py index fbf73ed753e..2aa99d9c792 100644 --- a/homeassistant/components/airly/sensor.py +++ b/homeassistant/components/airly/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -175,7 +175,7 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirlyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Airly sensor entities based on a config entry.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/airnow/sensor.py b/homeassistant/components/airnow/sensor.py index c8b1c985c8b..db579de4976 100644 --- a/homeassistant/components/airnow/sensor.py +++ b/homeassistant/components/airnow/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -130,7 +130,7 @@ SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AirNowConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirNow sensor entities based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/airq/sensor.py b/homeassistant/components/airq/sensor.py index c465d710406..08a344ae9f4 100644 --- a/homeassistant/components/airq/sensor.py +++ b/homeassistant/components/airq/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import AirQConfigEntry, AirQCoordinator @@ -399,7 +399,7 @@ SENSOR_TYPES: list[AirQEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: AirQConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities based on a config entry.""" diff --git a/homeassistant/components/airthings/sensor.py b/homeassistant/components/airthings/sensor.py index 1b604d72032..a0d9c97c8c8 100644 --- a/homeassistant/components/airthings/sensor.py +++ b/homeassistant/components/airthings/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -114,7 +114,7 @@ SENSORS: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: AirthingsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Airthings sensor.""" diff --git a/homeassistant/components/airthings_ble/sensor.py b/homeassistant/components/airthings_ble/sensor.py index 248561706a3..9c1a2af7a9f 100644 --- a/homeassistant/components/airthings_ble/sensor.py +++ b/homeassistant/components/airthings_ble/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_registry import ( RegistryEntry, async_entries_for_device, @@ -153,7 +153,7 @@ def async_migrate(hass: HomeAssistant, address: str, sensor_name: str) -> None: async def async_setup_entry( hass: HomeAssistant, entry: AirthingsBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Airthings BLE sensors.""" is_metric = hass.config.units is METRIC_SYSTEM diff --git a/homeassistant/components/airtouch4/climate.py b/homeassistant/components/airtouch4/climate.py index 0af920bd7a9..6d393ed0c99 100644 --- a/homeassistant/components/airtouch4/climate.py +++ b/homeassistant/components/airtouch4/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import AirTouch4ConfigEntry @@ -64,7 +64,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: AirTouch4ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Airtouch 4.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/airtouch5/climate.py b/homeassistant/components/airtouch5/climate.py index 16566f5d664..f3b914bf341 100644 --- a/homeassistant/components/airtouch5/climate.py +++ b/homeassistant/components/airtouch5/climate.py @@ -37,7 +37,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Airtouch5ConfigEntry from .const import DOMAIN, FAN_INTELLIGENT_AUTO, FAN_TURBO @@ -93,7 +93,7 @@ FAN_MODE_TO_SET_AC_FAN_SPEED = { async def async_setup_entry( hass: HomeAssistant, config_entry: Airtouch5ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Airtouch 5 Climate entities.""" client = config_entry.runtime_data diff --git a/homeassistant/components/airtouch5/cover.py b/homeassistant/components/airtouch5/cover.py index 62cf7938fc2..b811ed5c451 100644 --- a/homeassistant/components/airtouch5/cover.py +++ b/homeassistant/components/airtouch5/cover.py @@ -20,7 +20,7 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Airtouch5ConfigEntry from .const import DOMAIN @@ -32,7 +32,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: Airtouch5ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Airtouch 5 Cover entities.""" client = config_entry.runtime_data diff --git a/homeassistant/components/airvisual/sensor.py b/homeassistant/components/airvisual/sensor.py index 88a670edb82..1f406bd8f36 100644 --- a/homeassistant/components/airvisual/sensor.py +++ b/homeassistant/components/airvisual/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( CONF_STATE, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import AirVisualConfigEntry @@ -108,7 +108,7 @@ POLLUTANT_UNITS = { async def async_setup_entry( hass: HomeAssistant, entry: AirVisualConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirVisual sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airvisual_pro/sensor.py b/homeassistant/components/airvisual_pro/sensor.py index 58ad730bc31..215370736fe 100644 --- a/homeassistant/components/airvisual_pro/sensor.py +++ b/homeassistant/components/airvisual_pro/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AirVisualProConfigEntry from .entity import AirVisualProEntity @@ -130,7 +130,7 @@ def async_get_aqi_locale(settings: dict[str, Any]) -> str: async def async_setup_entry( hass: HomeAssistant, entry: AirVisualProConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AirVisual sensors based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/airzone/binary_sensor.py b/homeassistant/components/airzone/binary_sensor.py index 48f6ce8fd94..7274df44261 100644 --- a/homeassistant/components/airzone/binary_sensor.py +++ b/homeassistant/components/airzone/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneEntity, AirzoneSystemEntity, AirzoneZoneEntity @@ -76,7 +76,7 @@ ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...] async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone binary sensors from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone/climate.py b/homeassistant/components/airzone/climate.py index 23355a070ab..39e70e58e6d 100644 --- a/homeassistant/components/airzone/climate.py +++ b/homeassistant/components/airzone/climate.py @@ -48,7 +48,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import API_TEMPERATURE_STEP, TEMP_UNIT_LIB_TO_HASS from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator @@ -100,7 +100,7 @@ HVAC_MODE_HASS_TO_LIB: Final[dict[HVACMode, OperationMode]] = { async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone climate from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone/select.py b/homeassistant/components/airzone/select.py index 56a9b06ea21..c00e83f2c5b 100644 --- a/homeassistant/components/airzone/select.py +++ b/homeassistant/components/airzone/select.py @@ -25,7 +25,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneEntity, AirzoneZoneEntity @@ -117,7 +117,7 @@ ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone select from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone/sensor.py b/homeassistant/components/airzone/sensor.py index 0b5c5666c89..f76eb1466a3 100644 --- a/homeassistant/components/airzone/sensor.py +++ b/homeassistant/components/airzone/sensor.py @@ -28,7 +28,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TEMP_UNIT_LIB_TO_HASS from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator @@ -79,7 +79,7 @@ ZONE_SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone sensors from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone/switch.py b/homeassistant/components/airzone/switch.py index 69bf33666a5..07278970e03 100644 --- a/homeassistant/components/airzone/switch.py +++ b/homeassistant/components/airzone/switch.py @@ -14,7 +14,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneEntity, AirzoneZoneEntity @@ -39,7 +39,7 @@ ZONE_SWITCH_TYPES: Final[tuple[AirzoneSwitchDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone switch from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone/water_heater.py b/homeassistant/components/airzone/water_heater.py index 2a1ca72db21..eb1537dc222 100644 --- a/homeassistant/components/airzone/water_heater.py +++ b/homeassistant/components/airzone/water_heater.py @@ -28,7 +28,7 @@ from homeassistant.components.water_heater import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TEMP_UNIT_LIB_TO_HASS from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator @@ -58,7 +58,7 @@ OPERATION_MODE_TO_DHW_PARAMS: Final[dict[str, dict[str, Any]]] = { async def async_setup_entry( hass: HomeAssistant, entry: AirzoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Water Heater from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index 4a7b5441b68..64fa8cb5151 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -26,7 +26,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import ( @@ -111,7 +111,7 @@ ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...] async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Cloud binary sensors from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/climate.py b/homeassistant/components/airzone_cloud/climate.py index 69b10d2a69e..115f6e32dbf 100644 --- a/homeassistant/components/airzone_cloud/climate.py +++ b/homeassistant/components/airzone_cloud/climate.py @@ -56,7 +56,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import ( @@ -119,7 +119,7 @@ HVAC_MODE_HASS_TO_LIB: Final[dict[HVACMode, OperationMode]] = { async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone climate from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/select.py b/homeassistant/components/airzone_cloud/select.py index e0c595a80e8..816544efdf8 100644 --- a/homeassistant/components/airzone_cloud/select.py +++ b/homeassistant/components/airzone_cloud/select.py @@ -21,7 +21,7 @@ from aioairzone_cloud.const import ( from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneEntity, AirzoneZoneEntity @@ -89,7 +89,7 @@ ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Cloud select from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/sensor.py b/homeassistant/components/airzone_cloud/sensor.py index 4b13e09d126..43526c3aa52 100644 --- a/homeassistant/components/airzone_cloud/sensor.py +++ b/homeassistant/components/airzone_cloud/sensor.py @@ -47,7 +47,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import ( @@ -221,7 +221,7 @@ ZONE_SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Cloud sensors from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/switch.py b/homeassistant/components/airzone_cloud/switch.py index 8de0685e15e..ab703cd537a 100644 --- a/homeassistant/components/airzone_cloud/switch.py +++ b/homeassistant/components/airzone_cloud/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneEntity, AirzoneZoneEntity @@ -38,7 +38,7 @@ ZONE_SWITCH_TYPES: Final[tuple[AirzoneSwitchDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Cloud switch from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/airzone_cloud/water_heater.py b/homeassistant/components/airzone_cloud/water_heater.py index 381dce913fe..41d43002569 100644 --- a/homeassistant/components/airzone_cloud/water_heater.py +++ b/homeassistant/components/airzone_cloud/water_heater.py @@ -29,7 +29,7 @@ from homeassistant.components.water_heater import ( ) from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator from .entity import AirzoneHotWaterEntity @@ -68,7 +68,7 @@ OPERATION_MODE_TO_DHW_PARAMS: Final[dict[str, dict[str, Any]]] = { async def async_setup_entry( hass: HomeAssistant, entry: AirzoneCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Airzone Cloud Water Heater from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/alarmdecoder/alarm_control_panel.py b/homeassistant/components/alarmdecoder/alarm_control_panel.py index d7092bbe1c4..52687f04bf9 100644 --- a/homeassistant/components/alarmdecoder/alarm_control_panel.py +++ b/homeassistant/components/alarmdecoder/alarm_control_panel.py @@ -14,7 +14,7 @@ from homeassistant.const import ATTR_CODE from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AlarmDecoderConfigEntry from .const import ( @@ -36,7 +36,7 @@ ATTR_KEYPRESS = "keypress" async def async_setup_entry( hass: HomeAssistant, entry: AlarmDecoderConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up for AlarmDecoder alarm panels.""" options = entry.options diff --git a/homeassistant/components/alarmdecoder/binary_sensor.py b/homeassistant/components/alarmdecoder/binary_sensor.py index 1234c9f349b..b025da70d59 100644 --- a/homeassistant/components/alarmdecoder/binary_sensor.py +++ b/homeassistant/components/alarmdecoder/binary_sensor.py @@ -5,7 +5,7 @@ import logging from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AlarmDecoderConfigEntry from .const import ( @@ -40,7 +40,7 @@ ATTR_RF_LOOP1 = "rf_loop1" async def async_setup_entry( hass: HomeAssistant, entry: AlarmDecoderConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up for AlarmDecoder sensor.""" diff --git a/homeassistant/components/alarmdecoder/sensor.py b/homeassistant/components/alarmdecoder/sensor.py index f5e744457fd..8fdc6d57c67 100644 --- a/homeassistant/components/alarmdecoder/sensor.py +++ b/homeassistant/components/alarmdecoder/sensor.py @@ -3,7 +3,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AlarmDecoderConfigEntry from .const import SIGNAL_PANEL_MESSAGE @@ -13,7 +13,7 @@ from .entity import AlarmDecoderEntity async def async_setup_entry( hass: HomeAssistant, entry: AlarmDecoderConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up for AlarmDecoder sensor.""" diff --git a/homeassistant/components/amberelectric/binary_sensor.py b/homeassistant/components/amberelectric/binary_sensor.py index 66292ea5524..3ee27f19849 100644 --- a/homeassistant/components/amberelectric/binary_sensor.py +++ b/homeassistant/components/amberelectric/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTRIBUTION @@ -85,7 +85,7 @@ class AmberDemandWindowBinarySensor(AmberPriceGridSensor): async def async_setup_entry( hass: HomeAssistant, entry: AmberConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/amberelectric/sensor.py b/homeassistant/components/amberelectric/sensor.py index 49d6e5f4eac..7276ddb26a5 100644 --- a/homeassistant/components/amberelectric/sensor.py +++ b/homeassistant/components/amberelectric/sensor.py @@ -19,7 +19,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CURRENCY_DOLLAR, PERCENTAGE, UnitOfEnergy from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTRIBUTION @@ -196,7 +196,7 @@ class AmberGridSensor(CoordinatorEntity[AmberUpdateCoordinator], SensorEntity): async def async_setup_entry( hass: HomeAssistant, entry: AmberConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ambient_network/sensor.py b/homeassistant/components/ambient_network/sensor.py index 9d262e5a987..eff99503cc8 100644 --- a/homeassistant/components/ambient_network/sensor.py +++ b/homeassistant/components/ambient_network/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import AmbientNetworkConfigEntry, AmbientNetworkDataUpdateCoordinator @@ -270,7 +270,7 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: AmbientNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ambient Network sensor entities.""" diff --git a/homeassistant/components/ambient_station/binary_sensor.py b/homeassistant/components/ambient_station/binary_sensor.py index a79788a4c38..9a7c89db95e 100644 --- a/homeassistant/components/ambient_station/binary_sensor.py +++ b/homeassistant/components/ambient_station/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import ATTR_NAME, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AmbientStationConfigEntry from .const import ATTR_LAST_DATA @@ -381,7 +381,7 @@ BINARY_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: AmbientStationConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ambient PWS binary sensors based on a config entry.""" ambient = entry.runtime_data diff --git a/homeassistant/components/ambient_station/sensor.py b/homeassistant/components/ambient_station/sensor.py index dfbd2d1b4a0..d1ac39ba01a 100644 --- a/homeassistant/components/ambient_station/sensor.py +++ b/homeassistant/components/ambient_station/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AmbientStation, AmbientStationConfigEntry from .const import ATTR_LAST_DATA, TYPE_SOLARRADIATION, TYPE_SOLARRADIATION_LX @@ -662,7 +662,7 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: AmbientStationConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ambient PWS sensors based on a config entry.""" ambient = entry.runtime_data diff --git a/homeassistant/components/analytics_insights/sensor.py b/homeassistant/components/analytics_insights/sensor.py index 324ca6991d2..830d914b311 100644 --- a/homeassistant/components/analytics_insights/sensor.py +++ b/homeassistant/components/analytics_insights/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -94,7 +94,7 @@ GENERAL_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: AnalyticsInsightsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize the entries.""" diff --git a/homeassistant/components/android_ip_webcam/binary_sensor.py b/homeassistant/components/android_ip_webcam/binary_sensor.py index 1846889bfda..67816664752 100644 --- a/homeassistant/components/android_ip_webcam/binary_sensor.py +++ b/homeassistant/components/android_ip_webcam/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import MOTION_ACTIVE from .coordinator import AndroidIPCamConfigEntry, AndroidIPCamDataUpdateCoordinator @@ -24,7 +24,7 @@ BINARY_SENSOR_DESCRIPTION = BinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidIPCamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the IP Webcam sensors from config entry.""" diff --git a/homeassistant/components/android_ip_webcam/camera.py b/homeassistant/components/android_ip_webcam/camera.py index 95d4fb9f67a..833b9a0d296 100644 --- a/homeassistant/components/android_ip_webcam/camera.py +++ b/homeassistant/components/android_ip_webcam/camera.py @@ -11,7 +11,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import AndroidIPCamConfigEntry, AndroidIPCamDataUpdateCoordinator @@ -20,7 +20,7 @@ from .coordinator import AndroidIPCamConfigEntry, AndroidIPCamDataUpdateCoordina async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidIPCamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the IP Webcam camera from config entry.""" filter_urllib3_logging() diff --git a/homeassistant/components/android_ip_webcam/sensor.py b/homeassistant/components/android_ip_webcam/sensor.py index 9b2454d6c09..e9d5f8514e8 100644 --- a/homeassistant/components/android_ip_webcam/sensor.py +++ b/homeassistant/components/android_ip_webcam/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AndroidIPCamConfigEntry, AndroidIPCamDataUpdateCoordinator @@ -119,7 +119,7 @@ SENSOR_TYPES: tuple[AndroidIPWebcamSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidIPCamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the IP Webcam sensors from config entry.""" diff --git a/homeassistant/components/android_ip_webcam/switch.py b/homeassistant/components/android_ip_webcam/switch.py index f813415df0b..3ceaf6e59b9 100644 --- a/homeassistant/components/android_ip_webcam/switch.py +++ b/homeassistant/components/android_ip_webcam/switch.py @@ -11,7 +11,7 @@ from pydroid_ipcam import PyDroidIPCam from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AndroidIPCamConfigEntry, AndroidIPCamDataUpdateCoordinator from .entity import AndroidIPCamBaseEntity @@ -112,7 +112,7 @@ SWITCH_TYPES: tuple[AndroidIPWebcamSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidIPCamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the IP Webcam switches from config entry.""" diff --git a/homeassistant/components/androidtv/media_player.py b/homeassistant/components/androidtv/media_player.py index 728411ddf42..c9e62908cac 100644 --- a/homeassistant/components/androidtv/media_player.py +++ b/homeassistant/components/androidtv/media_player.py @@ -21,7 +21,7 @@ from homeassistant.const import ATTR_COMMAND from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from . import AndroidTVConfigEntry @@ -65,7 +65,7 @@ ANDROIDTV_STATES = { async def async_setup_entry( hass: HomeAssistant, entry: AndroidTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Android Debug Bridge entity.""" device_class = entry.runtime_data.aftv.DEVICE_CLASS diff --git a/homeassistant/components/androidtv/remote.py b/homeassistant/components/androidtv/remote.py index db48b0cf1b6..026d1485e07 100644 --- a/homeassistant/components/androidtv/remote.py +++ b/homeassistant/components/androidtv/remote.py @@ -12,7 +12,7 @@ from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_TURN_OFF_COMMAND, CONF_TURN_ON_COMMAND, DOMAIN from .entity import AndroidTVEntity, adb_decorator @@ -21,7 +21,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the AndroidTV remote from a config entry.""" async_add_entities([AndroidTVRemote(entry)]) diff --git a/homeassistant/components/androidtv_remote/media_player.py b/homeassistant/components/androidtv_remote/media_player.py index cdc307a0472..3d3a97092bc 100644 --- a/homeassistant/components/androidtv_remote/media_player.py +++ b/homeassistant/components/androidtv_remote/media_player.py @@ -18,7 +18,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AndroidTVRemoteConfigEntry from .const import CONF_APP_ICON, CONF_APP_NAME @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidTVRemoteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Android TV media player entity based on a config entry.""" api = config_entry.runtime_data diff --git a/homeassistant/components/androidtv_remote/remote.py b/homeassistant/components/androidtv_remote/remote.py index c9a261c8735..212b0491d2d 100644 --- a/homeassistant/components/androidtv_remote/remote.py +++ b/homeassistant/components/androidtv_remote/remote.py @@ -18,7 +18,7 @@ from homeassistant.components.remote import ( RemoteEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AndroidTVRemoteConfigEntry from .const import CONF_APP_NAME @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: AndroidTVRemoteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Android TV remote entity based on a config entry.""" api = config_entry.runtime_data diff --git a/homeassistant/components/anova/coordinator.py b/homeassistant/components/anova/coordinator.py index 811c32c97b5..61d118ed0a5 100644 --- a/homeassistant/components/anova/coordinator.py +++ b/homeassistant/components/anova/coordinator.py @@ -1,5 +1,7 @@ """Support for Anova Coordinators.""" +from __future__ import annotations + from dataclasses import dataclass import logging @@ -20,7 +22,7 @@ class AnovaData: """Data for the Anova integration.""" api_jwt: str - coordinators: list["AnovaCoordinator"] + coordinators: list[AnovaCoordinator] api: AnovaApi diff --git a/homeassistant/components/anova/sensor.py b/homeassistant/components/anova/sensor.py index 7365e4597ba..c3a3d3861f2 100644 --- a/homeassistant/components/anova/sensor.py +++ b/homeassistant/components/anova/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AnovaConfigEntry, AnovaCoordinator @@ -97,7 +97,7 @@ SENSOR_DESCRIPTIONS: list[AnovaSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: AnovaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Anova device.""" anova_data = entry.runtime_data @@ -108,7 +108,7 @@ async def async_setup_entry( def setup_coordinator( coordinator: AnovaCoordinator, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an individual Anova Coordinator.""" diff --git a/homeassistant/components/anthemav/media_player.py b/homeassistant/components/anthemav/media_player.py index be5a6ad2258..cfbd3c29547 100644 --- a/homeassistant/components/anthemav/media_player.py +++ b/homeassistant/components/anthemav/media_player.py @@ -16,7 +16,7 @@ from homeassistant.const import CONF_MAC, CONF_MODEL from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AnthemavConfigEntry from .const import ANTHEMAV_UPDATE_SIGNAL, DOMAIN, MANUFACTURER @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: AnthemavConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" name = config_entry.title diff --git a/homeassistant/components/anthropic/conversation.py b/homeassistant/components/anthropic/conversation.py index 259d1295809..9f513509ce7 100644 --- a/homeassistant/components/anthropic/conversation.py +++ b/homeassistant/components/anthropic/conversation.py @@ -16,18 +16,15 @@ from anthropic.types import ( ToolUseBlock, ToolUseBlockParam, ) -import voluptuous as vol from voluptuous_openapi import convert from homeassistant.components import conversation -from homeassistant.components.conversation import trace from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_LLM_HASS_API, MATCH_ALL from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError, TemplateError -from homeassistant.helpers import device_registry as dr, intent, llm, template -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.util import ulid as ulid_util +from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers import chat_session, device_registry as dr, intent, llm +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AnthropicConfigEntry from .const import ( @@ -49,7 +46,7 @@ MAX_TOOL_ITERATIONS = 10 async def async_setup_entry( hass: HomeAssistant, config_entry: AnthropicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up conversation entities.""" agent = AnthropicConversationEntity(config_entry) @@ -89,6 +86,44 @@ def _message_convert( return MessageParam(role=message.role, content=param_content) +def _convert_content(chat_content: conversation.Content) -> MessageParam: + """Create tool response content.""" + if isinstance(chat_content, conversation.ToolResultContent): + return MessageParam( + role="user", + content=[ + ToolResultBlockParam( + type="tool_result", + tool_use_id=chat_content.tool_call_id, + content=json.dumps(chat_content.tool_result), + ) + ], + ) + if isinstance(chat_content, conversation.AssistantContent): + return MessageParam( + role="assistant", + content=[ + TextBlockParam(type="text", text=chat_content.content or ""), + *[ + ToolUseBlockParam( + type="tool_use", + id=tool_call.id, + name=tool_call.tool_name, + input=json.dumps(tool_call.tool_args), + ) + for tool_call in chat_content.tool_calls or () + ], + ], + ) + if isinstance(chat_content, conversation.UserContent): + return MessageParam( + role="user", + content=chat_content.content, + ) + # Note: We don't pass SystemContent here as its passed to the API as the prompt + raise ValueError(f"Unexpected content type: {type(chat_content)}") + + class AnthropicConversationEntity( conversation.ConversationEntity, conversation.AbstractConversationAgent ): @@ -100,7 +135,6 @@ class AnthropicConversationEntity( def __init__(self, entry: AnthropicConfigEntry) -> None: """Initialize the agent.""" self.entry = entry - self.history: dict[str, list[MessageParam]] = {} self._attr_unique_id = entry.entry_id self._attr_device_info = dr.DeviceInfo( identifiers={(DOMAIN, entry.entry_id)}, @@ -129,110 +163,43 @@ class AnthropicConversationEntity( self, user_input: conversation.ConversationInput ) -> conversation.ConversationResult: """Process a sentence.""" - options = self.entry.options - intent_response = intent.IntentResponse(language=user_input.language) - llm_api: llm.APIInstance | None = None - tools: list[ToolParam] | None = None - user_name: str | None = None - llm_context = llm.LLMContext( - platform=DOMAIN, - context=user_input.context, - user_prompt=user_input.text, - language=user_input.language, - assistant=conversation.DOMAIN, - device_id=user_input.device_id, - ) - - if options.get(CONF_LLM_HASS_API): - try: - llm_api = await llm.async_get_api( - self.hass, - options[CONF_LLM_HASS_API], - llm_context, - ) - except HomeAssistantError as err: - LOGGER.error("Error getting LLM API: %s", err) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Error preparing LLM API: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=user_input.conversation_id - ) - tools = [ - _format_tool(tool, llm_api.custom_serializer) for tool in llm_api.tools - ] - - if user_input.conversation_id is None: - conversation_id = ulid_util.ulid_now() - messages = [] - - elif user_input.conversation_id in self.history: - conversation_id = user_input.conversation_id - messages = self.history[conversation_id] - - else: - # Conversation IDs are ULIDs. We generate a new one if not provided. - # If an old OLID is passed in, we will generate a new one to indicate - # a new conversation was started. If the user picks their own, they - # want to track a conversation and we respect it. - try: - ulid_util.ulid_to_bytes(user_input.conversation_id) - conversation_id = ulid_util.ulid_now() - except ValueError: - conversation_id = user_input.conversation_id - - messages = [] - - if ( - user_input.context - and user_input.context.user_id - and ( - user := await self.hass.auth.async_get_user(user_input.context.user_id) - ) + with ( + chat_session.async_get_chat_session( + self.hass, user_input.conversation_id + ) as session, + conversation.async_get_chat_log(self.hass, session, user_input) as chat_log, ): - user_name = user.name + return await self._async_handle_message(user_input, chat_log) + + async def _async_handle_message( + self, + user_input: conversation.ConversationInput, + chat_log: conversation.ChatLog, + ) -> conversation.ConversationResult: + """Call the API.""" + options = self.entry.options try: - prompt_parts = [ - template.Template( - llm.BASE_PROMPT - + options.get(CONF_PROMPT, llm.DEFAULT_INSTRUCTIONS_PROMPT), - self.hass, - ).async_render( - { - "ha_name": self.hass.config.location_name, - "user_name": user_name, - "llm_context": llm_context, - }, - parse_result=False, - ) + await chat_log.async_update_llm_data( + DOMAIN, + user_input, + options.get(CONF_LLM_HASS_API), + options.get(CONF_PROMPT), + ) + except conversation.ConverseError as err: + return err.as_conversation_result() + + tools: list[ToolParam] | None = None + if chat_log.llm_api: + tools = [ + _format_tool(tool, chat_log.llm_api.custom_serializer) + for tool in chat_log.llm_api.tools ] - except TemplateError as err: - LOGGER.error("Error rendering prompt: %s", err) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Sorry, I had a problem with my template: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id - ) - - if llm_api: - prompt_parts.append(llm_api.api_prompt) - - prompt = "\n".join(prompt_parts) - - # Create a copy of the variable because we attach it to the trace - messages = [*messages, MessageParam(role="user", content=user_input.text)] - - LOGGER.debug("Prompt: %s", messages) - LOGGER.debug("Tools: %s", tools) - trace.async_conversation_trace_append( - trace.ConversationTraceEventType.AGENT_DETAIL, - {"system": prompt, "messages": messages}, - ) + system = chat_log.content[0] + if not isinstance(system, conversation.SystemContent): + raise TypeError("First message must be a system message") + messages = [_convert_content(content) for content in chat_log.content[1:]] client = self.entry.runtime_data @@ -244,69 +211,62 @@ class AnthropicConversationEntity( messages=messages, tools=tools or NOT_GIVEN, max_tokens=options.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS), - system=prompt, + system=system.content, temperature=options.get(CONF_TEMPERATURE, RECOMMENDED_TEMPERATURE), ) except anthropic.AnthropicError as err: - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Sorry, I had a problem talking to Anthropic: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id - ) + raise HomeAssistantError( + f"Sorry, I had a problem talking to Anthropic: {err}" + ) from err LOGGER.debug("Response %s", response) messages.append(_message_convert(response)) - if response.stop_reason != "tool_use" or not llm_api: - break - - tool_results: list[ToolResultBlockParam] = [] - for tool_call in response.content: - if isinstance(tool_call, TextBlock): - LOGGER.info(tool_call.text) - - if not isinstance(tool_call, ToolUseBlock): - continue - - tool_input = llm.ToolInput( + text = "".join( + [ + content.text + for content in response.content + if isinstance(content, TextBlock) + ] + ) + tool_inputs = [ + llm.ToolInput( id=tool_call.id, tool_name=tool_call.name, tool_args=cast(dict[str, Any], tool_call.input), ) - LOGGER.debug( - "Tool call: %s(%s)", tool_input.tool_name, tool_input.tool_args + for tool_call in response.content + if isinstance(tool_call, ToolUseBlock) + ] + + tool_results = [ + ToolResultBlockParam( + type="tool_result", + tool_use_id=tool_response.tool_call_id, + content=json.dumps(tool_response.tool_result), ) - - try: - tool_response = await llm_api.async_call_tool(tool_input) - except (HomeAssistantError, vol.Invalid) as e: - tool_response = {"error": type(e).__name__} - if str(e): - tool_response["error_text"] = str(e) - - LOGGER.debug("Tool response: %s", tool_response) - tool_results.append( - ToolResultBlockParam( - type="tool_result", - tool_use_id=tool_call.id, - content=json.dumps(tool_response), + async for tool_response in chat_log.async_add_assistant_content( + conversation.AssistantContent( + agent_id=user_input.agent_id, + content=text, + tool_calls=tool_inputs or None, ) ) + ] + if tool_results: + messages.append(MessageParam(role="user", content=tool_results)) - messages.append(MessageParam(role="user", content=tool_results)) - - self.history[conversation_id] = messages - - for content in response.content: - if isinstance(content, TextBlock): - intent_response.async_set_speech(content.text) + if not tool_inputs: break + response_content = chat_log.content[-1] + if not isinstance(response_content, conversation.AssistantContent): + raise TypeError("Last message must be an assistant message") + intent_response = intent.IntentResponse(language=user_input.language) + intent_response.async_set_speech(response_content.content or "") return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id + response=intent_response, conversation_id=chat_log.conversation_id ) async def _async_entry_update_listener( diff --git a/homeassistant/components/aosmith/coordinator.py b/homeassistant/components/aosmith/coordinator.py index 26029fee750..16cacfcbc10 100644 --- a/homeassistant/components/aosmith/coordinator.py +++ b/homeassistant/components/aosmith/coordinator.py @@ -1,5 +1,7 @@ """The data update coordinator for the A. O. Smith integration.""" +from __future__ import annotations + from dataclasses import dataclass import logging @@ -27,8 +29,8 @@ class AOSmithData: """Data for the A. O. Smith integration.""" client: AOSmithAPIClient - status_coordinator: "AOSmithStatusCoordinator" - energy_coordinator: "AOSmithEnergyCoordinator" + status_coordinator: AOSmithStatusCoordinator + energy_coordinator: AOSmithEnergyCoordinator class AOSmithStatusCoordinator(DataUpdateCoordinator[dict[str, AOSmithDevice]]): diff --git a/homeassistant/components/aosmith/sensor.py b/homeassistant/components/aosmith/sensor.py index 8a7a98115fa..071407e7b17 100644 --- a/homeassistant/components/aosmith/sensor.py +++ b/homeassistant/components/aosmith/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfEnergy from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ( AOSmithConfigEntry, @@ -43,7 +43,7 @@ STATUS_ENTITY_DESCRIPTIONS: tuple[AOSmithStatusSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AOSmithConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up A. O. Smith sensor platform.""" data = entry.runtime_data diff --git a/homeassistant/components/aosmith/water_heater.py b/homeassistant/components/aosmith/water_heater.py index 110f997065b..d29b00955b6 100644 --- a/homeassistant/components/aosmith/water_heater.py +++ b/homeassistant/components/aosmith/water_heater.py @@ -15,7 +15,7 @@ from homeassistant.components.water_heater import ( from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AOSmithConfigEntry, AOSmithStatusCoordinator from .entity import AOSmithStatusEntity @@ -45,7 +45,7 @@ DEFAULT_OPERATION_MODE_PRIORITY = [ async def async_setup_entry( hass: HomeAssistant, entry: AOSmithConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up A. O. Smith water heater platform.""" data = entry.runtime_data diff --git a/homeassistant/components/apcupsd/binary_sensor.py b/homeassistant/components/apcupsd/binary_sensor.py index 2a44845618e..f3829b41f61 100644 --- a/homeassistant/components/apcupsd/binary_sensor.py +++ b/homeassistant/components/apcupsd/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator @@ -27,7 +27,7 @@ _VALUE_ONLINE_MASK: Final = 0b1000 async def async_setup_entry( hass: HomeAssistant, config_entry: APCUPSdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an APCUPSd Online Status binary sensor.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/apcupsd/sensor.py b/homeassistant/components/apcupsd/sensor.py index b3c396daf5e..02016efa4ca 100644 --- a/homeassistant/components/apcupsd/sensor.py +++ b/homeassistant/components/apcupsd/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import LAST_S_TEST @@ -406,7 +406,7 @@ INFERRED_UNITS = { async def async_setup_entry( hass: HomeAssistant, config_entry: APCUPSdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the APCUPSd sensors from config entries.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/apple_tv/media_player.py b/homeassistant/components/apple_tv/media_player.py index 8a2336eea3b..b68d74e6115 100644 --- a/homeassistant/components/apple_tv/media_player.py +++ b/homeassistant/components/apple_tv/media_player.py @@ -39,7 +39,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import AppleTvConfigEntry, AppleTVManager @@ -100,7 +100,7 @@ SUPPORT_FEATURE_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: AppleTvConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Apple TV media player based on a config entry.""" name: str = config_entry.data[CONF_NAME] diff --git a/homeassistant/components/apple_tv/remote.py b/homeassistant/components/apple_tv/remote.py index 7f2c9f1b591..97e31bd4bb0 100644 --- a/homeassistant/components/apple_tv/remote.py +++ b/homeassistant/components/apple_tv/remote.py @@ -17,7 +17,7 @@ from homeassistant.components.remote import ( ) from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AppleTvConfigEntry from .entity import AppleTVEntity @@ -38,7 +38,7 @@ COMMAND_TO_ATTRIBUTE = { async def async_setup_entry( hass: HomeAssistant, config_entry: AppleTvConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Apple TV remote based on a config entry.""" name: str = config_entry.data[CONF_NAME] diff --git a/homeassistant/components/aprilaire/climate.py b/homeassistant/components/aprilaire/climate.py index 194453046e6..5116e06b58f 100644 --- a/homeassistant/components/aprilaire/climate.py +++ b/homeassistant/components/aprilaire/climate.py @@ -18,7 +18,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import PRECISION_HALVES, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( FAN_CIRCULATE, @@ -63,7 +63,7 @@ FAN_MODE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: AprilaireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add climates for passed config_entry in HA.""" diff --git a/homeassistant/components/aprilaire/humidifier.py b/homeassistant/components/aprilaire/humidifier.py index 8a173e5e95e..fdb9233a0e3 100644 --- a/homeassistant/components/aprilaire/humidifier.py +++ b/homeassistant/components/aprilaire/humidifier.py @@ -15,7 +15,7 @@ from homeassistant.components.humidifier import ( HumidifierEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AprilaireConfigEntry, AprilaireCoordinator @@ -40,7 +40,7 @@ DEHUMIDIFIER_ACTION_MAP: dict[StateType, HumidifierAction] = { async def async_setup_entry( hass: HomeAssistant, config_entry: AprilaireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Aprilaire humidifier devices.""" diff --git a/homeassistant/components/aprilaire/select.py b/homeassistant/components/aprilaire/select.py index d8f6137f53d..c38c9e94501 100644 --- a/homeassistant/components/aprilaire/select.py +++ b/homeassistant/components/aprilaire/select.py @@ -10,7 +10,7 @@ from pyaprilaire.const import Attribute from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AprilaireConfigEntry, AprilaireCoordinator from .entity import BaseAprilaireEntity @@ -24,7 +24,7 @@ FRESH_AIR_MODE_MAP = {0: "off", 1: "automatic"} async def async_setup_entry( hass: HomeAssistant, config_entry: AprilaireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Aprilaire select devices.""" diff --git a/homeassistant/components/aprilaire/sensor.py b/homeassistant/components/aprilaire/sensor.py index e1909746364..bf3bd12f43d 100644 --- a/homeassistant/components/aprilaire/sensor.py +++ b/homeassistant/components/aprilaire/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AprilaireConfigEntry, AprilaireCoordinator @@ -75,7 +75,7 @@ def get_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: AprilaireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Aprilaire sensor devices.""" diff --git a/homeassistant/components/apsystems/binary_sensor.py b/homeassistant/components/apsystems/binary_sensor.py index 863a50ca455..202d878014d 100644 --- a/homeassistant/components/apsystems/binary_sensor.py +++ b/homeassistant/components/apsystems/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator @@ -63,7 +63,7 @@ BINARY_SENSORS: tuple[ApsystemsLocalApiBinarySensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ApSystemsConfigEntry, - add_entities: AddEntitiesCallback, + add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensor platform.""" config = config_entry.runtime_data diff --git a/homeassistant/components/apsystems/number.py b/homeassistant/components/apsystems/number.py index f7bdc7c2711..b43b21f2b71 100644 --- a/homeassistant/components/apsystems/number.py +++ b/homeassistant/components/apsystems/number.py @@ -7,7 +7,7 @@ from aiohttp import ClientConnectorError from homeassistant.components.number import NumberDeviceClass, NumberEntity, NumberMode from homeassistant.const import UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import DiscoveryInfoType from .coordinator import ApSystemsConfigEntry, ApSystemsData @@ -17,7 +17,7 @@ from .entity import ApSystemsEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ApSystemsConfigEntry, - add_entities: AddEntitiesCallback, + add_entities: AddConfigEntryEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/apsystems/sensor.py b/homeassistant/components/apsystems/sensor.py index 673dba05acc..6e654cfbf61 100644 --- a/homeassistant/components/apsystems/sensor.py +++ b/homeassistant/components/apsystems/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import DiscoveryInfoType, StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -109,7 +109,7 @@ SENSORS: tuple[ApsystemsLocalApiSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ApSystemsConfigEntry, - add_entities: AddEntitiesCallback, + add_entities: AddConfigEntryEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/apsystems/switch.py b/homeassistant/components/apsystems/switch.py index 2d3b0cfd08f..e1017f95448 100644 --- a/homeassistant/components/apsystems/switch.py +++ b/homeassistant/components/apsystems/switch.py @@ -9,7 +9,7 @@ from APsystemsEZ1 import InverterReturnedError from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ApSystemsConfigEntry, ApSystemsData from .entity import ApSystemsEntity @@ -18,7 +18,7 @@ from .entity import ApSystemsEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ApSystemsConfigEntry, - add_entities: AddEntitiesCallback, + add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch platform.""" diff --git a/homeassistant/components/aquacell/sensor.py b/homeassistant/components/aquacell/sensor.py index a76d26244ad..77cd3cdd60a 100644 --- a/homeassistant/components/aquacell/sensor.py +++ b/homeassistant/components/aquacell/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AquacellConfigEntry, AquacellCoordinator @@ -83,7 +83,7 @@ SENSORS: tuple[SoftenerSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AquacellConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" softeners = config_entry.runtime_data.data diff --git a/homeassistant/components/aranet/sensor.py b/homeassistant/components/aranet/sensor.py index b5187cba1f4..c5750de1c12 100644 --- a/homeassistant/components/aranet/sensor.py +++ b/homeassistant/components/aranet/sensor.py @@ -35,7 +35,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AranetConfigEntry from .const import ARANET_MANUFACTURER_NAME @@ -176,7 +176,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: AranetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Aranet sensors.""" processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update) diff --git a/homeassistant/components/arcam_fmj/media_player.py b/homeassistant/components/arcam_fmj/media_player.py index 7a133777a0a..cd4ed7bbb05 100644 --- a/homeassistant/components/arcam_fmj/media_player.py +++ b/homeassistant/components/arcam_fmj/media_player.py @@ -24,7 +24,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ArcamFmjConfigEntry from .const import ( @@ -41,7 +41,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ArcamFmjConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" diff --git a/homeassistant/components/arve/sensor.py b/homeassistant/components/arve/sensor.py index 64d9f6f8874..dea7110f611 100644 --- a/homeassistant/components/arve/sensor.py +++ b/homeassistant/components/arve/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ArveConfigEntry from .entity import ArveDeviceEntity @@ -83,7 +83,9 @@ SENSORS: tuple[ArveDeviceEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ArveConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ArveConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Arve device based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/aseko_pool_live/binary_sensor.py b/homeassistant/components/aseko_pool_live/binary_sensor.py index c8cc31dc795..15c72614ee1 100644 --- a/homeassistant/components/aseko_pool_live/binary_sensor.py +++ b/homeassistant/components/aseko_pool_live/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AsekoConfigEntry from .entity import AsekoEntity @@ -37,7 +37,7 @@ BINARY_SENSORS: tuple[AsekoBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AsekoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Aseko Pool Live binary sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/aseko_pool_live/sensor.py b/homeassistant/components/aseko_pool_live/sensor.py index 3fe7cdd5272..f9a7287a9f1 100644 --- a/homeassistant/components/aseko_pool_live/sensor.py +++ b/homeassistant/components/aseko_pool_live/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfElectricPotential, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import AsekoConfigEntry @@ -86,7 +86,7 @@ SENSORS: list[AsekoSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: AsekoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Aseko Pool Live sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/assist_pipeline/pipeline.py b/homeassistant/components/assist_pipeline/pipeline.py index ef26e1a5a6d..cf9fb4c7212 100644 --- a/homeassistant/components/assist_pipeline/pipeline.py +++ b/homeassistant/components/assist_pipeline/pipeline.py @@ -374,6 +374,7 @@ class PipelineEventType(StrEnum): STT_VAD_END = "stt-vad-end" STT_END = "stt-end" INTENT_START = "intent-start" + INTENT_PROGRESS = "intent-progress" INTENT_END = "intent-end" TTS_START = "tts-start" TTS_END = "tts-end" @@ -1093,6 +1094,20 @@ class PipelineRun: agent_id = conversation.HOME_ASSISTANT_AGENT processed_locally = True + @callback + def chat_log_delta_listener( + chat_log: conversation.ChatLog, delta: dict + ) -> None: + """Handle chat log delta.""" + self.process_event( + PipelineEvent( + PipelineEventType.INTENT_PROGRESS, + { + "chat_log_delta": delta, + }, + ) + ) + with ( chat_session.async_get_chat_session( self.hass, user_input.conversation_id @@ -1101,6 +1116,7 @@ class PipelineRun: self.hass, session, user_input, + chat_log_delta_listener=chat_log_delta_listener, ) as chat_log, ): # It was already handled, create response and add to chat history diff --git a/homeassistant/components/assist_satellite/entity.py b/homeassistant/components/assist_satellite/entity.py index e43abb4539c..8c63525294c 100644 --- a/homeassistant/components/assist_satellite/entity.py +++ b/homeassistant/components/assist_satellite/entity.py @@ -405,7 +405,10 @@ class AssistSatelliteEntity(entity.Entity): def _internal_on_pipeline_event(self, event: PipelineEvent) -> None: """Set state based on pipeline stage.""" if event.type is PipelineEventType.WAKE_WORD_START: - self._set_state(AssistSatelliteState.IDLE) + # Only return to idle if we're not currently responding. + # The state will return to idle in tts_response_finished. + if self.state != AssistSatelliteState.RESPONDING: + self._set_state(AssistSatelliteState.IDLE) elif event.type is PipelineEventType.STT_START: self._set_state(AssistSatelliteState.LISTENING) elif event.type is PipelineEventType.INTENT_START: diff --git a/homeassistant/components/asuswrt/device_tracker.py b/homeassistant/components/asuswrt/device_tracker.py index 95d2e4c8000..ee6c3f96fc4 100644 --- a/homeassistant/components/asuswrt/device_tracker.py +++ b/homeassistant/components/asuswrt/device_tracker.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.device_tracker import ScannerEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AsusWrtConfigEntry from .router import AsusWrtDevInfo, AsusWrtRouter @@ -18,7 +18,7 @@ DEFAULT_DEVICE_NAME = "Unknown device" async def async_setup_entry( hass: HomeAssistant, entry: AsusWrtConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for AsusWrt component.""" router = entry.runtime_data @@ -38,7 +38,9 @@ async def async_setup_entry( @callback def add_entities( - router: AsusWrtRouter, async_add_entities: AddEntitiesCallback, tracked: set[str] + router: AsusWrtRouter, + async_add_entities: AddConfigEntryEntitiesCallback, + tracked: set[str], ) -> None: """Add new tracker entities from the router.""" new_tracked = [] diff --git a/homeassistant/components/asuswrt/sensor.py b/homeassistant/components/asuswrt/sensor.py index fb43e574379..c4bd5e4bded 100644 --- a/homeassistant/components/asuswrt/sensor.py +++ b/homeassistant/components/asuswrt/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -246,7 +246,7 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AsusWrtConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" router = entry.runtime_data diff --git a/homeassistant/components/atag/climate.py b/homeassistant/components/atag/climate.py index a362b71fbc8..8f1ded150f1 100644 --- a/homeassistant/components/atag/climate.py +++ b/homeassistant/components/atag/climate.py @@ -14,7 +14,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from .coordinator import AtagConfigEntry, AtagDataUpdateCoordinator @@ -32,7 +32,9 @@ HVAC_MODES = [HVACMode.AUTO, HVACMode.HEAT] async def async_setup_entry( - hass: HomeAssistant, entry: AtagConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: AtagConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load a config entry.""" async_add_entities([AtagThermostat(entry.runtime_data, "climate")]) diff --git a/homeassistant/components/atag/sensor.py b/homeassistant/components/atag/sensor.py index bd39f0b3458..ca5bbd5e614 100644 --- a/homeassistant/components/atag/sensor.py +++ b/homeassistant/components/atag/sensor.py @@ -8,7 +8,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AtagConfigEntry, AtagDataUpdateCoordinator from .entity import AtagEntity @@ -28,7 +28,7 @@ SENSORS = { async def async_setup_entry( hass: HomeAssistant, config_entry: AtagConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize sensor platform from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/atag/water_heater.py b/homeassistant/components/atag/water_heater.py index 6b013b36885..00761f47324 100644 --- a/homeassistant/components/atag/water_heater.py +++ b/homeassistant/components/atag/water_heater.py @@ -9,7 +9,7 @@ from homeassistant.components.water_heater import ( ) from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AtagConfigEntry from .entity import AtagEntity @@ -20,7 +20,7 @@ OPERATION_LIST = [STATE_OFF, STATE_ECO, STATE_PERFORMANCE] async def async_setup_entry( hass: HomeAssistant, config_entry: AtagConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize DHW device from config entry.""" async_add_entities( diff --git a/homeassistant/components/august/binary_sensor.py b/homeassistant/components/august/binary_sensor.py index fb877252010..b4c440599c4 100644 --- a/homeassistant/components/august/binary_sensor.py +++ b/homeassistant/components/august/binary_sensor.py @@ -21,7 +21,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from . import AugustConfigEntry, AugustData @@ -92,7 +92,7 @@ SENSOR_TYPES_DOORBELL: tuple[AugustDoorbellBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the August binary sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/august/button.py b/homeassistant/components/august/button.py index 79f2b67888a..4971d0cccf5 100644 --- a/homeassistant/components/august/button.py +++ b/homeassistant/components/august/button.py @@ -2,7 +2,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AugustConfigEntry from .entity import AugustEntity @@ -11,7 +11,7 @@ from .entity import AugustEntity async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up August lock wake buttons.""" data = config_entry.runtime_data diff --git a/homeassistant/components/august/camera.py b/homeassistant/components/august/camera.py index f4398455256..7b013022299 100644 --- a/homeassistant/components/august/camera.py +++ b/homeassistant/components/august/camera.py @@ -12,7 +12,7 @@ from yalexs.util import update_doorbell_image_from_activity from homeassistant.components.camera import Camera from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AugustConfigEntry, AugustData from .const import DEFAULT_NAME, DEFAULT_TIMEOUT @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up August cameras.""" data = config_entry.runtime_data diff --git a/homeassistant/components/august/event.py b/homeassistant/components/august/event.py index 49b14630337..0abc840bc69 100644 --- a/homeassistant/components/august/event.py +++ b/homeassistant/components/august/event.py @@ -16,7 +16,7 @@ from homeassistant.components.event import ( EventEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AugustConfigEntry, AugustData from .entity import AugustDescriptionEntity @@ -59,7 +59,7 @@ TYPES_DOORBELL: tuple[AugustEventEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the august event platform.""" data = config_entry.runtime_data diff --git a/homeassistant/components/august/lock.py b/homeassistant/components/august/lock.py index c681cc98808..4a37149772a 100644 --- a/homeassistant/components/august/lock.py +++ b/homeassistant/components/august/lock.py @@ -14,7 +14,7 @@ from yalexs.util import get_latest_activity, update_lock_detail_from_activity from homeassistant.components.lock import ATTR_CHANGED_BY, LockEntity, LockEntityFeature from homeassistant.const import ATTR_BATTERY_LEVEL from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.util import dt as dt_util @@ -29,7 +29,7 @@ LOCK_JAMMED_ERR = 531 async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up August locks.""" data = config_entry.runtime_data diff --git a/homeassistant/components/august/sensor.py b/homeassistant/components/august/sensor.py index b7c0d618492..94a5461149f 100644 --- a/homeassistant/components/august/sensor.py +++ b/homeassistant/components/august/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AugustConfigEntry from .const import ( @@ -82,7 +82,7 @@ SENSOR_TYPE_KEYPAD_BATTERY = AugustSensorEntityDescription[KeypadDetail]( async def async_setup_entry( hass: HomeAssistant, config_entry: AugustConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the August sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/aurora/binary_sensor.py b/homeassistant/components/aurora/binary_sensor.py index 648f6de08c9..73e732dc44a 100644 --- a/homeassistant/components/aurora/binary_sensor.py +++ b/homeassistant/components/aurora/binary_sensor.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AuroraConfigEntry from .entity import AuroraEntity @@ -13,7 +13,7 @@ from .entity import AuroraEntity async def async_setup_entry( hass: HomeAssistant, entry: AuroraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary_sensor platform.""" async_add_entities( diff --git a/homeassistant/components/aurora/sensor.py b/homeassistant/components/aurora/sensor.py index ec1b82c3c4d..d424b7e98ab 100644 --- a/homeassistant/components/aurora/sensor.py +++ b/homeassistant/components/aurora/sensor.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AuroraConfigEntry from .entity import AuroraEntity @@ -14,7 +14,7 @@ from .entity import AuroraEntity async def async_setup_entry( hass: HomeAssistant, entry: AuroraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/aurora_abb_powerone/sensor.py b/homeassistant/components/aurora_abb_powerone/sensor.py index 29d5cab2667..d35d8a2d8cb 100644 --- a/homeassistant/components/aurora_abb_powerone/sensor.py +++ b/homeassistant/components/aurora_abb_powerone/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -130,7 +130,7 @@ SENSOR_TYPES = [ async def async_setup_entry( hass: HomeAssistant, config_entry: AuroraAbbConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up aurora_abb_powerone sensor based on a config entry.""" diff --git a/homeassistant/components/aussie_broadband/sensor.py b/homeassistant/components/aussie_broadband/sensor.py index 49da78da8de..41a2f164095 100644 --- a/homeassistant/components/aussie_broadband/sensor.py +++ b/homeassistant/components/aussie_broadband/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfInformation, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -123,7 +123,7 @@ SENSOR_DESCRIPTIONS: tuple[SensorValueEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AussieBroadbandConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Aussie Broadband sensor platform from a config entry.""" diff --git a/homeassistant/components/autarco/sensor.py b/homeassistant/components/autarco/sensor.py index b7c4312815b..1635adefdb8 100644 --- a/homeassistant/components/autarco/sensor.py +++ b/homeassistant/components/autarco/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -172,7 +172,7 @@ SENSORS_INVERTER: tuple[AutarcoInverterSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AutarcoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Autarco sensors based on a config entry.""" entities: list[SensorEntity] = [] diff --git a/homeassistant/components/awair/sensor.py b/homeassistant/components/awair/sensor.py index c92009d9b1b..a0c4b5ba8fe 100644 --- a/homeassistant/components/awair/sensor.py +++ b/homeassistant/components/awair/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -133,7 +133,7 @@ SENSOR_TYPES_DUST: tuple[AwairSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AwairConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Awair sensor entity based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/axis/binary_sensor.py b/homeassistant/components/axis/binary_sensor.py index d6f132874b6..6933380c094 100644 --- a/homeassistant/components/axis/binary_sensor.py +++ b/homeassistant/components/axis/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from . import AxisConfigEntry @@ -178,7 +178,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AxisConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Axis binary sensor.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/axis/camera.py b/homeassistant/components/axis/camera.py index a5a00bcd1ab..089a018ee5b 100644 --- a/homeassistant/components/axis/camera.py +++ b/homeassistant/components/axis/camera.py @@ -7,7 +7,7 @@ from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging from homeassistant.const import HTTP_DIGEST_AUTHENTICATION from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AxisConfigEntry from .const import DEFAULT_STREAM_PROFILE, DEFAULT_VIDEO_SOURCE @@ -18,7 +18,7 @@ from .hub import AxisHub async def async_setup_entry( hass: HomeAssistant, config_entry: AxisConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Axis camera video stream.""" filter_urllib3_logging() diff --git a/homeassistant/components/axis/light.py b/homeassistant/components/axis/light.py index d0d144a28fa..0c6015efced 100644 --- a/homeassistant/components/axis/light.py +++ b/homeassistant/components/axis/light.py @@ -12,7 +12,7 @@ from homeassistant.components.light import ( LightEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AxisConfigEntry from .entity import TOPIC_TO_EVENT_TYPE, AxisEventDescription, AxisEventEntity @@ -46,7 +46,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AxisConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Axis light platform.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/axis/switch.py b/homeassistant/components/axis/switch.py index 17824302871..55250b5f489 100644 --- a/homeassistant/components/axis/switch.py +++ b/homeassistant/components/axis/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AxisConfigEntry from .entity import AxisEventDescription, AxisEventEntity @@ -39,7 +39,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: AxisConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Axis switch platform.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/azure_devops/sensor.py b/homeassistant/components/azure_devops/sensor.py index 1d590032a85..55c821a119e 100644 --- a/homeassistant/components/azure_devops/sensor.py +++ b/homeassistant/components/azure_devops/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( SensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -145,7 +145,7 @@ def parse_datetime(value: str | None) -> datetime | None: async def async_setup_entry( hass: HomeAssistant, entry: AzureDevOpsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Azure DevOps sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/backup/manager.py b/homeassistant/components/backup/manager.py index 25393a872cc..81826ffcb24 100644 --- a/homeassistant/components/backup/manager.py +++ b/homeassistant/components/backup/manager.py @@ -4,6 +4,7 @@ from __future__ import annotations import abc import asyncio +from collections import defaultdict from collections.abc import AsyncIterator, Callable, Coroutine from dataclasses import dataclass, replace from enum import StrEnum @@ -560,8 +561,15 @@ class BackupManager: return_exceptions=True, ) for idx, result in enumerate(list_backups_results): + agent_id = agent_ids[idx] if isinstance(result, BackupAgentError): - agent_errors[agent_ids[idx]] = result + agent_errors[agent_id] = result + continue + if isinstance(result, Exception): + agent_errors[agent_id] = result + LOGGER.error( + "Unexpected error for %s: %s", agent_id, result, exc_info=result + ) continue if isinstance(result, BaseException): raise result # unexpected error @@ -588,7 +596,7 @@ class BackupManager: name=agent_backup.name, with_automatic_settings=with_automatic_settings, ) - backups[backup_id].agents[agent_ids[idx]] = AgentBackupStatus( + backups[backup_id].agents[agent_id] = AgentBackupStatus( protected=agent_backup.protected, size=agent_backup.size, ) @@ -611,8 +619,15 @@ class BackupManager: return_exceptions=True, ) for idx, result in enumerate(get_backup_results): + agent_id = agent_ids[idx] if isinstance(result, BackupAgentError): - agent_errors[agent_ids[idx]] = result + agent_errors[agent_id] = result + continue + if isinstance(result, Exception): + agent_errors[agent_id] = result + LOGGER.error( + "Unexpected error for %s: %s", agent_id, result, exc_info=result + ) continue if isinstance(result, BaseException): raise result # unexpected error @@ -640,7 +655,7 @@ class BackupManager: name=result.name, with_automatic_settings=with_automatic_settings, ) - backup.agents[agent_ids[idx]] = AgentBackupStatus( + backup.agents[agent_id] = AgentBackupStatus( protected=result.protected, size=result.size, ) @@ -663,21 +678,31 @@ class BackupManager: return None return with_automatic_settings - async def async_delete_backup(self, backup_id: str) -> dict[str, Exception]: + async def async_delete_backup( + self, backup_id: str, *, agent_ids: list[str] | None = None + ) -> dict[str, Exception]: """Delete a backup.""" agent_errors: dict[str, Exception] = {} - agent_ids = list(self.backup_agents) + if agent_ids is None: + agent_ids = list(self.backup_agents) delete_backup_results = await asyncio.gather( *( - agent.async_delete_backup(backup_id) - for agent in self.backup_agents.values() + self.backup_agents[agent_id].async_delete_backup(backup_id) + for agent_id in agent_ids ), return_exceptions=True, ) for idx, result in enumerate(delete_backup_results): + agent_id = agent_ids[idx] if isinstance(result, BackupAgentError): - agent_errors[agent_ids[idx]] = result + agent_errors[agent_id] = result + continue + if isinstance(result, Exception): + agent_errors[agent_id] = result + LOGGER.error( + "Unexpected error for %s: %s", agent_id, result, exc_info=result + ) continue if isinstance(result, BaseException): raise result # unexpected error @@ -710,35 +735,71 @@ class BackupManager: # Run the include filter first to ensure we only consider backups that # should be included in the deletion process. backups = include_filter(backups) + backups_by_agent: dict[str, dict[str, ManagerBackup]] = defaultdict(dict) + for backup_id, backup in backups.items(): + for agent_id in backup.agents: + backups_by_agent[agent_id][backup_id] = backup - LOGGER.debug("Total automatic backups: %s", backups) + LOGGER.debug("Backups returned by include filter: %s", backups) + LOGGER.debug( + "Backups returned by include filter by agent: %s", + {agent_id: list(backups) for agent_id, backups in backups_by_agent.items()}, + ) backups_to_delete = delete_filter(backups) + LOGGER.debug("Backups returned by delete filter: %s", backups_to_delete) + if not backups_to_delete: return # always delete oldest backup first - backups_to_delete = dict( - sorted( - backups_to_delete.items(), - key=lambda backup_item: backup_item[1].date, - ) + backups_to_delete_by_agent: dict[str, dict[str, ManagerBackup]] = defaultdict( + dict + ) + for backup_id, backup in sorted( + backups_to_delete.items(), + key=lambda backup_item: backup_item[1].date, + ): + for agent_id in backup.agents: + backups_to_delete_by_agent[agent_id][backup_id] = backup + LOGGER.debug( + "Backups returned by delete filter by agent: %s", + { + agent_id: list(backups) + for agent_id, backups in backups_to_delete_by_agent.items() + }, + ) + for agent_id, to_delete_from_agent in backups_to_delete_by_agent.items(): + if len(to_delete_from_agent) >= len(backups_by_agent[agent_id]): + # Never delete the last backup. + last_backup = to_delete_from_agent.popitem() + LOGGER.debug( + "Keeping the last backup %s for agent %s", last_backup, agent_id + ) + + LOGGER.debug( + "Backups to delete by agent: %s", + { + agent_id: list(backups) + for agent_id, backups in backups_to_delete_by_agent.items() + }, ) - if len(backups_to_delete) >= len(backups): - # Never delete the last backup. - last_backup = backups_to_delete.popitem() - LOGGER.debug("Keeping the last backup: %s", last_backup) + backup_ids_to_delete: dict[str, set[str]] = defaultdict(set) + for agent_id, to_delete in backups_to_delete_by_agent.items(): + for backup_id in to_delete: + backup_ids_to_delete[backup_id].add(agent_id) - LOGGER.debug("Backups to delete: %s", backups_to_delete) - - if not backups_to_delete: + if not backup_ids_to_delete: return - backup_ids = list(backups_to_delete) + backup_ids = list(backup_ids_to_delete) delete_results = await asyncio.gather( - *(self.async_delete_backup(backup_id) for backup_id in backups_to_delete) + *( + self.async_delete_backup(backup_id, agent_ids=list(agent_ids)) + for backup_id, agent_ids in backup_ids_to_delete.items() + ) ) agent_errors = { backup_id: error diff --git a/homeassistant/components/baf/binary_sensor.py b/homeassistant/components/baf/binary_sensor.py index 7c855711712..e12bfd8b90c 100644 --- a/homeassistant/components/baf/binary_sensor.py +++ b/homeassistant/components/baf/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .entity import BAFDescriptionEntity @@ -41,7 +41,7 @@ OCCUPANCY_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF binary sensors.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/climate.py b/homeassistant/components/baf/climate.py index c30d49e8c9d..abcc2afe254 100644 --- a/homeassistant/components/baf/climate.py +++ b/homeassistant/components/baf/climate.py @@ -12,7 +12,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .entity import BAFEntity @@ -21,7 +21,7 @@ from .entity import BAFEntity async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF fan auto comfort.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/fan.py b/homeassistant/components/baf/fan.py index 8f7aab40b79..c990a248588 100644 --- a/homeassistant/components/baf/fan.py +++ b/homeassistant/components/baf/fan.py @@ -14,7 +14,7 @@ from homeassistant.components.fan import ( FanEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -28,7 +28,7 @@ from .entity import BAFEntity async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SenseME fans.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/light.py b/homeassistant/components/baf/light.py index 4c0b1e353fe..e8298a8e4d4 100644 --- a/homeassistant/components/baf/light.py +++ b/homeassistant/components/baf/light.py @@ -13,7 +13,7 @@ from homeassistant.components.light import ( LightEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .entity import BAFEntity @@ -22,7 +22,7 @@ from .entity import BAFEntity async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF lights.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/number.py b/homeassistant/components/baf/number.py index a2e5e704e4d..87b5cdc095b 100644 --- a/homeassistant/components/baf/number.py +++ b/homeassistant/components/baf/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .const import HALF_DAY_SECS, ONE_DAY_SECS, ONE_MIN_SECS, SPEED_RANGE @@ -116,7 +116,7 @@ LIGHT_NUMBER_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF numbers.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/sensor.py b/homeassistant/components/baf/sensor.py index 7e664254a38..e9b8965b7c4 100644 --- a/homeassistant/components/baf/sensor.py +++ b/homeassistant/components/baf/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .entity import BAFDescriptionEntity @@ -93,7 +93,7 @@ FAN_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF fan sensors.""" device = entry.runtime_data diff --git a/homeassistant/components/baf/switch.py b/homeassistant/components/baf/switch.py index e18e26ddcaa..50bd90a6107 100644 --- a/homeassistant/components/baf/switch.py +++ b/homeassistant/components/baf/switch.py @@ -11,7 +11,7 @@ from aiobafi6 import Device from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BAFConfigEntry from .entity import BAFDescriptionEntity @@ -103,7 +103,7 @@ LIGHT_SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: BAFConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BAF fan switches.""" device = entry.runtime_data diff --git a/homeassistant/components/balboa/binary_sensor.py b/homeassistant/components/balboa/binary_sensor.py index b8c62ce8abf..437a01866b8 100644 --- a/homeassistant/components/balboa/binary_sensor.py +++ b/homeassistant/components/balboa/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BalboaConfigEntry from .entity import BalboaEntity @@ -22,7 +22,7 @@ from .entity import BalboaEntity async def async_setup_entry( hass: HomeAssistant, entry: BalboaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the spa's binary sensors.""" spa = entry.runtime_data diff --git a/homeassistant/components/balboa/climate.py b/homeassistant/components/balboa/climate.py index 76b02f0e165..3fb2457d610 100644 --- a/homeassistant/components/balboa/climate.py +++ b/homeassistant/components/balboa/climate.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BalboaConfigEntry from .const import DOMAIN @@ -47,7 +47,7 @@ TEMPERATURE_UNIT_MAP = { async def async_setup_entry( hass: HomeAssistant, entry: BalboaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the spa climate entity.""" async_add_entities([BalboaClimateEntity(entry.runtime_data)]) diff --git a/homeassistant/components/balboa/fan.py b/homeassistant/components/balboa/fan.py index 3ecfec53a1e..b0d4379594b 100644 --- a/homeassistant/components/balboa/fan.py +++ b/homeassistant/components/balboa/fan.py @@ -10,7 +10,7 @@ from pybalboa.enums import OffOnState, UnknownState from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -23,7 +23,7 @@ from .entity import BalboaEntity async def async_setup_entry( hass: HomeAssistant, entry: BalboaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the spa's pumps.""" spa = entry.runtime_data diff --git a/homeassistant/components/balboa/light.py b/homeassistant/components/balboa/light.py index 21e4dfc5e08..2f48747c084 100644 --- a/homeassistant/components/balboa/light.py +++ b/homeassistant/components/balboa/light.py @@ -9,7 +9,7 @@ from pybalboa.enums import OffOnState, UnknownState from homeassistant.components.light import ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BalboaConfigEntry from .entity import BalboaEntity @@ -18,7 +18,7 @@ from .entity import BalboaEntity async def async_setup_entry( hass: HomeAssistant, entry: BalboaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the spa's lights.""" spa = entry.runtime_data diff --git a/homeassistant/components/balboa/manifest.json b/homeassistant/components/balboa/manifest.json index 867e277358c..61cb5bbbf69 100644 --- a/homeassistant/components/balboa/manifest.json +++ b/homeassistant/components/balboa/manifest.json @@ -14,5 +14,5 @@ "documentation": "https://www.home-assistant.io/integrations/balboa", "iot_class": "local_push", "loggers": ["pybalboa"], - "requirements": ["pybalboa==1.0.2"] + "requirements": ["pybalboa==1.1.2"] } diff --git a/homeassistant/components/balboa/select.py b/homeassistant/components/balboa/select.py index e88e40ab063..ea82760744c 100644 --- a/homeassistant/components/balboa/select.py +++ b/homeassistant/components/balboa/select.py @@ -5,7 +5,7 @@ from pybalboa.enums import LowHighRange from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BalboaConfigEntry from .entity import BalboaEntity @@ -14,7 +14,7 @@ from .entity import BalboaEntity async def async_setup_entry( hass: HomeAssistant, entry: BalboaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the spa select entity.""" spa = entry.runtime_data diff --git a/homeassistant/components/bang_olufsen/event.py b/homeassistant/components/bang_olufsen/event.py index 99e5c8bb6fd..91e04b92330 100644 --- a/homeassistant/components/bang_olufsen/event.py +++ b/homeassistant/components/bang_olufsen/event.py @@ -6,7 +6,7 @@ from homeassistant.components.event import EventDeviceClass, EventEntity from homeassistant.const import CONF_MODEL from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BangOlufsenConfigEntry from .const import ( @@ -25,7 +25,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: BangOlufsenConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensor entities from config entry.""" diff --git a/homeassistant/components/bang_olufsen/media_player.py b/homeassistant/components/bang_olufsen/media_player.py index 282ecdd2ae5..efb6843356b 100644 --- a/homeassistant/components/bang_olufsen/media_player.py +++ b/homeassistant/components/bang_olufsen/media_player.py @@ -64,7 +64,7 @@ from homeassistant.helpers import ( from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.util.dt import utcnow @@ -118,7 +118,7 @@ BANG_OLUFSEN_FEATURES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BangOlufsenConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Media Player entity from config entry.""" # Add MediaPlayer entity diff --git a/homeassistant/components/blebox/binary_sensor.py b/homeassistant/components/blebox/binary_sensor.py index 2aa86059ee2..b9032e6e705 100644 --- a/homeassistant/components/blebox/binary_sensor.py +++ b/homeassistant/components/blebox/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -24,7 +24,7 @@ BINARY_SENSOR_TYPES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox entry.""" entities = [ diff --git a/homeassistant/components/blebox/button.py b/homeassistant/components/blebox/button.py index 90356c8ae14..15867f84029 100644 --- a/homeassistant/components/blebox/button.py +++ b/homeassistant/components/blebox/button.py @@ -6,7 +6,7 @@ import blebox_uniapi.button from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -15,7 +15,7 @@ from .entity import BleBoxEntity async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox button entry.""" entities = [ diff --git a/homeassistant/components/blebox/climate.py b/homeassistant/components/blebox/climate.py index 2c528d50e3e..dbf4a326990 100644 --- a/homeassistant/components/blebox/climate.py +++ b/homeassistant/components/blebox/climate.py @@ -13,7 +13,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -38,7 +38,7 @@ BLEBOX_TO_HVACACTION = { async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox climate entity.""" entities = [ diff --git a/homeassistant/components/blebox/cover.py b/homeassistant/components/blebox/cover.py index 4f2a7eeef11..c52c551bbac 100644 --- a/homeassistant/components/blebox/cover.py +++ b/homeassistant/components/blebox/cover.py @@ -16,7 +16,7 @@ from homeassistant.components.cover import ( CoverState, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -45,7 +45,7 @@ BLEBOX_TO_HASS_COVER_STATES = { async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox entry.""" entities = [ diff --git a/homeassistant/components/blebox/light.py b/homeassistant/components/blebox/light.py index c3c9de8be51..86ec8993779 100644 --- a/homeassistant/components/blebox/light.py +++ b/homeassistant/components/blebox/light.py @@ -21,7 +21,7 @@ from homeassistant.components.light import ( LightEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import BleBoxConfigEntry @@ -35,7 +35,7 @@ SCAN_INTERVAL = timedelta(seconds=5) async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox entry.""" entities = [ diff --git a/homeassistant/components/blebox/sensor.py b/homeassistant/components/blebox/sensor.py index c0abff31257..5120a7a3c98 100644 --- a/homeassistant/components/blebox/sensor.py +++ b/homeassistant/components/blebox/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -116,7 +116,7 @@ SENSOR_TYPES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox entry.""" entities = [ diff --git a/homeassistant/components/blebox/switch.py b/homeassistant/components/blebox/switch.py index c6f439e27c5..1598d4db6fa 100644 --- a/homeassistant/components/blebox/switch.py +++ b/homeassistant/components/blebox/switch.py @@ -7,7 +7,7 @@ import blebox_uniapi.switch from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BleBoxConfigEntry from .entity import BleBoxEntity @@ -18,7 +18,7 @@ SCAN_INTERVAL = timedelta(seconds=5) async def async_setup_entry( hass: HomeAssistant, config_entry: BleBoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a BleBox switch entity.""" entities = [ diff --git a/homeassistant/components/blink/alarm_control_panel.py b/homeassistant/components/blink/alarm_control_panel.py index bfb8aa9a3a0..17fd003742f 100644 --- a/homeassistant/components/blink/alarm_control_panel.py +++ b/homeassistant/components/blink/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DEFAULT_ATTRIBUTION, DEFAULT_BRAND, DOMAIN @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: BlinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Blink Alarm Control Panels.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/blink/binary_sensor.py b/homeassistant/components/blink/binary_sensor.py index c11d4cfea23..3d5430c8d1f 100644 --- a/homeassistant/components/blink/binary_sensor.py +++ b/homeassistant/components/blink/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -48,7 +48,7 @@ BINARY_SENSORS_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BlinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the blink binary sensors.""" diff --git a/homeassistant/components/blink/camera.py b/homeassistant/components/blink/camera.py index e35dd20eea7..04bd125d249 100644 --- a/homeassistant/components/blink/camera.py +++ b/homeassistant/components/blink/camera.py @@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -38,7 +38,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: BlinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Blink Camera.""" diff --git a/homeassistant/components/blink/sensor.py b/homeassistant/components/blink/sensor.py index e0b5989cc80..1df708c3a10 100644 --- a/homeassistant/components/blink/sensor.py +++ b/homeassistant/components/blink/sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DEFAULT_BRAND, DOMAIN, TYPE_TEMPERATURE, TYPE_WIFI_STRENGTH @@ -47,7 +47,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BlinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize a Blink sensor.""" diff --git a/homeassistant/components/blink/switch.py b/homeassistant/components/blink/switch.py index 8eabd5c0e59..4f490e28310 100644 --- a/homeassistant/components/blink/switch.py +++ b/homeassistant/components/blink/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DEFAULT_BRAND, DOMAIN, TYPE_CAMERA_ARMED @@ -30,7 +30,7 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BlinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Blink switches.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/blue_current/sensor.py b/homeassistant/components/blue_current/sensor.py index be39e9571ec..9ea444f9ec2 100644 --- a/homeassistant/components/blue_current/sensor.py +++ b/homeassistant/components/blue_current/sensor.py @@ -16,7 +16,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BlueCurrentConfigEntry, Connector from .const import DOMAIN @@ -212,7 +212,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: BlueCurrentConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Blue Current sensors.""" connector = entry.runtime_data diff --git a/homeassistant/components/bluemaestro/sensor.py b/homeassistant/components/bluemaestro/sensor.py index 57702d4ff31..1163f8a1ff6 100644 --- a/homeassistant/components/bluemaestro/sensor.py +++ b/homeassistant/components/bluemaestro/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import BlueMaestroConfigEntry @@ -116,7 +116,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: BlueMaestroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the BlueMaestro BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/blueprint/importer.py b/homeassistant/components/blueprint/importer.py index 8582761bafb..83afa511b68 100644 --- a/homeassistant/components/blueprint/importer.py +++ b/homeassistant/components/blueprint/importer.py @@ -6,6 +6,7 @@ from contextlib import suppress from dataclasses import dataclass import html import re +from typing import TYPE_CHECKING import voluptuous as vol import yarl @@ -195,8 +196,8 @@ async def fetch_blueprint_from_github_gist_url( ) gist = await resp.json() - blueprint = None - filename = None + blueprint: Blueprint | None = None + filename: str | None = None content: str for filename, info in gist["files"].items(): @@ -218,6 +219,8 @@ async def fetch_blueprint_from_github_gist_url( "No valid blueprint found in the gist. The blueprint file needs to end with" " '.yaml'" ) + if TYPE_CHECKING: + assert isinstance(filename, str) return ImportedBlueprint( f"{gist['owner']['login']}/{filename[:-5]}", content, blueprint diff --git a/homeassistant/components/bluesound/media_player.py b/homeassistant/components/bluesound/media_player.py index 6bb3c101cd1..135d1b5d27e 100644 --- a/homeassistant/components/bluesound/media_player.py +++ b/homeassistant/components/bluesound/media_player.py @@ -32,7 +32,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -61,7 +61,7 @@ POLL_TIMEOUT = 120 async def async_setup_entry( hass: HomeAssistant, config_entry: BluesoundConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Bluesound entry.""" bluesound_player = BluesoundPlayer( diff --git a/homeassistant/components/bmw_connected_drive/binary_sensor.py b/homeassistant/components/bmw_connected_drive/binary_sensor.py index 5a58c707d6a..01cdbbdc94d 100644 --- a/homeassistant/components/bmw_connected_drive/binary_sensor.py +++ b/homeassistant/components/bmw_connected_drive/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import UnitSystem from . import BMWConfigEntry @@ -200,7 +200,7 @@ SENSOR_TYPES: tuple[BMWBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the BMW binary sensors from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/button.py b/homeassistant/components/bmw_connected_drive/button.py index a7c31d0ef79..f8980201f3f 100644 --- a/homeassistant/components/bmw_connected_drive/button.py +++ b/homeassistant/components/bmw_connected_drive/button.py @@ -14,7 +14,7 @@ from bimmer_connected.vehicle.remote_services import RemoteServiceStatus from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as BMW_DOMAIN, BMWConfigEntry from .entity import BMWBaseEntity @@ -69,7 +69,7 @@ BUTTON_TYPES: tuple[BMWButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the BMW buttons from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/device_tracker.py b/homeassistant/components/bmw_connected_drive/device_tracker.py index 74df8693f7a..23273cc8ba9 100644 --- a/homeassistant/components/bmw_connected_drive/device_tracker.py +++ b/homeassistant/components/bmw_connected_drive/device_tracker.py @@ -9,7 +9,7 @@ from bimmer_connected.vehicle import MyBMWVehicle from homeassistant.components.device_tracker import TrackerEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BMWConfigEntry from .const import ATTR_DIRECTION @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW tracker from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/lock.py b/homeassistant/components/bmw_connected_drive/lock.py index 4bec12e796b..9d8965d6ebf 100644 --- a/homeassistant/components/bmw_connected_drive/lock.py +++ b/homeassistant/components/bmw_connected_drive/lock.py @@ -12,7 +12,7 @@ from bimmer_connected.vehicle.doors_windows import LockState from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as BMW_DOMAIN, BMWConfigEntry from .coordinator import BMWDataUpdateCoordinator @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW lock from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/number.py b/homeassistant/components/bmw_connected_drive/number.py index c6a328ecc20..8361306ba9d 100644 --- a/homeassistant/components/bmw_connected_drive/number.py +++ b/homeassistant/components/bmw_connected_drive/number.py @@ -16,7 +16,7 @@ from homeassistant.components.number import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as BMW_DOMAIN, BMWConfigEntry from .coordinator import BMWDataUpdateCoordinator @@ -58,7 +58,7 @@ NUMBER_TYPES: list[BMWNumberEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW number from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/select.py b/homeassistant/components/bmw_connected_drive/select.py index 385b45fd9fa..f144d3a71df 100644 --- a/homeassistant/components/bmw_connected_drive/select.py +++ b/homeassistant/components/bmw_connected_drive/select.py @@ -13,7 +13,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import UnitOfElectricCurrent from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as BMW_DOMAIN, BMWConfigEntry from .coordinator import BMWDataUpdateCoordinator @@ -65,7 +65,7 @@ SELECT_TYPES: tuple[BMWSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW lock from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/sensor.py b/homeassistant/components/bmw_connected_drive/sensor.py index b7be367d57d..114412ef9f2 100644 --- a/homeassistant/components/bmw_connected_drive/sensor.py +++ b/homeassistant/components/bmw_connected_drive/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import BMWConfigEntry @@ -190,7 +190,7 @@ SENSOR_TYPES: list[BMWSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW sensors from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bmw_connected_drive/switch.py b/homeassistant/components/bmw_connected_drive/switch.py index 600ad41165a..f46969f3e9b 100644 --- a/homeassistant/components/bmw_connected_drive/switch.py +++ b/homeassistant/components/bmw_connected_drive/switch.py @@ -12,7 +12,7 @@ from bimmer_connected.vehicle.fuel_and_battery import ChargingState from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as BMW_DOMAIN, BMWConfigEntry from .coordinator import BMWDataUpdateCoordinator @@ -66,7 +66,7 @@ NUMBER_TYPES: list[BMWSwitchEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: BMWConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the MyBMW switch from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bond/button.py b/homeassistant/components/bond/button.py index 42915c7dc0b..47c8356d08e 100644 --- a/homeassistant/components/bond/button.py +++ b/homeassistant/components/bond/button.py @@ -8,7 +8,7 @@ from bond_async import Action from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BondConfigEntry from .entity import BondEntity @@ -257,7 +257,7 @@ BUTTONS: tuple[BondButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: BondConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bond button devices.""" data = entry.runtime_data diff --git a/homeassistant/components/bond/cover.py b/homeassistant/components/bond/cover.py index 66344a1913d..d2a78819fae 100644 --- a/homeassistant/components/bond/cover.py +++ b/homeassistant/components/bond/cover.py @@ -13,7 +13,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BondConfigEntry from .entity import BondEntity @@ -34,7 +34,7 @@ def _hass_to_bond_position(hass_position: int) -> int: async def async_setup_entry( hass: HomeAssistant, entry: BondConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bond cover devices.""" data = entry.runtime_data diff --git a/homeassistant/components/bond/fan.py b/homeassistant/components/bond/fan.py index 76a0daa46f9..c228c7355dd 100644 --- a/homeassistant/components/bond/fan.py +++ b/homeassistant/components/bond/fan.py @@ -19,7 +19,7 @@ from homeassistant.components.fan import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -40,7 +40,7 @@ PRESET_MODE_BREEZE = "Breeze" async def async_setup_entry( hass: HomeAssistant, entry: BondConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bond fan devices.""" data = entry.runtime_data diff --git a/homeassistant/components/bond/light.py b/homeassistant/components/bond/light.py index c3cf23e4fad..9c51165ebdb 100644 --- a/homeassistant/components/bond/light.py +++ b/homeassistant/components/bond/light.py @@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BondConfigEntry from .const import ( @@ -42,7 +42,7 @@ ENTITY_SERVICES = [ async def async_setup_entry( hass: HomeAssistant, entry: BondConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bond light devices.""" data = entry.runtime_data diff --git a/homeassistant/components/bond/switch.py b/homeassistant/components/bond/switch.py index ace6d307e6d..fa2ccd2ca93 100644 --- a/homeassistant/components/bond/switch.py +++ b/homeassistant/components/bond/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BondConfigEntry from .const import ATTR_POWER_STATE, SERVICE_SET_POWER_TRACKED_STATE @@ -22,7 +22,7 @@ from .entity import BondEntity async def async_setup_entry( hass: HomeAssistant, entry: BondConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bond generic devices.""" data = entry.runtime_data diff --git a/homeassistant/components/bosch_shc/binary_sensor.py b/homeassistant/components/bosch_shc/binary_sensor.py index dd0f31ea6f9..30d823fd608 100644 --- a/homeassistant/components/bosch_shc/binary_sensor.py +++ b/homeassistant/components/bosch_shc/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BoschConfigEntry from .entity import SHCEntity @@ -19,7 +19,7 @@ from .entity import SHCEntity async def async_setup_entry( hass: HomeAssistant, config_entry: BoschConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SHC binary sensor platform.""" session = config_entry.runtime_data diff --git a/homeassistant/components/bosch_shc/cover.py b/homeassistant/components/bosch_shc/cover.py index 55d6bfc35de..766dcf37ce9 100644 --- a/homeassistant/components/bosch_shc/cover.py +++ b/homeassistant/components/bosch_shc/cover.py @@ -11,7 +11,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BoschConfigEntry from .entity import SHCEntity @@ -20,7 +20,7 @@ from .entity import SHCEntity async def async_setup_entry( hass: HomeAssistant, config_entry: BoschConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SHC cover platform.""" session = config_entry.runtime_data diff --git a/homeassistant/components/bosch_shc/sensor.py b/homeassistant/components/bosch_shc/sensor.py index 6408e21654e..885908804c0 100644 --- a/homeassistant/components/bosch_shc/sensor.py +++ b/homeassistant/components/bosch_shc/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import BoschConfigEntry @@ -126,7 +126,7 @@ SENSOR_DESCRIPTIONS: dict[str, SHCSensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: BoschConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SHC sensor platform.""" session = config_entry.runtime_data diff --git a/homeassistant/components/bosch_shc/switch.py b/homeassistant/components/bosch_shc/switch.py index 76b1da3e534..bf1d5d39ee5 100644 --- a/homeassistant/components/bosch_shc/switch.py +++ b/homeassistant/components/bosch_shc/switch.py @@ -21,7 +21,7 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import BoschConfigEntry @@ -79,7 +79,7 @@ SWITCH_TYPES: dict[str, SHCSwitchEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: BoschConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SHC switch platform.""" session = config_entry.runtime_data diff --git a/homeassistant/components/braviatv/button.py b/homeassistant/components/braviatv/button.py index 626e5a225b7..20250949bcb 100644 --- a/homeassistant/components/braviatv/button.py +++ b/homeassistant/components/braviatv/button.py @@ -12,7 +12,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import BraviaTVConfigEntry, BraviaTVCoordinator from .entity import BraviaTVEntity @@ -44,7 +44,7 @@ BUTTONS: tuple[BraviaTVButtonDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BraviaTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Bravia TV Button entities.""" diff --git a/homeassistant/components/braviatv/coordinator.py b/homeassistant/components/braviatv/coordinator.py index 1cc306bd5cf..039726de94d 100644 --- a/homeassistant/components/braviatv/coordinator.py +++ b/homeassistant/components/braviatv/coordinator.py @@ -39,7 +39,7 @@ _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL: Final = timedelta(seconds=10) -type BraviaTVConfigEntry = ConfigEntry["BraviaTVCoordinator"] +type BraviaTVConfigEntry = ConfigEntry[BraviaTVCoordinator] def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P]( diff --git a/homeassistant/components/braviatv/media_player.py b/homeassistant/components/braviatv/media_player.py index ca48c6ee639..fe9c386b060 100644 --- a/homeassistant/components/braviatv/media_player.py +++ b/homeassistant/components/braviatv/media_player.py @@ -16,7 +16,7 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SourceType from .coordinator import BraviaTVConfigEntry @@ -26,7 +26,7 @@ from .entity import BraviaTVEntity async def async_setup_entry( hass: HomeAssistant, config_entry: BraviaTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bravia TV Media Player from a config_entry.""" diff --git a/homeassistant/components/braviatv/remote.py b/homeassistant/components/braviatv/remote.py index 9f4a573827b..0611e367445 100644 --- a/homeassistant/components/braviatv/remote.py +++ b/homeassistant/components/braviatv/remote.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import BraviaTVConfigEntry from .entity import BraviaTVEntity @@ -16,7 +16,7 @@ from .entity import BraviaTVEntity async def async_setup_entry( hass: HomeAssistant, config_entry: BraviaTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Bravia TV Remote from a config entry.""" diff --git a/homeassistant/components/bring/event.py b/homeassistant/components/bring/event.py index 699dba9015a..08d06b596b8 100644 --- a/homeassistant/components/bring/event.py +++ b/homeassistant/components/bring/event.py @@ -9,7 +9,7 @@ from bring_api import ActivityType, BringList from homeassistant.components.event import EventEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BringConfigEntry from .coordinator import BringDataUpdateCoordinator @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: BringConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the event platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bring/sensor.py b/homeassistant/components/bring/sensor.py index bfe93619dbb..2a09d574607 100644 --- a/homeassistant/components/bring/sensor.py +++ b/homeassistant/components/bring/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import BringConfigEntry, BringData, BringDataUpdateCoordinator @@ -85,7 +85,7 @@ SENSOR_DESCRIPTIONS: tuple[BringSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: BringConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/bring/todo.py b/homeassistant/components/bring/todo.py index 4de306273f3..d1eb9e78341 100644 --- a/homeassistant/components/bring/todo.py +++ b/homeassistant/components/bring/todo.py @@ -24,7 +24,7 @@ from homeassistant.components.todo import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_ITEM_NAME, @@ -41,7 +41,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: BringConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor from a config entry created in the integrations UI.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/broadlink/climate.py b/homeassistant/components/broadlink/climate.py index 25a6bbd60a5..5be04c24f0d 100644 --- a/homeassistant/components/broadlink/climate.py +++ b/homeassistant/components/broadlink/climate.py @@ -13,7 +13,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PRECISION_HALVES, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, DOMAINS_AND_TYPES from .device import BroadlinkDevice @@ -31,7 +31,7 @@ class SensorMode(IntEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink climate entities.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/light.py b/homeassistant/components/broadlink/light.py index 39d6caaa49f..64698e57249 100644 --- a/homeassistant/components/broadlink/light.py +++ b/homeassistant/components/broadlink/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import BroadlinkEntity @@ -29,7 +29,7 @@ BROADLINK_COLOR_MODE_SCENES = 2 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink light.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/remote.py b/homeassistant/components/broadlink/remote.py index 18a3a82017c..c1196b03310 100644 --- a/homeassistant/components/broadlink/remote.py +++ b/homeassistant/components/broadlink/remote.py @@ -37,7 +37,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_COMMAND, STATE_OFF from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.storage import Store from homeassistant.util import dt as dt_util @@ -92,7 +92,7 @@ SERVICE_DELETE_SCHEMA = COMMAND_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Broadlink remote.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/select.py b/homeassistant/components/broadlink/select.py index 6253adc308a..661fc62600d 100644 --- a/homeassistant/components/broadlink/select.py +++ b/homeassistant/components/broadlink/select.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BroadlinkDevice from .const import DOMAIN @@ -28,7 +28,7 @@ DAY_NAME_TO_ID = {v: k for k, v in DAY_ID_TO_NAME.items()} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink select.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/sensor.py b/homeassistant/components/broadlink/sensor.py index b7ae71ff803..e7d420f0c0e 100644 --- a/homeassistant/components/broadlink/sensor.py +++ b/homeassistant/components/broadlink/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import BroadlinkEntity @@ -86,7 +86,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink sensor.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/switch.py b/homeassistant/components/broadlink/switch.py index 9098440a5c4..d6869ac4c9c 100644 --- a/homeassistant/components/broadlink/switch.py +++ b/homeassistant/components/broadlink/switch.py @@ -30,7 +30,10 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -85,7 +88,7 @@ async def async_setup_platform( if switches := config.get(CONF_SWITCHES): platform_data = hass.data[DOMAIN].platforms.get(Platform.SWITCH, {}) - async_add_entities_config_entry: AddEntitiesCallback + async_add_entities_config_entry: AddConfigEntryEntitiesCallback device: BroadlinkDevice async_add_entities_config_entry, device = platform_data.get( mac_addr, (None, None) @@ -111,7 +114,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink switch.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/broadlink/time.py b/homeassistant/components/broadlink/time.py index 3dcb045fead..4687df6b8b6 100644 --- a/homeassistant/components/broadlink/time.py +++ b/homeassistant/components/broadlink/time.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.time import TimeEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import BroadlinkDevice @@ -19,7 +19,7 @@ from .entity import BroadlinkEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Broadlink time.""" device = hass.data[DOMAIN].devices[config_entry.entry_id] diff --git a/homeassistant/components/brother/sensor.py b/homeassistant/components/brother/sensor.py index 087a971f928..a09fe8ebc60 100644 --- a/homeassistant/components/brother/sensor.py +++ b/homeassistant/components/brother/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -303,7 +303,7 @@ SENSOR_TYPES: tuple[BrotherSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: BrotherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Brother entities from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/brottsplatskartan/sensor.py b/homeassistant/components/brottsplatskartan/sensor.py index 6725a32bb40..60f9a8163de 100644 --- a/homeassistant/components/brottsplatskartan/sensor.py +++ b/homeassistant/components/brottsplatskartan/sensor.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_APP_ID, CONF_AREA, DOMAIN, LOGGER @@ -21,7 +21,9 @@ SCAN_INTERVAL = timedelta(minutes=30) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Brottsplatskartan sensor entry.""" diff --git a/homeassistant/components/brunt/cover.py b/homeassistant/components/brunt/cover.py index bb97f42bd36..95931d3449e 100644 --- a/homeassistant/components/brunt/cover.py +++ b/homeassistant/components/brunt/cover.py @@ -16,7 +16,7 @@ from homeassistant.components.cover import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -34,7 +34,7 @@ from .coordinator import BruntConfigEntry, BruntCoordinator async def async_setup_entry( hass: HomeAssistant, entry: BruntConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the brunt platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/bryant_evolution/climate.py b/homeassistant/components/bryant_evolution/climate.py index 2d54ced8217..bd053229a1a 100644 --- a/homeassistant/components/bryant_evolution/climate.py +++ b/homeassistant/components/bryant_evolution/climate.py @@ -17,7 +17,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BryantEvolutionConfigEntry, names from .const import CONF_SYSTEM_ZONE, DOMAIN @@ -31,7 +31,7 @@ SCAN_INTERVAL = timedelta(seconds=60) async def async_setup_entry( hass: HomeAssistant, config_entry: BryantEvolutionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" diff --git a/homeassistant/components/bsblan/climate.py b/homeassistant/components/bsblan/climate.py index 2833d6549b4..bef0388a57d 100644 --- a/homeassistant/components/bsblan/climate.py +++ b/homeassistant/components/bsblan/climate.py @@ -19,7 +19,7 @@ from homeassistant.const import ATTR_TEMPERATURE from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers.device_registry import format_mac -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from . import BSBLanConfigEntry, BSBLanData @@ -43,7 +43,7 @@ PRESET_MODES = [ async def async_setup_entry( hass: HomeAssistant, entry: BSBLanConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BSBLAN device based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/bsblan/sensor.py b/homeassistant/components/bsblan/sensor.py index c13b4ad7650..6a6784a4542 100644 --- a/homeassistant/components/bsblan/sensor.py +++ b/homeassistant/components/bsblan/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import BSBLanConfigEntry, BSBLanData @@ -51,7 +51,7 @@ SENSOR_TYPES: tuple[BSBLanSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: BSBLanConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BSB-Lan sensor based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/bsblan/water_heater.py b/homeassistant/components/bsblan/water_heater.py index 318408a9124..a3aee4cdc15 100644 --- a/homeassistant/components/bsblan/water_heater.py +++ b/homeassistant/components/bsblan/water_heater.py @@ -16,7 +16,7 @@ from homeassistant.const import ATTR_TEMPERATURE, STATE_ON from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import format_mac -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BSBLanConfigEntry, BSBLanData from .const import DOMAIN @@ -37,7 +37,7 @@ OPERATION_MODES_REVERSE = {v: k for k, v in OPERATION_MODES.items()} async def async_setup_entry( hass: HomeAssistant, entry: BSBLanConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BSBLAN water heater based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/bthome/binary_sensor.py b/homeassistant/components/bthome/binary_sensor.py index bcc420df4a8..97ed85c1204 100644 --- a/homeassistant/components/bthome/binary_sensor.py +++ b/homeassistant/components/bthome/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothProcessorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import BTHomePassiveBluetoothDataProcessor @@ -169,7 +169,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: BTHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the BTHome BLE binary sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/bthome/event.py b/homeassistant/components/bthome/event.py index a6ee79f4e05..99799819e43 100644 --- a/homeassistant/components/bthome/event.py +++ b/homeassistant/components/bthome/event.py @@ -12,7 +12,7 @@ from homeassistant.components.event import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import format_discovered_event_class, format_event_dispatcher_name from .const import ( @@ -104,7 +104,7 @@ class BTHomeEventEntity(EventEntity): async def async_setup_entry( hass: HomeAssistant, entry: BTHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up BTHome event.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/bthome/sensor.py b/homeassistant/components/bthome/sensor.py index 23a058b0b0c..7025929abd8 100644 --- a/homeassistant/components/bthome/sensor.py +++ b/homeassistant/components/bthome/sensor.py @@ -42,7 +42,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import BTHomePassiveBluetoothDataProcessor @@ -423,7 +423,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: BTHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the BTHome BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/buienradar/camera.py b/homeassistant/components/buienradar/camera.py index 45ff2d6de52..15d08281911 100644 --- a/homeassistant/components/buienradar/camera.py +++ b/homeassistant/components/buienradar/camera.py @@ -13,7 +13,7 @@ from homeassistant.components.camera import Camera from homeassistant.const import CONF_COUNTRY_CODE, CONF_LATITUDE, CONF_LONGITUDE from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import BuienRadarConfigEntry @@ -31,7 +31,7 @@ SUPPORTED_COUNTRY_CODES = ["NL", "BE"] async def async_setup_entry( hass: HomeAssistant, entry: BuienRadarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buienradar radar-loop camera component.""" config = entry.data diff --git a/homeassistant/components/buienradar/sensor.py b/homeassistant/components/buienradar/sensor.py index 712f765237e..f9a110586ba 100644 --- a/homeassistant/components/buienradar/sensor.py +++ b/homeassistant/components/buienradar/sensor.py @@ -45,7 +45,7 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import BuienRadarConfigEntry @@ -691,7 +691,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: BuienRadarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the buienradar sensor.""" config = entry.data diff --git a/homeassistant/components/buienradar/weather.py b/homeassistant/components/buienradar/weather.py index 8b71032bace..4b71024c241 100644 --- a/homeassistant/components/buienradar/weather.py +++ b/homeassistant/components/buienradar/weather.py @@ -51,7 +51,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import BuienRadarConfigEntry from .const import DEFAULT_TIMEFRAME @@ -94,7 +94,7 @@ CONDITION_MAP = { async def async_setup_entry( hass: HomeAssistant, entry: BuienRadarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the buienradar platform.""" config = entry.data diff --git a/homeassistant/components/caldav/calendar.py b/homeassistant/components/caldav/calendar.py index 7a426112d04..be909a02ea5 100644 --- a/homeassistant/components/caldav/calendar.py +++ b/homeassistant/components/caldav/calendar.py @@ -25,7 +25,10 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import async_generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -143,7 +146,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: CalDavConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CalDav calendar platform for a config entry.""" calendars = await async_get_calendars(hass, entry.runtime_data, SUPPORTED_COMPONENT) diff --git a/homeassistant/components/caldav/todo.py b/homeassistant/components/caldav/todo.py index cbd7963b595..fada4693cf0 100644 --- a/homeassistant/components/caldav/todo.py +++ b/homeassistant/components/caldav/todo.py @@ -20,7 +20,7 @@ from homeassistant.components.todo import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import CalDavConfigEntry @@ -46,7 +46,7 @@ TODO_STATUS_MAP_INV: dict[TodoItemStatus, str] = { async def async_setup_entry( hass: HomeAssistant, entry: CalDavConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CalDav todo platform for a config entry.""" calendars = await async_get_calendars(hass, entry.runtime_data, SUPPORTED_COMPONENT) diff --git a/homeassistant/components/cambridge_audio/media_player.py b/homeassistant/components/cambridge_audio/media_player.py index 042178d5781..d18898fa916 100644 --- a/homeassistant/components/cambridge_audio/media_player.py +++ b/homeassistant/components/cambridge_audio/media_player.py @@ -23,7 +23,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import CambridgeAudioConfigEntry, media_browser from .const import ( @@ -65,7 +65,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: CambridgeAudioConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Cambridge Audio device based on a config entry.""" client: StreamMagicClient = entry.runtime_data diff --git a/homeassistant/components/cambridge_audio/select.py b/homeassistant/components/cambridge_audio/select.py index 6bfe83c2539..e7d9136711f 100644 --- a/homeassistant/components/cambridge_audio/select.py +++ b/homeassistant/components/cambridge_audio/select.py @@ -9,7 +9,7 @@ from aiostreammagic.models import DisplayBrightness from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import CambridgeAudioConfigEntry from .entity import CambridgeAudioEntity, command @@ -82,7 +82,7 @@ CONTROL_ENTITIES: tuple[CambridgeAudioSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: CambridgeAudioConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Cambridge Audio select entities based on a config entry.""" diff --git a/homeassistant/components/cambridge_audio/switch.py b/homeassistant/components/cambridge_audio/switch.py index 065a1da4f94..0cebe8266c4 100644 --- a/homeassistant/components/cambridge_audio/switch.py +++ b/homeassistant/components/cambridge_audio/switch.py @@ -9,7 +9,7 @@ from aiostreammagic import StreamMagicClient from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import CambridgeAudioConfigEntry from .entity import CambridgeAudioEntity, command @@ -46,7 +46,7 @@ CONTROL_ENTITIES: tuple[CambridgeAudioSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: CambridgeAudioConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Cambridge Audio switch entities based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/canary/alarm_control_panel.py b/homeassistant/components/canary/alarm_control_panel.py index 443944da8c3..9fe2dfb598d 100644 --- a/homeassistant/components/canary/alarm_control_panel.py +++ b/homeassistant/components/canary/alarm_control_panel.py @@ -13,7 +13,7 @@ from homeassistant.components.alarm_control_panel import ( AlarmControlPanelState, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator @@ -22,7 +22,7 @@ from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: CanaryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Canary alarm control panels based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/canary/camera.py b/homeassistant/components/canary/camera.py index 8f4a01c9968..07645f2f403 100644 --- a/homeassistant/components/canary/camera.py +++ b/homeassistant/components/canary/camera.py @@ -22,7 +22,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -48,7 +48,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: CanaryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Canary sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/canary/sensor.py b/homeassistant/components/canary/sensor.py index 22f3eada2cb..d92166926e9 100644 --- a/homeassistant/components/canary/sensor.py +++ b/homeassistant/components/canary/sensor.py @@ -14,7 +14,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER @@ -64,7 +64,7 @@ STATE_AIR_QUALITY_VERY_ABNORMAL: Final = "very_abnormal" async def async_setup_entry( hass: HomeAssistant, entry: CanaryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Canary sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/cast/media_player.py b/homeassistant/components/cast/media_player.py index 3cc17fae43b..8ff078dfafd 100644 --- a/homeassistant/components/cast/media_player.py +++ b/homeassistant/components/cast/media_player.py @@ -51,7 +51,7 @@ from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.network import NoURLAvailableError, get_url, is_hass_url from homeassistant.util import dt as dt_util from homeassistant.util.logging import async_create_catching_coro @@ -140,7 +140,7 @@ def _async_create_cast_device(hass: HomeAssistant, info: ChromecastInfo): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Cast from a config entry.""" hass.data.setdefault(ADDED_CAST_DEVICES_KEY, set()) diff --git a/homeassistant/components/ccm15/climate.py b/homeassistant/components/ccm15/climate.py index 099b91ec02c..df321395b9e 100644 --- a/homeassistant/components/ccm15/climate.py +++ b/homeassistant/components/ccm15/climate.py @@ -20,7 +20,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONST_CMD_FAN_MAP, CONST_CMD_STATE_MAP, DOMAIN @@ -32,7 +32,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: CCM15ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all climate.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/cert_expiry/sensor.py b/homeassistant/components/cert_expiry/sensor.py index a875e664fdd..3854dfc109e 100644 --- a/homeassistant/components/cert_expiry/sensor.py +++ b/homeassistant/components/cert_expiry/sensor.py @@ -7,7 +7,7 @@ from datetime import datetime from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CertExpiryConfigEntry, CertExpiryDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import CertExpiryEntity async def async_setup_entry( hass: HomeAssistant, entry: CertExpiryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add cert-expiry entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/chacon_dio/cover.py b/homeassistant/components/chacon_dio/cover.py index 3a4955adf5c..ea80116be8a 100644 --- a/homeassistant/components/chacon_dio/cover.py +++ b/homeassistant/components/chacon_dio/cover.py @@ -12,7 +12,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ChaconDioConfigEntry from .entity import ChaconDioEntity @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ChaconDioConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Chacon Dio cover devices.""" data = config_entry.runtime_data diff --git a/homeassistant/components/chacon_dio/switch.py b/homeassistant/components/chacon_dio/switch.py index be178c3c3b5..05b55552615 100644 --- a/homeassistant/components/chacon_dio/switch.py +++ b/homeassistant/components/chacon_dio/switch.py @@ -7,7 +7,7 @@ from dio_chacon_wifi_api.const import DeviceTypeEnum from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ChaconDioConfigEntry from .entity import ChaconDioEntity @@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ChaconDioConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Chacon Dio switch devices.""" data = config_entry.runtime_data diff --git a/homeassistant/components/cloud/binary_sensor.py b/homeassistant/components/cloud/binary_sensor.py index 75cbd3c9f3d..0df13fe4c7b 100644 --- a/homeassistant/components/cloud/binary_sensor.py +++ b/homeassistant/components/cloud/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .client import CloudClient from .const import DATA_CLOUD, DISPATCHER_REMOTE_UPDATE @@ -26,7 +26,7 @@ WAIT_UNTIL_CHANGE = 3 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Assistant Cloud binary sensors.""" cloud = hass.data[DATA_CLOUD] diff --git a/homeassistant/components/cloud/stt.py b/homeassistant/components/cloud/stt.py index b2154448d3a..df377c9a410 100644 --- a/homeassistant/components/cloud/stt.py +++ b/homeassistant/components/cloud/stt.py @@ -22,7 +22,7 @@ from homeassistant.components.stt import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_when_setup from .assist_pipeline import async_migrate_cloud_pipeline_engine @@ -35,7 +35,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Home Assistant Cloud speech platform via config entry.""" stt_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.STT] diff --git a/homeassistant/components/cloud/tts.py b/homeassistant/components/cloud/tts.py index 63f36554c65..3ac3f3d1c2d 100644 --- a/homeassistant/components/cloud/tts.py +++ b/homeassistant/components/cloud/tts.py @@ -23,7 +23,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PLATFORM, Platform from homeassistant.core import HomeAssistant, async_get_hass, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import async_when_setup @@ -256,7 +256,7 @@ async def async_get_engine( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Home Assistant Cloud text-to-speech platform.""" tts_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.TTS] diff --git a/homeassistant/components/co2signal/sensor.py b/homeassistant/components/co2signal/sensor.py index 92f88b8ae82..a8e962532b8 100644 --- a/homeassistant/components/co2signal/sensor.py +++ b/homeassistant/components/co2signal/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTRIBUTION, DOMAIN @@ -54,7 +54,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: CO2SignalConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CO2signal sensor.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/coinbase/__init__.py b/homeassistant/components/coinbase/__init__.py index a29154d9c1b..317759f820d 100644 --- a/homeassistant/components/coinbase/__init__.py +++ b/homeassistant/components/coinbase/__init__.py @@ -140,8 +140,10 @@ def get_accounts(client, version): API_ACCOUNT_ID: account[API_V3_ACCOUNT_ID], API_ACCOUNT_NAME: account[API_ACCOUNT_NAME], API_ACCOUNT_CURRENCY: account[API_ACCOUNT_CURRENCY], - API_ACCOUNT_AMOUNT: account[API_ACCOUNT_AVALIABLE][API_ACCOUNT_VALUE] - + account[API_ACCOUNT_HOLD][API_ACCOUNT_VALUE], + API_ACCOUNT_AMOUNT: ( + float(account[API_ACCOUNT_AVALIABLE][API_ACCOUNT_VALUE]) + + float(account[API_ACCOUNT_HOLD][API_ACCOUNT_VALUE]) + ), ACCOUNT_IS_VAULT: account[API_RESOURCE_TYPE] == API_V3_TYPE_VAULT, } for account in accounts diff --git a/homeassistant/components/coinbase/sensor.py b/homeassistant/components/coinbase/sensor.py index 37509160247..578877e7d90 100644 --- a/homeassistant/components/coinbase/sensor.py +++ b/homeassistant/components/coinbase/sensor.py @@ -7,7 +7,7 @@ import logging from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import CoinbaseConfigEntry, CoinbaseData from .const import ( @@ -45,7 +45,7 @@ ATTRIBUTION = "Data provided by coinbase.com" async def async_setup_entry( hass: HomeAssistant, config_entry: CoinbaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Coinbase sensor platform.""" instance = config_entry.runtime_data diff --git a/homeassistant/components/comelit/alarm_control_panel.py b/homeassistant/components/comelit/alarm_control_panel.py index f694c2b392b..6ea4e97f12e 100644 --- a/homeassistant/components/comelit/alarm_control_panel.py +++ b/homeassistant/components/comelit/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import ( CodeFormat, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ComelitConfigEntry, ComelitVedoSystem @@ -48,7 +48,7 @@ ALARM_AREA_ARMED_STATUS: dict[str, int] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Comelit VEDO system alarm control panel devices.""" diff --git a/homeassistant/components/comelit/binary_sensor.py b/homeassistant/components/comelit/binary_sensor.py index fa51e0b1fda..a895f8dc511 100644 --- a/homeassistant/components/comelit/binary_sensor.py +++ b/homeassistant/components/comelit/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ComelitConfigEntry, ComelitVedoSystem @@ -21,7 +21,7 @@ from .coordinator import ComelitConfigEntry, ComelitVedoSystem async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit VEDO presence sensors.""" diff --git a/homeassistant/components/comelit/climate.py b/homeassistant/components/comelit/climate.py index 1baa777bf99..6906c9bf735 100644 --- a/homeassistant/components/comelit/climate.py +++ b/homeassistant/components/comelit/climate.py @@ -17,7 +17,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ComelitConfigEntry, ComelitSerialBridge @@ -71,7 +71,7 @@ MODE_TO_ACTION: dict[HVACMode, ClimaComelitCommand] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit climates.""" diff --git a/homeassistant/components/comelit/cover.py b/homeassistant/components/comelit/cover.py index abb84824621..64412569f95 100644 --- a/homeassistant/components/comelit/cover.py +++ b/homeassistant/components/comelit/cover.py @@ -9,7 +9,7 @@ from aiocomelit.const import COVER, STATE_COVER, STATE_OFF, STATE_ON from homeassistant.components.cover import CoverDeviceClass, CoverEntity, CoverState from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -19,7 +19,7 @@ from .coordinator import ComelitConfigEntry, ComelitSerialBridge async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit covers.""" diff --git a/homeassistant/components/comelit/humidifier.py b/homeassistant/components/comelit/humidifier.py index d8058074c16..5daf2297782 100644 --- a/homeassistant/components/comelit/humidifier.py +++ b/homeassistant/components/comelit/humidifier.py @@ -18,7 +18,7 @@ from homeassistant.components.humidifier import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -55,7 +55,7 @@ MODE_TO_ACTION: dict[str, HumidifierComelitCommand] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit humidifiers.""" diff --git a/homeassistant/components/comelit/light.py b/homeassistant/components/comelit/light.py index 9736c9ac2a0..45f4146ece6 100644 --- a/homeassistant/components/comelit/light.py +++ b/homeassistant/components/comelit/light.py @@ -9,7 +9,7 @@ from aiocomelit.const import LIGHT, STATE_OFF, STATE_ON from homeassistant.components.light import ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ComelitConfigEntry, ComelitSerialBridge @@ -18,7 +18,7 @@ from .coordinator import ComelitConfigEntry, ComelitSerialBridge async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit lights.""" diff --git a/homeassistant/components/comelit/sensor.py b/homeassistant/components/comelit/sensor.py index efb2418244e..9200d99262f 100644 --- a/homeassistant/components/comelit/sensor.py +++ b/homeassistant/components/comelit/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CONF_TYPE, UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -42,7 +42,7 @@ SENSOR_VEDO_TYPES: Final = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit sensors.""" @@ -55,7 +55,7 @@ async def async_setup_entry( async def async_setup_bridge_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit Bridge sensors.""" @@ -75,7 +75,7 @@ async def async_setup_bridge_entry( async def async_setup_vedo_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit VEDO sensors.""" diff --git a/homeassistant/components/comelit/switch.py b/homeassistant/components/comelit/switch.py index 26d3b81ebde..e89ee74c1be 100644 --- a/homeassistant/components/comelit/switch.py +++ b/homeassistant/components/comelit/switch.py @@ -9,7 +9,7 @@ from aiocomelit.const import IRRIGATION, OTHER, STATE_OFF, STATE_ON from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import ComelitConfigEntry, ComelitSerialBridge @@ -18,7 +18,7 @@ from .coordinator import ComelitConfigEntry, ComelitSerialBridge async def async_setup_entry( hass: HomeAssistant, config_entry: ComelitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Comelit switches.""" diff --git a/homeassistant/components/config/config_entries.py b/homeassistant/components/config/config_entries.py index 52e3346002e..74c9b5a9d0c 100644 --- a/homeassistant/components/config/config_entries.py +++ b/homeassistant/components/config/config_entries.py @@ -46,6 +46,13 @@ def async_setup(hass: HomeAssistant) -> bool: hass.http.register_view(OptionManagerFlowIndexView(hass.config_entries.options)) hass.http.register_view(OptionManagerFlowResourceView(hass.config_entries.options)) + hass.http.register_view( + SubentryManagerFlowIndexView(hass.config_entries.subentries) + ) + hass.http.register_view( + SubentryManagerFlowResourceView(hass.config_entries.subentries) + ) + websocket_api.async_register_command(hass, config_entries_get) websocket_api.async_register_command(hass, config_entry_disable) websocket_api.async_register_command(hass, config_entry_get_single) @@ -54,6 +61,9 @@ def async_setup(hass: HomeAssistant) -> bool: websocket_api.async_register_command(hass, config_entries_progress) websocket_api.async_register_command(hass, ignore_config_flow) + websocket_api.async_register_command(hass, config_subentry_delete) + websocket_api.async_register_command(hass, config_subentry_list) + return True @@ -285,6 +295,66 @@ class OptionManagerFlowResourceView( return await super().post(request, flow_id) +class SubentryManagerFlowIndexView( + FlowManagerIndexView[config_entries.ConfigSubentryFlowManager] +): + """View to create subentry flows.""" + + url = "/api/config/config_entries/subentries/flow" + name = "api:config:config_entries:subentries:flow" + + @require_admin( + error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT) + ) + @RequestDataValidator( + vol.Schema( + { + vol.Required("handler"): vol.All(vol.Coerce(tuple), (str, str)), + vol.Optional("show_advanced_options", default=False): cv.boolean, + }, + extra=vol.ALLOW_EXTRA, + ) + ) + async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: + """Handle a POST request. + + handler in request is [entry_id, subentry_type]. + """ + return await super()._post_impl(request, data) + + def get_context(self, data: dict[str, Any]) -> dict[str, Any]: + """Return context.""" + context = super().get_context(data) + context["source"] = config_entries.SOURCE_USER + if subentry_id := data.get("subentry_id"): + context["source"] = config_entries.SOURCE_RECONFIGURE + context["subentry_id"] = subentry_id + return context + + +class SubentryManagerFlowResourceView( + FlowManagerResourceView[config_entries.ConfigSubentryFlowManager] +): + """View to interact with the subentry flow manager.""" + + url = "/api/config/config_entries/subentries/flow/{flow_id}" + name = "api:config:config_entries:subentries:flow:resource" + + @require_admin( + error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT) + ) + async def get(self, request: web.Request, /, flow_id: str) -> web.Response: + """Get the current state of a data_entry_flow.""" + return await super().get(request, flow_id) + + @require_admin( + error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT) + ) + async def post(self, request: web.Request, flow_id: str) -> web.Response: + """Handle a POST request.""" + return await super().post(request, flow_id) + + @websocket_api.require_admin @websocket_api.websocket_command({"type": "config_entries/flow/progress"}) def config_entries_progress( @@ -589,3 +659,63 @@ async def _async_matching_config_entries_json_fragments( ) or (filter_is_not_helper and entry.domain not in integrations) ] + + +@websocket_api.require_admin +@websocket_api.websocket_command( + { + "type": "config_entries/subentries/list", + "entry_id": str, + } +) +@websocket_api.async_response +async def config_subentry_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: dict[str, Any], +) -> None: + """List subentries of a config entry.""" + entry = get_entry(hass, connection, msg["entry_id"], msg["id"]) + if entry is None: + return + + result = [ + { + "subentry_id": subentry.subentry_id, + "subentry_type": subentry.subentry_type, + "title": subentry.title, + "unique_id": subentry.unique_id, + } + for subentry in entry.subentries.values() + ] + connection.send_result(msg["id"], result) + + +@websocket_api.require_admin +@websocket_api.websocket_command( + { + "type": "config_entries/subentries/delete", + "entry_id": str, + "subentry_id": str, + } +) +@websocket_api.async_response +async def config_subentry_delete( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: dict[str, Any], +) -> None: + """Delete a subentry of a config entry.""" + entry = get_entry(hass, connection, msg["entry_id"], msg["id"]) + if entry is None: + return + + try: + hass.config_entries.async_remove_subentry(entry, msg["subentry_id"]) + except config_entries.UnknownSubEntry: + connection.send_error( + msg["id"], websocket_api.const.ERR_NOT_FOUND, "Config subentry not found" + ) + return + + connection.send_result(msg["id"]) diff --git a/homeassistant/components/control4/light.py b/homeassistant/components/control4/light.py index cedfbeb49c3..d2d0f85f476 100644 --- a/homeassistant/components/control4/light.py +++ b/homeassistant/components/control4/light.py @@ -18,7 +18,7 @@ from homeassistant.components.light import ( LightEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from . import Control4ConfigEntry, Control4RuntimeData, get_items_of_category @@ -36,7 +36,7 @@ CONTROL4_DIMMER_VARS = ["LIGHT_LEVEL", "Brightness Percent"] async def async_setup_entry( hass: HomeAssistant, entry: Control4ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Control4 lights from a config entry.""" runtime_data = entry.runtime_data diff --git a/homeassistant/components/control4/media_player.py b/homeassistant/components/control4/media_player.py index bd8e3fb38fe..824ce431aea 100644 --- a/homeassistant/components/control4/media_player.py +++ b/homeassistant/components/control4/media_player.py @@ -19,7 +19,7 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from . import Control4ConfigEntry, Control4RuntimeData @@ -77,7 +77,7 @@ async def get_rooms(hass: HomeAssistant, entry: Control4ConfigEntry): async def async_setup_entry( hass: HomeAssistant, entry: Control4ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Control4 rooms from a config entry.""" runtime_data = entry.runtime_data diff --git a/homeassistant/components/conversation/__init__.py b/homeassistant/components/conversation/__init__.py index 69e738205c5..11de75801ba 100644 --- a/homeassistant/components/conversation/__init__.py +++ b/homeassistant/components/conversation/__init__.py @@ -32,6 +32,7 @@ from .agent_manager import ( ) from .chat_log import ( AssistantContent, + AssistantContentDeltaDict, ChatLog, Content, ConverseError, @@ -65,6 +66,7 @@ __all__ = [ "HOME_ASSISTANT_AGENT", "OLD_HOME_ASSISTANT_AGENT", "AssistantContent", + "AssistantContentDeltaDict", "ChatLog", "Content", "ConversationEntity", diff --git a/homeassistant/components/conversation/chat_log.py b/homeassistant/components/conversation/chat_log.py index e4ff1904e7c..1ee5e9965ab 100644 --- a/homeassistant/components/conversation/chat_log.py +++ b/homeassistant/components/conversation/chat_log.py @@ -3,11 +3,12 @@ from __future__ import annotations import asyncio -from collections.abc import AsyncGenerator, Generator +from collections.abc import AsyncGenerator, AsyncIterable, Callable, Generator from contextlib import contextmanager from contextvars import ContextVar -from dataclasses import dataclass, field, replace +from dataclasses import asdict, dataclass, field, replace import logging +from typing import Literal, TypedDict import voluptuous as vol @@ -35,27 +36,38 @@ def async_get_chat_log( hass: HomeAssistant, session: chat_session.ChatSession, user_input: ConversationInput | None = None, + *, + chat_log_delta_listener: Callable[[ChatLog, dict], None] | None = None, ) -> Generator[ChatLog]: """Return chat log for a specific chat session.""" - if chat_log := current_chat_log.get(): - # If a chat log is already active and it's the requested conversation ID, - # return that. We won't update the last updated time in this case. - if chat_log.conversation_id == session.conversation_id: - yield chat_log - return + # If a chat log is already active and it's the requested conversation ID, + # return that. We won't update the last updated time in this case. + if ( + chat_log := current_chat_log.get() + ) and chat_log.conversation_id == session.conversation_id: + if chat_log_delta_listener is not None: + raise RuntimeError( + "Cannot attach chat log delta listener unless initial caller" + ) + if user_input is not None: + chat_log.async_add_user_content(UserContent(content=user_input.text)) + + yield chat_log + return all_chat_logs = hass.data.get(DATA_CHAT_LOGS) if all_chat_logs is None: all_chat_logs = {} hass.data[DATA_CHAT_LOGS] = all_chat_logs - chat_log = all_chat_logs.get(session.conversation_id) - - if chat_log: + if chat_log := all_chat_logs.get(session.conversation_id): chat_log = replace(chat_log, content=chat_log.content.copy()) else: chat_log = ChatLog(hass, session.conversation_id) + if chat_log_delta_listener: + chat_log.delta_listener = chat_log_delta_listener + if user_input is not None: chat_log.async_add_user_content(UserContent(content=user_input.text)) @@ -80,6 +92,9 @@ def async_get_chat_log( session.async_on_cleanup(do_cleanup) + if chat_log_delta_listener: + chat_log.delta_listener = None + all_chat_logs[session.conversation_id] = chat_log @@ -142,7 +157,15 @@ class ToolResultContent: tool_result: JsonObjectType -Content = SystemContent | UserContent | AssistantContent | ToolResultContent +type Content = SystemContent | UserContent | AssistantContent | ToolResultContent + + +class AssistantContentDeltaDict(TypedDict, total=False): + """Partial content to define an AssistantContent.""" + + role: Literal["assistant"] + content: str | None + tool_calls: list[llm.ToolInput] | None @dataclass @@ -154,6 +177,12 @@ class ChatLog: content: list[Content] = field(default_factory=lambda: [SystemContent(content="")]) extra_system_prompt: str | None = None llm_api: llm.APIInstance | None = None + delta_listener: Callable[[ChatLog, dict], None] | None = None + + @property + def unresponded_tool_results(self) -> bool: + """Return if there are unresponded tool results.""" + return self.content[-1].role == "tool_result" @callback def async_add_user_content(self, content: UserContent) -> None: @@ -223,6 +252,86 @@ class ChatLog: self.content.append(response_content) yield response_content + async def async_add_delta_content_stream( + self, agent_id: str, stream: AsyncIterable[AssistantContentDeltaDict] + ) -> AsyncGenerator[AssistantContent | ToolResultContent]: + """Stream content into the chat log. + + Returns a generator with all content that was added to the chat log. + + stream iterates over dictionaries with optional keys role, content and tool_calls. + + When a delta contains a role key, the current message is considered complete and + a new message is started. + + The keys content and tool_calls will be concatenated if they appear multiple times. + """ + current_content = "" + current_tool_calls: list[llm.ToolInput] = [] + tool_call_tasks: dict[str, asyncio.Task] = {} + + async for delta in stream: + LOGGER.debug("Received delta: %s", delta) + + # Indicates update to current message + if "role" not in delta: + if delta_content := delta.get("content"): + current_content += delta_content + if delta_tool_calls := delta.get("tool_calls"): + if self.llm_api is None: + raise ValueError("No LLM API configured") + current_tool_calls += delta_tool_calls + + # Start processing the tool calls as soon as we know about them + for tool_call in delta_tool_calls: + tool_call_tasks[tool_call.id] = self.hass.async_create_task( + self.llm_api.async_call_tool(tool_call), + name=f"llm_tool_{tool_call.id}", + ) + if self.delta_listener: + self.delta_listener(self, delta) # type: ignore[arg-type] + continue + + # Starting a new message + + if delta["role"] != "assistant": + raise ValueError(f"Only assistant role expected. Got {delta['role']}") + + # Yield the previous message if it has content + if current_content or current_tool_calls: + content = AssistantContent( + agent_id=agent_id, + content=current_content or None, + tool_calls=current_tool_calls or None, + ) + yield content + async for tool_result in self.async_add_assistant_content( + content, tool_call_tasks=tool_call_tasks + ): + yield tool_result + if self.delta_listener: + self.delta_listener(self, asdict(tool_result)) + + current_content = delta.get("content") or "" + current_tool_calls = delta.get("tool_calls") or [] + + if self.delta_listener: + self.delta_listener(self, delta) # type: ignore[arg-type] + + if current_content or current_tool_calls: + content = AssistantContent( + agent_id=agent_id, + content=current_content or None, + tool_calls=current_tool_calls or None, + ) + yield content + async for tool_result in self.async_add_assistant_content( + content, tool_call_tasks=tool_call_tasks + ): + yield tool_result + if self.delta_listener: + self.delta_listener(self, asdict(tool_result)) + async def async_update_llm_data( self, conversing_domain: str, @@ -310,12 +419,10 @@ class ChatLog: if llm_api: prompt_parts.append(llm_api.api_prompt) - extra_system_prompt = ( + if extra_system_prompt := ( # Take new system prompt if one was given user_input.extra_system_prompt or self.extra_system_prompt - ) - - if extra_system_prompt: + ): prompt_parts.append(extra_system_prompt) prompt = "\n".join(prompt_parts) diff --git a/homeassistant/components/cookidoo/button.py b/homeassistant/components/cookidoo/button.py index b292a7309ba..97136deb031 100644 --- a/homeassistant/components/cookidoo/button.py +++ b/homeassistant/components/cookidoo/button.py @@ -8,7 +8,7 @@ from cookidoo_api import Cookidoo, CookidooException from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CookidooConfigEntry, CookidooDataUpdateCoordinator @@ -35,7 +35,7 @@ TODO_CLEAR = CookidooButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: CookidooConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Cookidoo button entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/cookidoo/sensor.py b/homeassistant/components/cookidoo/sensor.py index 7fbacea18bc..6df41383a75 100644 --- a/homeassistant/components/cookidoo/sensor.py +++ b/homeassistant/components/cookidoo/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -73,7 +73,7 @@ SENSOR_DESCRIPTIONS: tuple[CookidooSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: CookidooConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/cookidoo/todo.py b/homeassistant/components/cookidoo/todo.py index 3d5264f4e01..c577b845657 100644 --- a/homeassistant/components/cookidoo/todo.py +++ b/homeassistant/components/cookidoo/todo.py @@ -18,7 +18,7 @@ from homeassistant.components.todo import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CookidooConfigEntry, CookidooDataUpdateCoordinator @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: CookidooConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the todo list from a config entry created in the integrations UI.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/coolmaster/binary_sensor.py b/homeassistant/components/coolmaster/binary_sensor.py index ab2718b9352..5c1f19fd14c 100644 --- a/homeassistant/components/coolmaster/binary_sensor.py +++ b/homeassistant/components/coolmaster/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import CoolmasterConfigEntry from .entity import CoolmasterEntity @@ -18,7 +18,7 @@ from .entity import CoolmasterEntity async def async_setup_entry( hass: HomeAssistant, config_entry: CoolmasterConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CoolMasterNet binary_sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/coolmaster/button.py b/homeassistant/components/coolmaster/button.py index 5463566d1ef..7cc8fc56c80 100644 --- a/homeassistant/components/coolmaster/button.py +++ b/homeassistant/components/coolmaster/button.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import CoolmasterConfigEntry from .entity import CoolmasterEntity @@ -14,7 +14,7 @@ from .entity import CoolmasterEntity async def async_setup_entry( hass: HomeAssistant, config_entry: CoolmasterConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CoolMasterNet button platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/coolmaster/climate.py b/homeassistant/components/coolmaster/climate.py index cd1659e1666..52fdfaaca3f 100644 --- a/homeassistant/components/coolmaster/climate.py +++ b/homeassistant/components/coolmaster/climate.py @@ -15,7 +15,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_SUPPORTED_MODES from .coordinator import CoolmasterConfigEntry, CoolmasterDataUpdateCoordinator @@ -39,7 +39,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: CoolmasterConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CoolMasterNet climate platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/coolmaster/sensor.py b/homeassistant/components/coolmaster/sensor.py index 2b835565bae..32dceb83c5f 100644 --- a/homeassistant/components/coolmaster/sensor.py +++ b/homeassistant/components/coolmaster/sensor.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import CoolmasterConfigEntry from .entity import CoolmasterEntity @@ -14,7 +14,7 @@ from .entity import CoolmasterEntity async def async_setup_entry( hass: HomeAssistant, config_entry: CoolmasterConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the CoolMasterNet sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/cpuspeed/sensor.py b/homeassistant/components/cpuspeed/sensor.py index 6a14f7ad13f..11f683b1434 100644 --- a/homeassistant/components/cpuspeed/sensor.py +++ b/homeassistant/components/cpuspeed/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfFrequency from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -24,7 +24,7 @@ HZ_ADVERTISED = "hz_advertised" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config_entry.""" async_add_entities([CPUSpeedSensor(entry)], True) diff --git a/homeassistant/components/crownstone/light.py b/homeassistant/components/crownstone/light.py index 70b7631fe6b..dc29ad93072 100644 --- a/homeassistant/components/crownstone/light.py +++ b/homeassistant/components/crownstone/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CROWNSTONE_INCLUDE_TYPES, @@ -30,7 +30,7 @@ from .helpers import map_from_to async def async_setup_entry( hass: HomeAssistant, config_entry: CrownstoneConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up crownstones from a config entry.""" manager = config_entry.runtime_data diff --git a/homeassistant/components/daikin/climate.py b/homeassistant/components/daikin/climate.py index 06ee0a03860..648a65c0d30 100644 --- a/homeassistant/components/daikin/climate.py +++ b/homeassistant/components/daikin/climate.py @@ -21,7 +21,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_INSIDE_TEMPERATURE, @@ -83,7 +83,7 @@ DAIKIN_ATTR_ADVANCED = "adv" async def async_setup_entry( hass: HomeAssistant, entry: DaikinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Daikin climate based on config_entry.""" daikin_api = entry.runtime_data diff --git a/homeassistant/components/daikin/sensor.py b/homeassistant/components/daikin/sensor.py index 982aac1f3f2..c1aa28fbe67 100644 --- a/homeassistant/components/daikin/sensor.py +++ b/homeassistant/components/daikin/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_COMPRESSOR_FREQUENCY, @@ -134,7 +134,7 @@ SENSOR_TYPES: tuple[DaikinSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: DaikinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Daikin climate based on config_entry.""" daikin_api = entry.runtime_data diff --git a/homeassistant/components/daikin/switch.py b/homeassistant/components/daikin/switch.py index 8a3a15d367f..20a56ac321c 100644 --- a/homeassistant/components/daikin/switch.py +++ b/homeassistant/components/daikin/switch.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DaikinConfigEntry, DaikinCoordinator from .entity import DaikinEntity @@ -19,7 +19,7 @@ DAIKIN_ATTR_MODE = "mode" async def async_setup_entry( hass: HomeAssistant, entry: DaikinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Daikin climate based on config_entry.""" daikin_api = entry.runtime_data diff --git a/homeassistant/components/deako/light.py b/homeassistant/components/deako/light.py index 75b01935c9a..12f42c36f29 100644 --- a/homeassistant/components/deako/light.py +++ b/homeassistant/components/deako/light.py @@ -7,7 +7,7 @@ from pydeako import Deako from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeakoConfigEntry from .const import DOMAIN @@ -20,7 +20,7 @@ MODEL_DIMMER = "dimmer" async def async_setup_entry( hass: HomeAssistant, config: DeakoConfigEntry, - add_entities: AddEntitiesCallback, + add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure the platform.""" client = config.runtime_data diff --git a/homeassistant/components/deconz/alarm_control_panel.py b/homeassistant/components/deconz/alarm_control_panel.py index 94f4cd1ddd6..85ca32d76e6 100644 --- a/homeassistant/components/deconz/alarm_control_panel.py +++ b/homeassistant/components/deconz/alarm_control_panel.py @@ -17,7 +17,7 @@ from homeassistant.components.alarm_control_panel import ( CodeFormat, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -48,7 +48,7 @@ def get_alarm_system_id_for_unique_id(hub: DeconzHub, unique_id: str) -> str | N async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ alarm control panel devices.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index e3b0fc2f2c0..fcbb61a4e4f 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -25,7 +25,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import ATTR_TEMPERATURE, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .const import ATTR_DARK, ATTR_ON @@ -161,7 +161,7 @@ ENTITY_DESCRIPTIONS: tuple[DeconzBinarySensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ binary sensor.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/button.py b/homeassistant/components/deconz/button.py index 9fea1d02ab8..1d96f9867a7 100644 --- a/homeassistant/components/deconz/button.py +++ b/homeassistant/components/deconz/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice, DeconzSceneMixin @@ -47,7 +47,7 @@ ENTITY_DESCRIPTIONS = { async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ button entity.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index aa274e6c0c1..26597c195e7 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -30,7 +30,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .const import ATTR_LOCKED, ATTR_OFFSET, ATTR_VALVE @@ -77,7 +77,7 @@ DECONZ_TO_PRESET_MODE = {value: key for key, value in PRESET_MODE_TO_DECONZ.item async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ climate devices.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/cover.py b/homeassistant/components/deconz/cover.py index 6dee00248ff..d68e0fec09c 100644 --- a/homeassistant/components/deconz/cover.py +++ b/homeassistant/components/deconz/cover.py @@ -18,7 +18,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -34,7 +34,7 @@ DECONZ_TYPE_TO_DEVICE_CLASS = { async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up covers for deCONZ component.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/fan.py b/homeassistant/components/deconz/fan.py index aec078f771f..324ada807e0 100644 --- a/homeassistant/components/deconz/fan.py +++ b/homeassistant/components/deconz/fan.py @@ -13,7 +13,7 @@ from homeassistant.components.fan import ( FanEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -34,7 +34,7 @@ ORDERED_NAMED_FAN_SPEEDS: list[LightFanSpeed] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up fans for deCONZ component.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/light.py b/homeassistant/components/deconz/light.py index 72ba7035c8e..b61a1d39333 100644 --- a/homeassistant/components/deconz/light.py +++ b/homeassistant/components/deconz/light.py @@ -30,7 +30,7 @@ from homeassistant.components.light import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.color import ( color_hs_to_xy, color_temperature_kelvin_to_mired, @@ -142,7 +142,7 @@ def update_color_state( async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ lights and groups from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/lock.py b/homeassistant/components/deconz/lock.py index e5e2faf1d57..77b9ea435c7 100644 --- a/homeassistant/components/deconz/lock.py +++ b/homeassistant/components/deconz/lock.py @@ -10,7 +10,7 @@ from pydeconz.models.sensor.door_lock import DoorLock from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN, LockEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -19,7 +19,7 @@ from .entity import DeconzDevice async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up locks for deCONZ component.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/number.py b/homeassistant/components/deconz/number.py index 9de86c1c79b..d5ba8cc28d5 100644 --- a/homeassistant/components/deconz/number.py +++ b/homeassistant/components/deconz/number.py @@ -19,7 +19,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -70,7 +70,7 @@ ENTITY_DESCRIPTIONS: tuple[DeconzNumberDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ number entity.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/scene.py b/homeassistant/components/deconz/scene.py index 3f29b12b05f..0aff2b3ca8c 100644 --- a/homeassistant/components/deconz/scene.py +++ b/homeassistant/components/deconz/scene.py @@ -8,7 +8,7 @@ from pydeconz.models.event import EventType from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN, Scene from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzSceneMixin @@ -17,7 +17,7 @@ from .entity import DeconzSceneMixin async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up scenes for deCONZ integration.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/select.py b/homeassistant/components/deconz/select.py index a3109a278fc..4d92b465cdc 100644 --- a/homeassistant/components/deconz/select.py +++ b/homeassistant/components/deconz/select.py @@ -14,7 +14,7 @@ from pydeconz.models.sensor.presence import ( from homeassistant.components.select import DOMAIN as SELECT_DOMAIN, SelectEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -30,7 +30,7 @@ DECONZ_TO_SENSITIVITY = {value: key for key, value in SENSITIVITY_TO_DECONZ.item async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ button entity.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 3003fb1008d..d318db6e2bf 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -50,7 +50,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -332,7 +332,7 @@ ENTITY_DESCRIPTIONS: tuple[DeconzSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the deCONZ sensors.""" hub = config_entry.runtime_data @@ -468,7 +468,7 @@ class DeconzBatteryTracker: sensor_id: str, hub: DeconzHub, description: DeconzSensorDescription, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tracker.""" self.sensor = hub.api.sensors[sensor_id] diff --git a/homeassistant/components/deconz/siren.py b/homeassistant/components/deconz/siren.py index 28b606e30ba..4c15cf8ccfe 100644 --- a/homeassistant/components/deconz/siren.py +++ b/homeassistant/components/deconz/siren.py @@ -14,7 +14,7 @@ from homeassistant.components.siren import ( SirenEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .entity import DeconzDevice @@ -23,7 +23,7 @@ from .entity import DeconzDevice async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sirens for deCONZ component.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/deconz/switch.py b/homeassistant/components/deconz/switch.py index cd28871e35b..49904642804 100644 --- a/homeassistant/components/deconz/switch.py +++ b/homeassistant/components/deconz/switch.py @@ -9,7 +9,7 @@ from pydeconz.models.light.light import Light from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeconzConfigEntry from .const import POWER_PLUGS @@ -19,7 +19,7 @@ from .entity import DeconzDevice async def async_setup_entry( hass: HomeAssistant, config_entry: DeconzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for deCONZ component. diff --git a/homeassistant/components/deluge/sensor.py b/homeassistant/components/deluge/sensor.py index 24d5ce9ec61..d6809967703 100644 --- a/homeassistant/components/deluge/sensor.py +++ b/homeassistant/components/deluge/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import STATE_IDLE, Platform, UnitOfDataRate from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DelugeGetSessionStatusKeys, DelugeSensorType @@ -116,7 +116,7 @@ SENSOR_TYPES: tuple[DelugeSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: DelugeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Deluge sensor.""" async_add_entities( diff --git a/homeassistant/components/deluge/switch.py b/homeassistant/components/deluge/switch.py index 1ec0cd7a7df..342442ee727 100644 --- a/homeassistant/components/deluge/switch.py +++ b/homeassistant/components/deluge/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DelugeConfigEntry, DelugeDataUpdateCoordinator from .entity import DelugeEntity @@ -16,7 +16,7 @@ from .entity import DelugeEntity async def async_setup_entry( hass: HomeAssistant, entry: DelugeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Deluge switch.""" async_add_entities([DelugeSwitch(entry.runtime_data)]) diff --git a/homeassistant/components/demo/air_quality.py b/homeassistant/components/demo/air_quality.py index 551f2c8e88a..4e247812efe 100644 --- a/homeassistant/components/demo/air_quality.py +++ b/homeassistant/components/demo/air_quality.py @@ -5,13 +5,13 @@ from __future__ import annotations from homeassistant.components.air_quality import AirQualityEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/alarm_control_panel.py b/homeassistant/components/demo/alarm_control_panel.py index d34830042d7..64474b4beb6 100644 --- a/homeassistant/components/demo/alarm_control_panel.py +++ b/homeassistant/components/demo/alarm_control_panel.py @@ -9,13 +9,13 @@ from homeassistant.components.manual.alarm_control_panel import ManualAlarm from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ARMING_TIME, CONF_DELAY_TIME, CONF_TRIGGER_TIME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/binary_sensor.py b/homeassistant/components/demo/binary_sensor.py index bc1d7b9daf2..b210e726205 100644 --- a/homeassistant/components/demo/binary_sensor.py +++ b/homeassistant/components/demo/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -17,7 +17,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo binary sensor platform.""" async_add_entities( diff --git a/homeassistant/components/demo/button.py b/homeassistant/components/demo/button.py index a3b8dd9ff0c..25212f38989 100644 --- a/homeassistant/components/demo/button.py +++ b/homeassistant/components/demo/button.py @@ -7,7 +7,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -15,7 +15,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo button platform.""" async_add_entities( diff --git a/homeassistant/components/demo/calendar.py b/homeassistant/components/demo/calendar.py index 4e2fa7b3460..b0e82acfa61 100644 --- a/homeassistant/components/demo/calendar.py +++ b/homeassistant/components/demo/calendar.py @@ -7,14 +7,14 @@ import datetime from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo Calendar config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/camera.py b/homeassistant/components/demo/camera.py index 9fae6468207..69ba7efda01 100644 --- a/homeassistant/components/demo/camera.py +++ b/homeassistant/components/demo/camera.py @@ -7,13 +7,13 @@ from pathlib import Path from homeassistant.components.camera import Camera, CameraEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/climate.py b/homeassistant/components/demo/climate.py index d5b763caa5a..f68714695f3 100644 --- a/homeassistant/components/demo/climate.py +++ b/homeassistant/components/demo/climate.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -27,7 +27,7 @@ SUPPORT_FLAGS = ClimateEntityFeature(0) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo climate platform.""" async_add_entities( diff --git a/homeassistant/components/demo/cover.py b/homeassistant/components/demo/cover.py index adddb6a3a7d..ed13f24cfd7 100644 --- a/homeassistant/components/demo/cover.py +++ b/homeassistant/components/demo/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_utc_time_change from . import DOMAIN @@ -24,7 +24,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo cover platform.""" async_add_entities( diff --git a/homeassistant/components/demo/date.py b/homeassistant/components/demo/date.py index b67c4248123..875075a381d 100644 --- a/homeassistant/components/demo/date.py +++ b/homeassistant/components/demo/date.py @@ -8,7 +8,7 @@ from homeassistant.components.date import DateEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -16,7 +16,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo date platform.""" async_add_entities( diff --git a/homeassistant/components/demo/datetime.py b/homeassistant/components/demo/datetime.py index 920bc14cdc5..353ed8311bb 100644 --- a/homeassistant/components/demo/datetime.py +++ b/homeassistant/components/demo/datetime.py @@ -8,7 +8,7 @@ from homeassistant.components.datetime import DateTimeEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -16,7 +16,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo datetime platform.""" async_add_entities( diff --git a/homeassistant/components/demo/event.py b/homeassistant/components/demo/event.py index c58b5f5fc2e..f593a833123 100644 --- a/homeassistant/components/demo/event.py +++ b/homeassistant/components/demo/event.py @@ -6,7 +6,7 @@ from homeassistant.components.event import EventDeviceClass, EventEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -14,7 +14,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo event platform.""" async_add_entities([DemoEvent()]) diff --git a/homeassistant/components/demo/fan.py b/homeassistant/components/demo/fan.py index 42e7f9e2434..9f48628688e 100644 --- a/homeassistant/components/demo/fan.py +++ b/homeassistant/components/demo/fan.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback PRESET_MODE_AUTO = "auto" PRESET_MODE_SMART = "smart" @@ -29,7 +29,7 @@ LIMITED_SUPPORT = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/humidifier.py b/homeassistant/components/demo/humidifier.py index 7245d96eaf0..2bdbd22eef8 100644 --- a/homeassistant/components/demo/humidifier.py +++ b/homeassistant/components/demo/humidifier.py @@ -12,7 +12,7 @@ from homeassistant.components.humidifier import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback SUPPORT_FLAGS = HumidifierEntityFeature(0) @@ -20,7 +20,7 @@ SUPPORT_FLAGS = HumidifierEntityFeature(0) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo humidifier devices config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/light.py b/homeassistant/components/demo/light.py index ec98a056b3e..c00f2b42828 100644 --- a/homeassistant/components/demo/light.py +++ b/homeassistant/components/demo/light.py @@ -22,7 +22,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -39,7 +39,7 @@ SUPPORT_DEMO_HS_WHITE = {ColorMode.HS, ColorMode.WHITE} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo light platform.""" async_add_entities( diff --git a/homeassistant/components/demo/lock.py b/homeassistant/components/demo/lock.py index 1f25445af7f..081e1cf1d53 100644 --- a/homeassistant/components/demo/lock.py +++ b/homeassistant/components/demo/lock.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.lock import LockEntity, LockEntityFeature, LockState from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback LOCK_UNLOCK_DELAY = 2 # Used to give a realistic lock/unlock experience in frontend @@ -16,7 +16,7 @@ LOCK_UNLOCK_DELAY = 2 # Used to give a realistic lock/unlock experience in fron async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/media_player.py b/homeassistant/components/demo/media_player.py index fa3c3e3b2fc..de2a2cb3937 100644 --- a/homeassistant/components/demo/media_player.py +++ b/homeassistant/components/demo/media_player.py @@ -15,14 +15,14 @@ from homeassistant.components.media_player import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/notify.py b/homeassistant/components/demo/notify.py index 7524517e6e8..d26e13cc541 100644 --- a/homeassistant/components/demo/notify.py +++ b/homeassistant/components/demo/notify.py @@ -10,7 +10,7 @@ from homeassistant.components.notify import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback EVENT_NOTIFY = "notify" @@ -18,7 +18,7 @@ EVENT_NOTIFY = "notify" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo entity platform.""" async_add_entities([DemoNotifyEntity(unique_id="notify", device_name="Notifier")]) diff --git a/homeassistant/components/demo/number.py b/homeassistant/components/demo/number.py index 8c3f5ec3477..c7b62bdc3e0 100644 --- a/homeassistant/components/demo/number.py +++ b/homeassistant/components/demo/number.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -15,7 +15,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo number platform.""" async_add_entities( diff --git a/homeassistant/components/demo/remote.py b/homeassistant/components/demo/remote.py index 774f375dd27..ffd6fd6e609 100644 --- a/homeassistant/components/demo/remote.py +++ b/homeassistant/components/demo/remote.py @@ -9,13 +9,13 @@ from homeassistant.components.remote import RemoteEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/select.py b/homeassistant/components/demo/select.py index ff664a31d2f..fce90bc9b4f 100644 --- a/homeassistant/components/demo/select.py +++ b/homeassistant/components/demo/select.py @@ -6,7 +6,7 @@ from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -14,7 +14,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo select platform.""" async_add_entities( diff --git a/homeassistant/components/demo/sensor.py b/homeassistant/components/demo/sensor.py index 0c61faae00e..ae9ff26eca9 100644 --- a/homeassistant/components/demo/sensor.py +++ b/homeassistant/components/demo/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from . import DOMAIN @@ -33,7 +33,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo sensor platform.""" async_add_entities( diff --git a/homeassistant/components/demo/siren.py b/homeassistant/components/demo/siren.py index 235d98f5875..ddaa5101e0f 100644 --- a/homeassistant/components/demo/siren.py +++ b/homeassistant/components/demo/siren.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.siren import SirenEntity, SirenEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback SUPPORT_FLAGS = SirenEntityFeature.TURN_OFF | SirenEntityFeature.TURN_ON @@ -15,7 +15,7 @@ SUPPORT_FLAGS = SirenEntityFeature.TURN_OFF | SirenEntityFeature.TURN_ON async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo siren devices config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/stt.py b/homeassistant/components/demo/stt.py index 95eebe44588..1757e4a8b88 100644 --- a/homeassistant/components/demo/stt.py +++ b/homeassistant/components/demo/stt.py @@ -17,7 +17,7 @@ from homeassistant.components.stt import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback SUPPORT_LANGUAGES = ["en", "de"] @@ -25,7 +25,7 @@ SUPPORT_LANGUAGES = ["en", "de"] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Demo speech platform via config entry.""" async_add_entities([DemoProviderEntity()]) diff --git a/homeassistant/components/demo/switch.py b/homeassistant/components/demo/switch.py index 5dc05398bf1..dd288f285af 100644 --- a/homeassistant/components/demo/switch.py +++ b/homeassistant/components/demo/switch.py @@ -8,7 +8,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -16,7 +16,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo switch platform.""" async_add_entities( diff --git a/homeassistant/components/demo/text.py b/homeassistant/components/demo/text.py index 1730f414fdf..3219821ef98 100644 --- a/homeassistant/components/demo/text.py +++ b/homeassistant/components/demo/text.py @@ -6,7 +6,7 @@ from homeassistant.components.text import TextEntity, TextMode from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -14,7 +14,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo text platform.""" async_add_entities( diff --git a/homeassistant/components/demo/time.py b/homeassistant/components/demo/time.py index f5f0322f9be..296155e9bec 100644 --- a/homeassistant/components/demo/time.py +++ b/homeassistant/components/demo/time.py @@ -8,7 +8,7 @@ from homeassistant.components.time import TimeEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -16,7 +16,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo time platform.""" async_add_entities([DemoTime("time", "Time", time(12, 0, 0), False)]) diff --git a/homeassistant/components/demo/update.py b/homeassistant/components/demo/update.py index 3fa037f6b02..916646416e9 100644 --- a/homeassistant/components/demo/update.py +++ b/homeassistant/components/demo/update.py @@ -13,7 +13,7 @@ from homeassistant.components.update import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -23,7 +23,7 @@ FAKE_INSTALL_SLEEP_TIME = 0.5 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up demo update platform.""" async_add_entities( diff --git a/homeassistant/components/demo/vacuum.py b/homeassistant/components/demo/vacuum.py index 3dd945ab82e..38019cff3c1 100644 --- a/homeassistant/components/demo/vacuum.py +++ b/homeassistant/components/demo/vacuum.py @@ -14,7 +14,7 @@ from homeassistant.components.vacuum import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import event -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback SUPPORT_MINIMAL_SERVICES = VacuumEntityFeature.TURN_ON | VacuumEntityFeature.TURN_OFF @@ -63,7 +63,7 @@ DEMO_VACUUM_NONE = "4_Fourth_floor" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/water_heater.py b/homeassistant/components/demo/water_heater.py index f295780b190..7bc558a2ae4 100644 --- a/homeassistant/components/demo/water_heater.py +++ b/homeassistant/components/demo/water_heater.py @@ -11,7 +11,7 @@ from homeassistant.components.water_heater import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback SUPPORT_FLAGS_HEATER = ( WaterHeaterEntityFeature.TARGET_TEMPERATURE @@ -24,7 +24,7 @@ SUPPORT_FLAGS_HEATER = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/demo/weather.py b/homeassistant/components/demo/weather.py index 2468c54dde3..d1f829fee1b 100644 --- a/homeassistant/components/demo/weather.py +++ b/homeassistant/components/demo/weather.py @@ -26,7 +26,7 @@ from homeassistant.components.weather import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPressure, UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from homeassistant.util import dt as dt_util @@ -58,7 +58,7 @@ WEATHER_UPDATE_INTERVAL = timedelta(minutes=30) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/denonavr/media_player.py b/homeassistant/components/denonavr/media_player.py index 818d530ddab..a67c76f6525 100644 --- a/homeassistant/components/denonavr/media_player.py +++ b/homeassistant/components/denonavr/media_player.py @@ -39,7 +39,7 @@ from homeassistant.const import ATTR_COMMAND, CONF_HOST, CONF_MODEL, CONF_TYPE from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DenonavrConfigEntry from .const import ( @@ -109,7 +109,7 @@ DENON_STATE_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: DenonavrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DenonAVR receiver from a config entry.""" entities = [] diff --git a/homeassistant/components/derivative/sensor.py b/homeassistant/components/derivative/sensor.py index 988da5e938b..90f8a95919d 100644 --- a/homeassistant/components/derivative/sensor.py +++ b/homeassistant/components/derivative/sensor.py @@ -28,7 +28,10 @@ from homeassistant.core import Event, EventStateChangedData, HomeAssistant, call from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -83,7 +86,7 @@ PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Derivative config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/devialet/media_player.py b/homeassistant/components/devialet/media_player.py index 04ec58723cf..6fa6d40e17d 100644 --- a/homeassistant/components/devialet/media_player.py +++ b/homeassistant/components/devialet/media_player.py @@ -12,7 +12,7 @@ from homeassistant.components.media_player import ( from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER, SOUND_MODES @@ -38,7 +38,7 @@ DEVIALET_TO_HA_FEATURE_MAP = { async def async_setup_entry( hass: HomeAssistant, entry: DevialetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Devialet entry.""" async_add_entities([DevialetMediaPlayerEntity(entry.runtime_data)]) diff --git a/homeassistant/components/devolo_home_control/binary_sensor.py b/homeassistant/components/devolo_home_control/binary_sensor.py index d24033a80b9..7a88b12c48a 100644 --- a/homeassistant/components/devolo_home_control/binary_sensor.py +++ b/homeassistant/components/devolo_home_control/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .entity import DevoloDeviceEntity @@ -29,7 +29,7 @@ DEVICE_CLASS_MAPPING = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all binary sensor and multi level sensor devices and setup them via config entry.""" entities: list[BinarySensorEntity] = [] diff --git a/homeassistant/components/devolo_home_control/climate.py b/homeassistant/components/devolo_home_control/climate.py index 1f407eb6804..3fdfa60870a 100644 --- a/homeassistant/components/devolo_home_control/climate.py +++ b/homeassistant/components/devolo_home_control/climate.py @@ -15,7 +15,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity @@ -24,7 +24,7 @@ from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all cover devices and setup them via config entry.""" diff --git a/homeassistant/components/devolo_home_control/cover.py b/homeassistant/components/devolo_home_control/cover.py index f49a9d0f0be..f23244f1b50 100644 --- a/homeassistant/components/devolo_home_control/cover.py +++ b/homeassistant/components/devolo_home_control/cover.py @@ -10,7 +10,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity @@ -19,7 +19,7 @@ from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all cover devices and setup them via config entry.""" diff --git a/homeassistant/components/devolo_home_control/light.py b/homeassistant/components/devolo_home_control/light.py index c855574b83a..8a88081ed05 100644 --- a/homeassistant/components/devolo_home_control/light.py +++ b/homeassistant/components/devolo_home_control/light.py @@ -9,7 +9,7 @@ from devolo_home_control_api.homecontrol import HomeControl from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity @@ -18,7 +18,7 @@ from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all light devices and setup them via config entry.""" diff --git a/homeassistant/components/devolo_home_control/sensor.py b/homeassistant/components/devolo_home_control/sensor.py index 8d0a7f0313c..22581267eea 100644 --- a/homeassistant/components/devolo_home_control/sensor.py +++ b/homeassistant/components/devolo_home_control/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .entity import DevoloDeviceEntity @@ -40,7 +40,7 @@ STATE_CLASS_MAPPING = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all sensor devices and setup them via config entry.""" entities: list[SensorEntity] = [] diff --git a/homeassistant/components/devolo_home_control/siren.py b/homeassistant/components/devolo_home_control/siren.py index e896f4d3ed8..5e4df944b3c 100644 --- a/homeassistant/components/devolo_home_control/siren.py +++ b/homeassistant/components/devolo_home_control/siren.py @@ -7,7 +7,7 @@ from devolo_home_control_api.homecontrol import HomeControl from homeassistant.components.siren import ATTR_TONE, SirenEntity, SirenEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity @@ -16,7 +16,7 @@ from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all binary sensor and multi level sensor devices and setup them via config entry.""" diff --git a/homeassistant/components/devolo_home_control/switch.py b/homeassistant/components/devolo_home_control/switch.py index a6f16229046..378e23a5f5f 100644 --- a/homeassistant/components/devolo_home_control/switch.py +++ b/homeassistant/components/devolo_home_control/switch.py @@ -9,7 +9,7 @@ from devolo_home_control_api.homecontrol import HomeControl from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeControlConfigEntry from .entity import DevoloDeviceEntity @@ -18,7 +18,7 @@ from .entity import DevoloDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and setup the switch devices via config entry.""" diff --git a/homeassistant/components/devolo_home_network/binary_sensor.py b/homeassistant/components/devolo_home_network/binary_sensor.py index 5752956ffb5..2c258d758da 100644 --- a/homeassistant/components/devolo_home_network/binary_sensor.py +++ b/homeassistant/components/devolo_home_network/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeNetworkConfigEntry from .const import CONNECTED_PLC_DEVICES, CONNECTED_TO_ROUTER @@ -54,7 +54,7 @@ SENSOR_TYPES: dict[str, DevoloBinarySensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" coordinators = entry.runtime_data.coordinators diff --git a/homeassistant/components/devolo_home_network/button.py b/homeassistant/components/devolo_home_network/button.py index 06822ff199e..fe6b1786363 100644 --- a/homeassistant/components/devolo_home_network/button.py +++ b/homeassistant/components/devolo_home_network/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeNetworkConfigEntry from .const import DOMAIN, IDENTIFY, PAIRING, RESTART, START_WPS @@ -59,7 +59,7 @@ BUTTON_TYPES: dict[str, DevoloButtonEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and buttons and setup them via config entry.""" device = entry.runtime_data.device diff --git a/homeassistant/components/devolo_home_network/device_tracker.py b/homeassistant/components/devolo_home_network/device_tracker.py index 583f022df84..c5862738bd1 100644 --- a/homeassistant/components/devolo_home_network/device_tracker.py +++ b/homeassistant/components/devolo_home_network/device_tracker.py @@ -12,7 +12,7 @@ from homeassistant.components.device_tracker import ( from homeassistant.const import STATE_UNKNOWN, UnitOfFrequency from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import DevoloHomeNetworkConfigEntry @@ -25,7 +25,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" device = entry.runtime_data.device diff --git a/homeassistant/components/devolo_home_network/image.py b/homeassistant/components/devolo_home_network/image.py index 91e8dd83b7d..46a3eb3426a 100644 --- a/homeassistant/components/devolo_home_network/image.py +++ b/homeassistant/components/devolo_home_network/image.py @@ -12,7 +12,7 @@ from devolo_plc_api.device_api import WifiGuestAccessGet from homeassistant.components.image import ImageEntity, ImageEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import DevoloHomeNetworkConfigEntry @@ -42,7 +42,7 @@ IMAGE_TYPES: dict[str, DevoloImageEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" coordinators = entry.runtime_data.coordinators diff --git a/homeassistant/components/devolo_home_network/sensor.py b/homeassistant/components/devolo_home_network/sensor.py index 220ab66312a..d9a6f3f1110 100644 --- a/homeassistant/components/devolo_home_network/sensor.py +++ b/homeassistant/components/devolo_home_network/sensor.py @@ -19,7 +19,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory, UnitOfDataRate from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from . import DevoloHomeNetworkConfigEntry @@ -123,7 +123,7 @@ SENSOR_TYPES: dict[str, DevoloSensorEntityDescription[Any, Any]] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" device = entry.runtime_data.device diff --git a/homeassistant/components/devolo_home_network/switch.py b/homeassistant/components/devolo_home_network/switch.py index 8ff35dcc4b6..0271270fa09 100644 --- a/homeassistant/components/devolo_home_network/switch.py +++ b/homeassistant/components/devolo_home_network/switch.py @@ -14,7 +14,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeNetworkConfigEntry from .const import DOMAIN, SWITCH_GUEST_WIFI, SWITCH_LEDS @@ -55,7 +55,7 @@ SWITCH_TYPES: dict[str, DevoloSwitchEntityDescription[Any]] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" device = entry.runtime_data.device diff --git a/homeassistant/components/devolo_home_network/update.py b/homeassistant/components/devolo_home_network/update.py index 5091ce8e1e7..aaaf72af359 100644 --- a/homeassistant/components/devolo_home_network/update.py +++ b/homeassistant/components/devolo_home_network/update.py @@ -19,7 +19,7 @@ from homeassistant.components.update import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DevoloHomeNetworkConfigEntry from .const import DOMAIN, REGULAR_FIRMWARE @@ -51,7 +51,7 @@ UPDATE_TYPES: dict[str, DevoloUpdateEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeNetworkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Get all devices and sensors and setup them via config entry.""" coordinators = entry.runtime_data.coordinators diff --git a/homeassistant/components/dexcom/sensor.py b/homeassistant/components/dexcom/sensor.py index cdb1894b675..eac0134f010 100644 --- a/homeassistant/components/dexcom/sensor.py +++ b/homeassistant/components/dexcom/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.const import CONF_USERNAME, UnitOfBloodGlucoseConcentration from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -26,7 +26,7 @@ TRENDS = { async def async_setup_entry( hass: HomeAssistant, config_entry: DexcomConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Dexcom sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/dhcp/manifest.json b/homeassistant/components/dhcp/manifest.json index 45af4f1b5dd..45aa5a29171 100644 --- a/homeassistant/components/dhcp/manifest.json +++ b/homeassistant/components/dhcp/manifest.json @@ -15,7 +15,7 @@ "quality_scale": "internal", "requirements": [ "aiodhcpwatcher==1.1.0", - "aiodiscover==2.2.2", + "aiodiscover==2.6.0", "cached-ipaddress==0.8.0" ] } diff --git a/homeassistant/components/directv/media_player.py b/homeassistant/components/directv/media_player.py index 8998e050a75..91934a2da3a 100644 --- a/homeassistant/components/directv/media_player.py +++ b/homeassistant/components/directv/media_player.py @@ -15,7 +15,7 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import DirecTVConfigEntry @@ -55,7 +55,7 @@ SUPPORT_DTV_CLIENT = ( async def async_setup_entry( hass: HomeAssistant, entry: DirecTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DirecTV config entry.""" dtv = entry.runtime_data diff --git a/homeassistant/components/directv/remote.py b/homeassistant/components/directv/remote.py index dbaab5fa4e6..c9aacaae4d3 100644 --- a/homeassistant/components/directv/remote.py +++ b/homeassistant/components/directv/remote.py @@ -11,7 +11,7 @@ from directv import DIRECTV, DIRECTVError from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DirecTVConfigEntry from .entity import DIRECTVEntity @@ -24,7 +24,7 @@ SCAN_INTERVAL = timedelta(minutes=2) async def async_setup_entry( hass: HomeAssistant, entry: DirecTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load DirecTV remote based on a config entry.""" dtv = entry.runtime_data diff --git a/homeassistant/components/discovergy/coordinator.py b/homeassistant/components/discovergy/coordinator.py index d4ef87049b8..e3f26ad49f8 100644 --- a/homeassistant/components/discovergy/coordinator.py +++ b/homeassistant/components/discovergy/coordinator.py @@ -51,9 +51,7 @@ class DiscovergyUpdateCoordinator(DataUpdateCoordinator[Reading]): ) except InvalidLogin as err: raise ConfigEntryAuthFailed( - f"Auth expired while fetching last reading for meter {self.meter.meter_id}" + "Auth expired while fetching last reading" ) from err except (HTTPError, DiscovergyClientError) as err: - raise UpdateFailed( - f"Error while fetching last reading for meter {self.meter.meter_id}" - ) from err + raise UpdateFailed(f"Error while fetching last reading: {err}") from err diff --git a/homeassistant/components/discovergy/sensor.py b/homeassistant/components/discovergy/sensor.py index 65b1722e0d8..7d4bb6cb052 100644 --- a/homeassistant/components/discovergy/sensor.py +++ b/homeassistant/components/discovergy/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER @@ -166,7 +166,7 @@ ADDITIONAL_SENSORS: tuple[DiscovergySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: DiscovergyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Discovergy sensors.""" entities: list[DiscovergySensor] = [] diff --git a/homeassistant/components/dlink/switch.py b/homeassistant/components/dlink/switch.py index 54322cc6875..ef1348f613d 100644 --- a/homeassistant/components/dlink/switch.py +++ b/homeassistant/components/dlink/switch.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DLinkConfigEntry from .const import ATTR_TOTAL_CONSUMPTION @@ -24,7 +24,7 @@ SWITCH_TYPE = SwitchEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: DLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the D-Link Power Plug switch.""" async_add_entities([SmartPlugSwitch(entry, SWITCH_TYPE)], True) diff --git a/homeassistant/components/dlna_dmr/media_player.py b/homeassistant/components/dlna_dmr/media_player.py index 563ed209b7d..d93d55e62be 100644 --- a/homeassistant/components/dlna_dmr/media_player.py +++ b/homeassistant/components/dlna_dmr/media_player.py @@ -32,7 +32,7 @@ from homeassistant.components.media_player import ( from homeassistant.const import CONF_DEVICE_ID, CONF_MAC, CONF_TYPE, CONF_URL from homeassistant.core import CoreState, HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.ssdp import SsdpServiceInfo from .const import ( @@ -92,7 +92,7 @@ def catch_request_errors[_DlnaDmrEntityT: DlnaDmrEntity, **_P, _R]( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DlnaDmrEntity from a config entry.""" _LOGGER.debug("media_player.async_setup_entry %s (%s)", entry.entry_id, entry.title) diff --git a/homeassistant/components/dnsip/sensor.py b/homeassistant/components/dnsip/sensor.py index 34730e934a0..6708baefe8c 100644 --- a/homeassistant/components/dnsip/sensor.py +++ b/homeassistant/components/dnsip/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_HOSTNAME, @@ -45,7 +45,9 @@ def sort_ips(ips: list, querytype: str) -> list: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the dnsip sensor entry.""" diff --git a/homeassistant/components/doorbird/button.py b/homeassistant/components/doorbird/button.py index 62631e51abc..173c2e923e4 100644 --- a/homeassistant/components/doorbird/button.py +++ b/homeassistant/components/doorbird/button.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .device import ConfiguredDoorBird, async_reset_device_favorites from .entity import DoorBirdEntity @@ -45,7 +45,7 @@ BUTTON_DESCRIPTIONS: tuple[DoorbirdButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DoorBirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DoorBird button platform.""" door_bird_data = config_entry.runtime_data diff --git a/homeassistant/components/doorbird/camera.py b/homeassistant/components/doorbird/camera.py index 45f37527ac1..a41e7c41b28 100644 --- a/homeassistant/components/doorbird/camera.py +++ b/homeassistant/components/doorbird/camera.py @@ -9,7 +9,7 @@ import aiohttp from homeassistant.components.camera import Camera, CameraEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .entity import DoorBirdEntity @@ -25,7 +25,7 @@ _TIMEOUT = 15 # seconds async def async_setup_entry( hass: HomeAssistant, config_entry: DoorBirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DoorBird camera platform.""" door_bird_data = config_entry.runtime_data diff --git a/homeassistant/components/doorbird/event.py b/homeassistant/components/doorbird/event.py index 4c20098fc80..688f8b2fbeb 100644 --- a/homeassistant/components/doorbird/event.py +++ b/homeassistant/components/doorbird/event.py @@ -9,7 +9,7 @@ from homeassistant.components.event import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .device import DoorbirdEvent @@ -35,7 +35,7 @@ EVENT_DESCRIPTIONS = { async def async_setup_entry( hass: HomeAssistant, config_entry: DoorBirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DoorBird event platform.""" door_bird_data = config_entry.runtime_data diff --git a/homeassistant/components/dormakaba_dkey/binary_sensor.py b/homeassistant/components/dormakaba_dkey/binary_sensor.py index 56b991bf908..a8870ed224b 100644 --- a/homeassistant/components/dormakaba_dkey/binary_sensor.py +++ b/homeassistant/components/dormakaba_dkey/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DormakabaDkeyConfigEntry, DormakabaDkeyCoordinator from .entity import DormakabaDkeyEntity @@ -45,7 +45,7 @@ BINARY_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: DormakabaDkeyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensor platform for Dormakaba dKey.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/dormakaba_dkey/lock.py b/homeassistant/components/dormakaba_dkey/lock.py index 352e7cbe0ac..12a553adba3 100644 --- a/homeassistant/components/dormakaba_dkey/lock.py +++ b/homeassistant/components/dormakaba_dkey/lock.py @@ -8,7 +8,7 @@ from py_dormakaba_dkey.commands import UnlockStatus from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DormakabaDkeyConfigEntry, DormakabaDkeyCoordinator from .entity import DormakabaDkeyEntity @@ -17,7 +17,7 @@ from .entity import DormakabaDkeyEntity async def async_setup_entry( hass: HomeAssistant, entry: DormakabaDkeyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the lock platform for Dormakaba dKey.""" async_add_entities([DormakabaDkeyLock(entry.runtime_data)]) diff --git a/homeassistant/components/dormakaba_dkey/sensor.py b/homeassistant/components/dormakaba_dkey/sensor.py index b1e941bc7e1..413ea1c56b1 100644 --- a/homeassistant/components/dormakaba_dkey/sensor.py +++ b/homeassistant/components/dormakaba_dkey/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DormakabaDkeyConfigEntry, DormakabaDkeyCoordinator from .entity import DormakabaDkeyEntity @@ -28,7 +28,7 @@ BINARY_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: DormakabaDkeyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the lock platform for Dormakaba dKey.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/dremel_3d_printer/binary_sensor.py b/homeassistant/components/dremel_3d_printer/binary_sensor.py index 972945a84bb..923bcdad09c 100644 --- a/homeassistant/components/dremel_3d_printer/binary_sensor.py +++ b/homeassistant/components/dremel_3d_printer/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DremelConfigEntry from .entity import Dremel3DPrinterEntity @@ -43,7 +43,7 @@ BINARY_SENSOR_TYPES: tuple[Dremel3DPrinterBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, config_entry: DremelConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the available Dremel binary sensors.""" async_add_entities( diff --git a/homeassistant/components/dremel_3d_printer/button.py b/homeassistant/components/dremel_3d_printer/button.py index f91c1b0ea51..880b179650f 100644 --- a/homeassistant/components/dremel_3d_printer/button.py +++ b/homeassistant/components/dremel_3d_printer/button.py @@ -10,7 +10,7 @@ from dremel3dpy import Dremel3DPrinter from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import DremelConfigEntry from .entity import Dremel3DPrinterEntity @@ -45,7 +45,7 @@ BUTTON_TYPES: tuple[Dremel3DPrinterButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DremelConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Dremel 3D Printer control buttons.""" async_add_entities( diff --git a/homeassistant/components/dremel_3d_printer/camera.py b/homeassistant/components/dremel_3d_printer/camera.py index f4293915a25..ccb7eeaa658 100644 --- a/homeassistant/components/dremel_3d_printer/camera.py +++ b/homeassistant/components/dremel_3d_printer/camera.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.camera import CameraEntityDescription from homeassistant.components.mjpeg import MjpegCamera from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import Dremel3DPrinterDataUpdateCoordinator, DremelConfigEntry from .entity import Dremel3DPrinterEntity @@ -19,7 +19,7 @@ CAMERA_TYPE = CameraEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: DremelConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a MJPEG IP Camera for the 3D45 Model. The 3D20 and 3D40 models don't have built in cameras.""" async_add_entities([Dremel3D45Camera(config_entry.runtime_data, CAMERA_TYPE)]) diff --git a/homeassistant/components/dremel_3d_printer/sensor.py b/homeassistant/components/dremel_3d_printer/sensor.py index 002a5fc4adb..1f02b1fe239 100644 --- a/homeassistant/components/dremel_3d_printer/sensor.py +++ b/homeassistant/components/dremel_3d_printer/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow from homeassistant.util.variance import ignore_variance @@ -235,7 +235,7 @@ SENSOR_TYPES: tuple[Dremel3DPrinterSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: DremelConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the available Dremel 3D Printer sensors.""" async_add_entities( diff --git a/homeassistant/components/drop_connect/binary_sensor.py b/homeassistant/components/drop_connect/binary_sensor.py index bc8cf900610..f133be431f0 100644 --- a/homeassistant/components/drop_connect/binary_sensor.py +++ b/homeassistant/components/drop_connect/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_DEVICE_TYPE, @@ -105,7 +105,7 @@ DEVICE_BINARY_SENSORS: dict[str, list[str]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: DROPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DROP binary sensors from config entry.""" _LOGGER.debug( diff --git a/homeassistant/components/drop_connect/select.py b/homeassistant/components/drop_connect/select.py index 9e4c74b67e6..e198033d0f7 100644 --- a/homeassistant/components/drop_connect/select.py +++ b/homeassistant/components/drop_connect/select.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_DEVICE_TYPE, DEV_HUB from .coordinator import DROPConfigEntry, DROPDeviceDataUpdateCoordinator @@ -50,7 +50,7 @@ DEVICE_SELECTS: dict[str, list[str]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: DROPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DROP selects from config entry.""" _LOGGER.debug( diff --git a/homeassistant/components/drop_connect/sensor.py b/homeassistant/components/drop_connect/sensor.py index 5ec47ed9eb1..c69e2e12ea0 100644 --- a/homeassistant/components/drop_connect/sensor.py +++ b/homeassistant/components/drop_connect/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_DEVICE_TYPE, @@ -242,7 +242,7 @@ DEVICE_SENSORS: dict[str, list[str]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: DROPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DROP sensors from config entry.""" _LOGGER.debug( diff --git a/homeassistant/components/drop_connect/switch.py b/homeassistant/components/drop_connect/switch.py index 404059d3196..d52d17c5ea0 100644 --- a/homeassistant/components/drop_connect/switch.py +++ b/homeassistant/components/drop_connect/switch.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_DEVICE_TYPE, @@ -65,7 +65,7 @@ DEVICE_SWITCHES: dict[str, list[str]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: DROPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DROP switches from config entry.""" _LOGGER.debug( diff --git a/homeassistant/components/dsmr/config_flow.py b/homeassistant/components/dsmr/config_flow.py index 7d6a641b006..6f15f99517b 100644 --- a/homeassistant/components/dsmr/config_flow.py +++ b/homeassistant/components/dsmr/config_flow.py @@ -59,7 +59,7 @@ class DSMRConnection: self._equipment_identifier = obis_ref.EQUIPMENT_IDENTIFIER if dsmr_version == "5B": self._equipment_identifier = obis_ref.BELGIUM_EQUIPMENT_IDENTIFIER - if dsmr_version == "5L": + if dsmr_version in ("5L", "5EONHU"): self._equipment_identifier = obis_ref.LUXEMBOURG_EQUIPMENT_IDENTIFIER if dsmr_version == "Q3D": self._equipment_identifier = obis_ref.Q3D_EQUIPMENT_IDENTIFIER diff --git a/homeassistant/components/dsmr/const.py b/homeassistant/components/dsmr/const.py index 4c6cb31ca4d..2682b4df1cc 100644 --- a/homeassistant/components/dsmr/const.py +++ b/homeassistant/components/dsmr/const.py @@ -28,7 +28,7 @@ DEVICE_NAME_GAS = "Gas Meter" DEVICE_NAME_WATER = "Water Meter" DEVICE_NAME_HEAT = "Heat Meter" -DSMR_VERSIONS = {"2.2", "4", "5", "5B", "5L", "5S", "Q3D"} +DSMR_VERSIONS = {"2.2", "4", "5", "5B", "5L", "5S", "Q3D", "5EONHU"} DSMR_PROTOCOL = "dsmr_protocol" RFXTRX_DSMR_PROTOCOL = "rfxtrx_dsmr_protocol" diff --git a/homeassistant/components/dsmr/sensor.py b/homeassistant/components/dsmr/sensor.py index e05785b8b26..ba528271824 100644 --- a/homeassistant/components/dsmr/sensor.py +++ b/homeassistant/components/dsmr/sensor.py @@ -43,7 +43,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import Throttle @@ -115,7 +115,7 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_active_tariff", translation_key="electricity_active_tariff", obis_reference="ELECTRICITY_ACTIVE_TARIFF", - dsmr_versions={"2.2", "4", "5", "5B", "5L"}, + dsmr_versions={"2.2", "4", "5", "5B", "5L", "5EONHU"}, device_class=SensorDeviceClass.ENUM, options=["low", "normal"], ), @@ -123,7 +123,7 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_used_tariff_1", translation_key="electricity_used_tariff_1", obis_reference="ELECTRICITY_USED_TARIFF_1", - dsmr_versions={"2.2", "4", "5", "5B", "5L"}, + dsmr_versions={"2.2", "4", "5", "5B", "5L", "5EONHU"}, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -131,7 +131,25 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_used_tariff_2", translation_key="electricity_used_tariff_2", obis_reference="ELECTRICITY_USED_TARIFF_2", - dsmr_versions={"2.2", "4", "5", "5B", "5L"}, + dsmr_versions={"2.2", "4", "5", "5B", "5L", "5EONHU"}, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + DSMRSensorEntityDescription( + key="electricity_used_tariff_3", + translation_key="electricity_used_tariff_3", + obis_reference="ELECTRICITY_USED_TARIFF_3", + dsmr_versions={"5EONHU"}, + force_update=True, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + DSMRSensorEntityDescription( + key="electricity_used_tariff_4", + translation_key="electricity_used_tariff_4", + obis_reference="ELECTRICITY_USED_TARIFF_4", + dsmr_versions={"5EONHU"}, + force_update=True, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -139,7 +157,7 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_delivered_tariff_1", translation_key="electricity_delivered_tariff_1", obis_reference="ELECTRICITY_DELIVERED_TARIFF_1", - dsmr_versions={"2.2", "4", "5", "5B", "5L"}, + dsmr_versions={"2.2", "4", "5", "5B", "5L", "5EONHU"}, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -147,7 +165,25 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_delivered_tariff_2", translation_key="electricity_delivered_tariff_2", obis_reference="ELECTRICITY_DELIVERED_TARIFF_2", - dsmr_versions={"2.2", "4", "5", "5B", "5L"}, + dsmr_versions={"2.2", "4", "5", "5B", "5L", "5EONHU"}, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + DSMRSensorEntityDescription( + key="electricity_delivered_tariff_3", + translation_key="electricity_delivered_tariff_3", + obis_reference="ELECTRICITY_DELIVERED_TARIFF_3", + dsmr_versions={"5EONHU"}, + force_update=True, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + DSMRSensorEntityDescription( + key="electricity_delivered_tariff_4", + translation_key="electricity_delivered_tariff_4", + obis_reference="ELECTRICITY_DELIVERED_TARIFF_4", + dsmr_versions={"5EONHU"}, + force_update=True, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -341,7 +377,7 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_imported_total", translation_key="electricity_imported_total", obis_reference="ELECTRICITY_IMPORTED_TOTAL", - dsmr_versions={"5L", "5S", "Q3D"}, + dsmr_versions={"5L", "5S", "Q3D", "5EONHU"}, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -349,7 +385,7 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( key="electricity_exported_total", translation_key="electricity_exported_total", obis_reference="ELECTRICITY_EXPORTED_TOTAL", - dsmr_versions={"5L", "5S", "Q3D"}, + dsmr_versions={"5L", "5S", "Q3D", "5EONHU"}, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), @@ -387,6 +423,113 @@ SENSORS: tuple[DSMRSensorEntityDescription, ...] = ( device_class=SensorDeviceClass.GAS, state_class=SensorStateClass.TOTAL_INCREASING, ), + DSMRSensorEntityDescription( + key="actual_threshold_electricity", + translation_key="actual_threshold_electricity", + obis_reference="ACTUAL_TRESHOLD_ELECTRICITY", # Misspelled in external tool + dsmr_versions={"5EONHU"}, + device_class=SensorDeviceClass.POWER, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="eon_hu_electricity_combined", + translation_key="electricity_combined", + obis_reference="EON_HU_ELECTRICITY_COMBINED", + dsmr_versions={"5EONHU"}, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + DSMRSensorEntityDescription( + key="eon_hu_instantaneous_power_factor_total", + translation_key="instantaneous_power_factor_total", + obis_reference="EON_HU_INSTANTANEOUS_POWER_FACTOR_TOTAL", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.POWER_FACTOR, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="eon_hu_instantaneous_power_factor_l1", + translation_key="instantaneous_power_factor_l1", + obis_reference="EON_HU_INSTANTANEOUS_POWER_FACTOR_L1", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.POWER_FACTOR, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="eon_hu_instantaneous_power_factor_l2", + translation_key="instantaneous_power_factor_l2", + obis_reference="EON_HU_INSTANTANEOUS_POWER_FACTOR_L2", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.POWER_FACTOR, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="eon_hu_instantaneous_power_factor_l3", + translation_key="instantaneous_power_factor_l3", + obis_reference="EON_HU_INSTANTANEOUS_POWER_FACTOR_L3", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.POWER_FACTOR, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="eon_hu_frequency", + translation_key="frequency", + obis_reference="EON_HU_FREQUENCY", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.FREQUENCY, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="fuse_threshold_l1", + translation_key="fuse_threshold_l1", + obis_reference="FUSE_THRESHOLD_L1", + dsmr_versions={"5EONHU"}, + device_class=SensorDeviceClass.CURRENT, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="fuse_threshold_l2", + translation_key="fuse_threshold_l2", + obis_reference="FUSE_THRESHOLD_L2", + dsmr_versions={"5EONHU"}, + device_class=SensorDeviceClass.CURRENT, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="fuse_threshold_l3", + translation_key="fuse_threshold_l3", + obis_reference="FUSE_THRESHOLD_L3", + dsmr_versions={"5EONHU"}, + device_class=SensorDeviceClass.CURRENT, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), + DSMRSensorEntityDescription( + key="text_message", + translation_key="text_message", + obis_reference="TEXT_MESSAGE", + dsmr_versions={"5EONHU"}, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ), ) SENSORS_MBUS_DEVICE_TYPE: dict[int, tuple[DSMRSensorEntityDescription, ...]] = { @@ -549,7 +692,9 @@ def get_dsmr_object( async def async_setup_entry( - hass: HomeAssistant, entry: DsmrConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: DsmrConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the DSMR sensor.""" dsmr_version = entry.data[CONF_DSMR_VERSION] @@ -842,8 +987,9 @@ class DSMREntity(SensorEntity): def translate_tariff(value: str, dsmr_version: str) -> str | None: """Convert 2/1 to normal/low depending on DSMR version.""" # DSMR V5B: Note: In Belgium values are swapped: + # DSMR V5EONHU: Note: In EON HUngary values are swapped: # Rate code 2 is used for low rate and rate code 1 is used for normal rate. - if dsmr_version == "5B": + if dsmr_version in ("5B", "5EONHU"): if value == "0001": value = "0002" elif value == "0002": diff --git a/homeassistant/components/dsmr/strings.json b/homeassistant/components/dsmr/strings.json index 055c0c41264..871dd382f2b 100644 --- a/homeassistant/components/dsmr/strings.json +++ b/homeassistant/components/dsmr/strings.json @@ -61,6 +61,12 @@ "electricity_delivered_tariff_2": { "name": "Energy production (tarif 2)" }, + "electricity_delivered_tariff_3": { + "name": "Energy production (tarif 3)" + }, + "electricity_delivered_tariff_4": { + "name": "Energy production (tarif 4)" + }, "electricity_exported_total": { "name": "Energy production (total)" }, @@ -73,6 +79,12 @@ "electricity_used_tariff_2": { "name": "Energy consumption (tarif 2)" }, + "electricity_used_tariff_3": { + "name": "Energy consumption (tarif 3)" + }, + "electricity_used_tariff_4": { + "name": "Energy consumption (tarif 4)" + }, "gas_meter_reading": { "name": "Gas consumption" }, @@ -150,6 +162,57 @@ }, "water_meter_reading": { "name": "Water consumption" + }, + "actual_threshold_electricity": { + "name": "Actual threshold electricity" + }, + "electricity_reactive_imported_total": { + "name": "Imported reactive electricity (total)" + }, + "electricity_reactive_exported_total": { + "name": "Exported reactive electricity (total)" + }, + "electricity_reactive_total_q1": { + "name": "Reactive electricity (Q1)" + }, + "electricity_reactive_total_q2": { + "name": "Reactive electricity (Q2)" + }, + "electricity_reactive_total_q3": { + "name": "Reactive electricity (Q3)" + }, + "electricity_reactive_total_q4": { + "name": "Reactive electricity (Q4)" + }, + "electricity_combined": { + "name": "Energy combined" + }, + "instantaneous_power_factor_total": { + "name": "Instantaneous power factor (total)" + }, + "instantaneous_power_factor_l1": { + "name": "Instantaneous power factor L1" + }, + "instantaneous_power_factor_l2": { + "name": "Instantaneous power factor L2" + }, + "instantaneous_power_factor_l3": { + "name": "Instantaneous power factor L3" + }, + "frequency": { + "name": "Frequency" + }, + "fuse_threshold_l1": { + "name": "Fuse threshold on L1" + }, + "fuse_threshold_l2": { + "name": "Fuse threshold on L2" + }, + "fuse_threshold_l3": { + "name": "Fuse threshold on L3" + }, + "text_message": { + "name": "Text message" } } }, diff --git a/homeassistant/components/dsmr_reader/sensor.py b/homeassistant/components/dsmr_reader/sensor.py index 784a4cdec51..c9bd9c9fff2 100644 --- a/homeassistant/components/dsmr_reader/sensor.py +++ b/homeassistant/components/dsmr_reader/sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.util import slugify @@ -18,7 +18,7 @@ from .definitions import SENSORS, DSMRReaderSensorEntityDescription async def async_setup_entry( _: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up DSMR Reader sensors from config entry.""" async_add_entities(DSMRSensor(description, config_entry) for description in SENSORS) diff --git a/homeassistant/components/dunehd/media_player.py b/homeassistant/components/dunehd/media_player.py index db903cac2bf..b3093221385 100644 --- a/homeassistant/components/dunehd/media_player.py +++ b/homeassistant/components/dunehd/media_player.py @@ -17,7 +17,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuneHDConfigEntry from .const import ATTR_MANUFACTURER, DEFAULT_NAME, DOMAIN @@ -39,7 +39,7 @@ DUNEHD_PLAYER_SUPPORT: Final[MediaPlayerEntityFeature] = ( async def async_setup_entry( hass: HomeAssistant, entry: DuneHDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Dune HD entities from a config_entry.""" async_add_entities( diff --git a/homeassistant/components/duotecno/binary_sensor.py b/homeassistant/components/duotecno/binary_sensor.py index aadef47b998..e2431b5eade 100644 --- a/homeassistant/components/duotecno/binary_sensor.py +++ b/homeassistant/components/duotecno/binary_sensor.py @@ -6,7 +6,7 @@ from duotecno.unit import ControlUnit, VirtualUnit from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuotecnoConfigEntry from .entity import DuotecnoEntity @@ -15,7 +15,7 @@ from .entity import DuotecnoEntity async def async_setup_entry( hass: HomeAssistant, entry: DuotecnoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Duotecno binary sensor on config_entry.""" async_add_entities( diff --git a/homeassistant/components/duotecno/climate.py b/homeassistant/components/duotecno/climate.py index 83a211d97f5..0ae6735feb5 100644 --- a/homeassistant/components/duotecno/climate.py +++ b/homeassistant/components/duotecno/climate.py @@ -13,7 +13,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuotecnoConfigEntry from .entity import DuotecnoEntity, api_call @@ -32,7 +32,7 @@ PRESETMODES_REVERSE: Final = {value: key for key, value in PRESETMODES.items()} async def async_setup_entry( hass: HomeAssistant, entry: DuotecnoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Duotecno climate based on config_entry.""" async_add_entities( diff --git a/homeassistant/components/duotecno/cover.py b/homeassistant/components/duotecno/cover.py index 7d879741555..e184cf7ffb3 100644 --- a/homeassistant/components/duotecno/cover.py +++ b/homeassistant/components/duotecno/cover.py @@ -8,7 +8,7 @@ from duotecno.unit import DuoswitchUnit from homeassistant.components.cover import CoverEntity, CoverEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuotecnoConfigEntry from .entity import DuotecnoEntity, api_call @@ -17,7 +17,7 @@ from .entity import DuotecnoEntity, api_call async def async_setup_entry( hass: HomeAssistant, entry: DuotecnoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the duoswitch endities.""" async_add_entities( diff --git a/homeassistant/components/duotecno/light.py b/homeassistant/components/duotecno/light.py index 7b41cbaef22..38617c92748 100644 --- a/homeassistant/components/duotecno/light.py +++ b/homeassistant/components/duotecno/light.py @@ -6,7 +6,7 @@ from duotecno.unit import DimUnit from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuotecnoConfigEntry from .entity import DuotecnoEntity, api_call @@ -15,7 +15,7 @@ from .entity import DuotecnoEntity, api_call async def async_setup_entry( hass: HomeAssistant, entry: DuotecnoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Duotecno light based on config_entry.""" async_add_entities( diff --git a/homeassistant/components/duotecno/switch.py b/homeassistant/components/duotecno/switch.py index 0c01a6ca4de..cef7715e946 100644 --- a/homeassistant/components/duotecno/switch.py +++ b/homeassistant/components/duotecno/switch.py @@ -6,7 +6,7 @@ from duotecno.unit import SwitchUnit from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DuotecnoConfigEntry from .entity import DuotecnoEntity, api_call @@ -15,7 +15,7 @@ from .entity import DuotecnoEntity, api_call async def async_setup_entry( hass: HomeAssistant, entry: DuotecnoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" async_add_entities( diff --git a/homeassistant/components/dwd_weather_warnings/sensor.py b/homeassistant/components/dwd_weather_warnings/sensor.py index 0aaf1f2a801..1c2817350a5 100644 --- a/homeassistant/components/dwd_weather_warnings/sensor.py +++ b/homeassistant/components/dwd_weather_warnings/sensor.py @@ -16,7 +16,7 @@ from typing import Any from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -55,7 +55,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: DwdWeatherWarningsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities from config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/dynalite/cover.py b/homeassistant/components/dynalite/cover.py index 17adf1947ec..2cd473a2977 100644 --- a/homeassistant/components/dynalite/cover.py +++ b/homeassistant/components/dynalite/cover.py @@ -8,7 +8,7 @@ from homeassistant.components.cover import ( CoverEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from .bridge import DynaliteBridge, DynaliteConfigEntry @@ -18,7 +18,7 @@ from .entity import DynaliteBase, async_setup_entry_base async def async_setup_entry( hass: HomeAssistant, config_entry: DynaliteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Record the async_add_entities function to add them later when received from Dynalite.""" diff --git a/homeassistant/components/dynalite/light.py b/homeassistant/components/dynalite/light.py index ea2bc2bc96f..e9816c828db 100644 --- a/homeassistant/components/dynalite/light.py +++ b/homeassistant/components/dynalite/light.py @@ -4,7 +4,7 @@ from typing import Any from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import DynaliteConfigEntry from .entity import DynaliteBase, async_setup_entry_base @@ -13,7 +13,7 @@ from .entity import DynaliteBase, async_setup_entry_base async def async_setup_entry( hass: HomeAssistant, config_entry: DynaliteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Record the async_add_entities function to add them later when received from Dynalite.""" async_setup_entry_base( diff --git a/homeassistant/components/dynalite/switch.py b/homeassistant/components/dynalite/switch.py index dd6aad8670c..29f78ecbc20 100644 --- a/homeassistant/components/dynalite/switch.py +++ b/homeassistant/components/dynalite/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import DynaliteConfigEntry from .entity import DynaliteBase, async_setup_entry_base @@ -14,7 +14,7 @@ from .entity import DynaliteBase, async_setup_entry_base async def async_setup_entry( hass: HomeAssistant, config_entry: DynaliteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Record the async_add_entities function to add them later when received from Dynalite.""" async_setup_entry_base( diff --git a/homeassistant/components/eafm/sensor.py b/homeassistant/components/eafm/sensor.py index d9b18cbc663..5d0af596521 100644 --- a/homeassistant/components/eafm/sensor.py +++ b/homeassistant/components/eafm/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -20,7 +20,7 @@ UNIT_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: EafmConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up UK Flood Monitoring Sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/easyenergy/sensor.py b/homeassistant/components/easyenergy/sensor.py index 6976a38da49..35fab870af3 100644 --- a/homeassistant/components/easyenergy/sensor.py +++ b/homeassistant/components/easyenergy/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, SERVICE_TYPE_DEVICE_NAMES @@ -213,7 +213,7 @@ def get_gas_price(data: EasyEnergyData, hours: int) -> float | None: async def async_setup_entry( hass: HomeAssistant, entry: EasyEnergyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up easyEnergy sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ecobee/binary_sensor.py b/homeassistant/components/ecobee/binary_sensor.py index 9c9f2192f43..76b3399ec6e 100644 --- a/homeassistant/components/ecobee/binary_sensor.py +++ b/homeassistant/components/ecobee/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcobeeConfigEntry from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER @@ -17,7 +17,7 @@ from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ecobee binary (occupancy) sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index 743e2e1ba4b..26fb362ba03 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -38,7 +38,7 @@ from homeassistant.helpers import ( entity_platform, ) from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter from . import EcobeeConfigEntry, EcobeeData @@ -204,7 +204,7 @@ SUPPORT_FLAGS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat.""" diff --git a/homeassistant/components/ecobee/humidifier.py b/homeassistant/components/ecobee/humidifier.py index 982cbdd07f2..ab6831d8f26 100644 --- a/homeassistant/components/ecobee/humidifier.py +++ b/homeassistant/components/ecobee/humidifier.py @@ -14,7 +14,7 @@ from homeassistant.components.humidifier import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcobeeConfigEntry from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER @@ -28,7 +28,7 @@ MODE_OFF = "off" async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat humidifier entity.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/notify.py b/homeassistant/components/ecobee/notify.py index 7c70d7ae4ac..2cf6a30acd7 100644 --- a/homeassistant/components/ecobee/notify.py +++ b/homeassistant/components/ecobee/notify.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.notify import NotifyEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcobeeConfigEntry, EcobeeData from .entity import EcobeeBaseEntity @@ -13,7 +13,7 @@ from .entity import EcobeeBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/number.py b/homeassistant/components/ecobee/number.py index f047ea8f896..50e9170394d 100644 --- a/homeassistant/components/ecobee/number.py +++ b/homeassistant/components/ecobee/number.py @@ -14,7 +14,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcobeeConfigEntry, EcobeeData from .entity import EcobeeBaseEntity @@ -53,7 +53,7 @@ VENTILATOR_NUMBERS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat number entity.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/sensor.py b/homeassistant/components/ecobee/sensor.py index 1b50fc21edf..759f167ec1c 100644 --- a/homeassistant/components/ecobee/sensor.py +++ b/homeassistant/components/ecobee/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcobeeConfigEntry from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER @@ -74,7 +74,7 @@ SENSOR_TYPES: tuple[EcobeeSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ecobee sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/switch.py b/homeassistant/components/ecobee/switch.py index c92082b7b58..e0848913b39 100644 --- a/homeassistant/components/ecobee/switch.py +++ b/homeassistant/components/ecobee/switch.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.climate import HVACMode from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import EcobeeConfigEntry, EcobeeData @@ -25,7 +25,7 @@ DATE_FORMAT = "%Y-%m-%d %H:%M:%S" async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat switch entity.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecobee/weather.py b/homeassistant/components/ecobee/weather.py index 39b2d30ddd8..126f8dd5061 100644 --- a/homeassistant/components/ecobee/weather.py +++ b/homeassistant/components/ecobee/weather.py @@ -25,7 +25,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import EcobeeConfigEntry @@ -40,7 +40,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcobeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee weather platform.""" data = config_entry.runtime_data diff --git a/homeassistant/components/ecoforest/number.py b/homeassistant/components/ecoforest/number.py index 878c150343e..c1d5f5f3055 100644 --- a/homeassistant/components/ecoforest/number.py +++ b/homeassistant/components/ecoforest/number.py @@ -9,7 +9,7 @@ from pyecoforest.models.device import Device from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EcoforestConfigEntry from .entity import EcoforestEntity @@ -37,7 +37,7 @@ NUMBER_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcoforestConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ecoforest number platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/ecoforest/sensor.py b/homeassistant/components/ecoforest/sensor.py index 0babb476ab6..c1d4aca6f0c 100644 --- a/homeassistant/components/ecoforest/sensor.py +++ b/homeassistant/components/ecoforest/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import EcoforestConfigEntry @@ -143,7 +143,7 @@ SENSOR_TYPES: tuple[EcoforestSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: EcoforestConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ecoforest sensor platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ecoforest/switch.py b/homeassistant/components/ecoforest/switch.py index de52248e751..bd83bfc9ee5 100644 --- a/homeassistant/components/ecoforest/switch.py +++ b/homeassistant/components/ecoforest/switch.py @@ -11,7 +11,7 @@ from pyecoforest.models.device import Device from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EcoforestConfigEntry from .entity import EcoforestEntity @@ -38,7 +38,7 @@ SWITCH_TYPES: tuple[EcoforestSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcoforestConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ecoforest switch platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/econet/binary_sensor.py b/homeassistant/components/econet/binary_sensor.py index 13ef8c4713b..0d041dfca5a 100644 --- a/homeassistant/components/econet/binary_sensor.py +++ b/homeassistant/components/econet/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EconetConfigEntry from .entity import EcoNetEntity @@ -42,7 +42,7 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: EconetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EcoNet binary sensor based on a config entry.""" equipment = entry.runtime_data diff --git a/homeassistant/components/econet/climate.py b/homeassistant/components/econet/climate.py index d46dbd8750a..b9673869046 100644 --- a/homeassistant/components/econet/climate.py +++ b/homeassistant/components/econet/climate.py @@ -22,7 +22,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from . import EconetConfigEntry @@ -57,7 +57,7 @@ SUPPORT_FLAGS_THERMOSTAT = ( async def async_setup_entry( hass: HomeAssistant, entry: EconetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EcoNet thermostat based on a config entry.""" equipment = entry.runtime_data diff --git a/homeassistant/components/econet/manifest.json b/homeassistant/components/econet/manifest.json index bda52ee3d07..86e3b3527f0 100644 --- a/homeassistant/components/econet/manifest.json +++ b/homeassistant/components/econet/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/econet", "iot_class": "cloud_push", "loggers": ["paho_mqtt", "pyeconet"], - "requirements": ["pyeconet==0.1.26"] + "requirements": ["pyeconet==0.1.27"] } diff --git a/homeassistant/components/econet/sensor.py b/homeassistant/components/econet/sensor.py index 510906d699c..1cc806ca8d5 100644 --- a/homeassistant/components/econet/sensor.py +++ b/homeassistant/components/econet/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EconetConfigEntry from .entity import EcoNetEntity @@ -83,7 +83,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: EconetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EcoNet sensor based on a config entry.""" diff --git a/homeassistant/components/econet/switch.py b/homeassistant/components/econet/switch.py index 9fcd38c860e..ff7f017b49f 100644 --- a/homeassistant/components/econet/switch.py +++ b/homeassistant/components/econet/switch.py @@ -10,7 +10,7 @@ from pyeconet.equipment.thermostat import Thermostat, ThermostatOperationMode from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EconetConfigEntry from .entity import EcoNetEntity @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: EconetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ecobee thermostat switch entity.""" equipment = entry.runtime_data diff --git a/homeassistant/components/econet/water_heater.py b/homeassistant/components/econet/water_heater.py index cfbff70b580..fb74ae8b4a5 100644 --- a/homeassistant/components/econet/water_heater.py +++ b/homeassistant/components/econet/water_heater.py @@ -19,7 +19,7 @@ from homeassistant.components.water_heater import ( ) from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EconetConfigEntry from .entity import EcoNetEntity @@ -48,7 +48,7 @@ SUPPORT_FLAGS_HEATER = ( async def async_setup_entry( hass: HomeAssistant, entry: EconetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EcoNet water heater based on a config entry.""" equipment = entry.runtime_data diff --git a/homeassistant/components/ecovacs/binary_sensor.py b/homeassistant/components/ecovacs/binary_sensor.py index d755d01a4ae..552a8152cc5 100644 --- a/homeassistant/components/ecovacs/binary_sensor.py +++ b/homeassistant/components/ecovacs/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import EcovacsCapabilityEntityDescription, EcovacsDescriptionEntity, EventT @@ -45,7 +45,7 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" async_add_entities( diff --git a/homeassistant/components/ecovacs/button.py b/homeassistant/components/ecovacs/button.py index 2759ca972df..04eb0af02e6 100644 --- a/homeassistant/components/ecovacs/button.py +++ b/homeassistant/components/ecovacs/button.py @@ -13,7 +13,7 @@ from deebot_client.events import LifeSpan from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .const import SUPPORTED_LIFESPANS, SUPPORTED_STATION_ACTIONS @@ -81,7 +81,7 @@ LIFESPAN_ENTITY_DESCRIPTIONS = tuple( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/event.py b/homeassistant/components/ecovacs/event.py index 3249b466c77..488767b472d 100644 --- a/homeassistant/components/ecovacs/event.py +++ b/homeassistant/components/ecovacs/event.py @@ -7,7 +7,7 @@ from deebot_client.events import CleanJobStatus, ReportStatsEvent from homeassistant.components.event import EventEntity, EventEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import EcovacsEntity @@ -17,7 +17,7 @@ from .util import get_name_key async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/image.py b/homeassistant/components/ecovacs/image.py index d8b69084cec..f8a89b0cfa0 100644 --- a/homeassistant/components/ecovacs/image.py +++ b/homeassistant/components/ecovacs/image.py @@ -7,7 +7,7 @@ from deebot_client.events.map import CachedMapInfoEvent, MapChangedEvent from homeassistant.components.image import ImageEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import EcovacsEntity @@ -16,7 +16,7 @@ from .entity import EcovacsEntity async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/lawn_mower.py b/homeassistant/components/ecovacs/lawn_mower.py index bf773207dc5..b9af67fafcd 100644 --- a/homeassistant/components/ecovacs/lawn_mower.py +++ b/homeassistant/components/ecovacs/lawn_mower.py @@ -16,7 +16,7 @@ from homeassistant.components.lawn_mower import ( LawnMowerEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import EcovacsEntity @@ -37,7 +37,7 @@ _STATE_TO_MOWER_STATE = { async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ecovacs mowers.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/number.py b/homeassistant/components/ecovacs/number.py index adf282560a9..7a74b02ceca 100644 --- a/homeassistant/components/ecovacs/number.py +++ b/homeassistant/components/ecovacs/number.py @@ -16,7 +16,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import DEGREE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import ( @@ -83,7 +83,7 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/select.py b/homeassistant/components/ecovacs/select.py index 3c3852f05ec..a7b9baf1c4a 100644 --- a/homeassistant/components/ecovacs/select.py +++ b/homeassistant/components/ecovacs/select.py @@ -11,7 +11,7 @@ from deebot_client.events import WaterInfoEvent, WorkModeEvent from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import EcovacsCapabilityEntityDescription, EcovacsDescriptionEntity, EventT @@ -54,7 +54,7 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/sensor.py b/homeassistant/components/ecovacs/sensor.py index 0e906c6cb16..6c8ae080fc3 100644 --- a/homeassistant/components/ecovacs/sensor.py +++ b/homeassistant/components/ecovacs/sensor.py @@ -35,7 +35,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import EcovacsConfigEntry @@ -192,7 +192,7 @@ LEGACY_LIFESPAN_SENSORS = tuple( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/switch.py b/homeassistant/components/ecovacs/switch.py index 288d092d391..dd379dbb199 100644 --- a/homeassistant/components/ecovacs/switch.py +++ b/homeassistant/components/ecovacs/switch.py @@ -9,7 +9,7 @@ from deebot_client.events import EnableEvent from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcovacsConfigEntry from .entity import ( @@ -105,7 +105,7 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for passed config_entry in HA.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/ecovacs/vacuum.py b/homeassistant/components/ecovacs/vacuum.py index bc78981d1db..6570b80e920 100644 --- a/homeassistant/components/ecovacs/vacuum.py +++ b/homeassistant/components/ecovacs/vacuum.py @@ -21,7 +21,7 @@ from homeassistant.components.vacuum import ( from homeassistant.core import HomeAssistant, SupportsResponse from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from homeassistant.util import slugify @@ -41,7 +41,7 @@ SERVICE_RAW_GET_POSITIONS = "raw_get_positions" async def async_setup_entry( hass: HomeAssistant, config_entry: EcovacsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ecovacs vacuums.""" diff --git a/homeassistant/components/ecowitt/binary_sensor.py b/homeassistant/components/ecowitt/binary_sensor.py index 5bc782e3589..a2ed279f601 100644 --- a/homeassistant/components/ecowitt/binary_sensor.py +++ b/homeassistant/components/ecowitt/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EcowittConfigEntry from .entity import EcowittEntity @@ -32,7 +32,7 @@ ECOWITT_BINARYSENSORS_MAPPING: Final = { async def async_setup_entry( hass: HomeAssistant, entry: EcowittConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add sensors if new.""" ecowitt = entry.runtime_data diff --git a/homeassistant/components/ecowitt/sensor.py b/homeassistant/components/ecowitt/sensor.py index 23af2f2a3af..b7816de0f35 100644 --- a/homeassistant/components/ecowitt/sensor.py +++ b/homeassistant/components/ecowitt/sensor.py @@ -32,7 +32,7 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM @@ -218,7 +218,7 @@ ECOWITT_SENSORS_MAPPING: Final = { async def async_setup_entry( hass: HomeAssistant, entry: EcowittConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add sensors if new.""" ecowitt = entry.runtime_data diff --git a/homeassistant/components/edl21/sensor.py b/homeassistant/components/edl21/sensor.py index 62d06a8a535..3194781d71c 100644 --- a/homeassistant/components/edl21/sensor.py +++ b/homeassistant/components/edl21/sensor.py @@ -30,7 +30,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .const import ( @@ -289,7 +289,7 @@ SENSOR_UNIT_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the EDL21 sensor.""" api = EDL21(hass, config_entry.data, async_add_entities) @@ -317,7 +317,7 @@ class EDL21: self, hass: HomeAssistant, config: Mapping[str, Any], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize an EDL21 object.""" self._registered_obis: set[tuple[str, str]] = set() diff --git a/homeassistant/components/efergy/sensor.py b/homeassistant/components/efergy/sensor.py index 419c4da591d..6b54e4779a0 100644 --- a/homeassistant/components/efergy/sensor.py +++ b/homeassistant/components/efergy/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import EfergyConfigEntry @@ -108,7 +108,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: EfergyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Efergy sensors.""" api = entry.runtime_data diff --git a/homeassistant/components/eheimdigital/climate.py b/homeassistant/components/eheimdigital/climate.py index f0038982965..0af7eb0c623 100644 --- a/homeassistant/components/eheimdigital/climate.py +++ b/homeassistant/components/eheimdigital/climate.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import HEATER_BIO_MODE, HEATER_PRESET_TO_HEATER_MODE, HEATER_SMART_MODE from .coordinator import EheimDigitalConfigEntry, EheimDigitalUpdateCoordinator @@ -34,7 +34,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: EheimDigitalConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the callbacks for the coordinator so climate entities can be added as devices are found.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/eheimdigital/light.py b/homeassistant/components/eheimdigital/light.py index 25498cf3af1..02062831fd3 100644 --- a/homeassistant/components/eheimdigital/light.py +++ b/homeassistant/components/eheimdigital/light.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.color import brightness_to_value, value_to_brightness from .const import EFFECT_DAYCL_MODE, EFFECT_TO_LIGHT_MODE @@ -32,7 +32,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: EheimDigitalConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the callbacks for the coordinator so lights can be added as devices are found.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/electrasmart/climate.py b/homeassistant/components/electrasmart/climate.py index 84def436dfb..bdf94f606db 100644 --- a/homeassistant/components/electrasmart/climate.py +++ b/homeassistant/components/electrasmart/climate.py @@ -28,7 +28,7 @@ from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElectraSmartConfigEntry from .const import ( @@ -91,7 +91,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: ElectraSmartConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Electra AC devices.""" api = entry.runtime_data diff --git a/homeassistant/components/electric_kiwi/select.py b/homeassistant/components/electric_kiwi/select.py index 30e02b5c5b9..38dc595b087 100644 --- a/homeassistant/components/electric_kiwi/select.py +++ b/homeassistant/components/electric_kiwi/select.py @@ -7,7 +7,7 @@ import logging from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTRIBUTION @@ -26,7 +26,7 @@ HOP_SELECT = SelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: ElectricKiwiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Electric Kiwi select setup.""" hop_coordinator = entry.runtime_data.hop diff --git a/homeassistant/components/electric_kiwi/sensor.py b/homeassistant/components/electric_kiwi/sensor.py index 410d70808c3..291208b74b8 100644 --- a/homeassistant/components/electric_kiwi/sensor.py +++ b/homeassistant/components/electric_kiwi/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CURRENCY_DOLLAR, PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -130,7 +130,7 @@ HOP_SENSOR_TYPES: tuple[ElectricKiwiHOPSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ElectricKiwiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Electric Kiwi Sensors Setup.""" account_coordinator = entry.runtime_data.account diff --git a/homeassistant/components/elevenlabs/tts.py b/homeassistant/components/elevenlabs/tts.py index 008cd106615..efcadb3f440 100644 --- a/homeassistant/components/elevenlabs/tts.py +++ b/homeassistant/components/elevenlabs/tts.py @@ -20,7 +20,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElevenLabsConfigEntry from .const import ( @@ -58,7 +58,7 @@ def to_voice_settings(options: MappingProxyType[str, Any]) -> VoiceSettings: async def async_setup_entry( hass: HomeAssistant, config_entry: ElevenLabsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ElevenLabs tts platform via config entry.""" client = config_entry.runtime_data.client diff --git a/homeassistant/components/elgato/button.py b/homeassistant/components/elgato/button.py index 505eff36b44..23ed65ded33 100644 --- a/homeassistant/components/elgato/button.py +++ b/homeassistant/components/elgato/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElgatoConfigEntry, ElgatoDataUpdateCoordinator from .entity import ElgatoEntity @@ -50,7 +50,7 @@ BUTTONS = [ async def async_setup_entry( hass: HomeAssistant, entry: ElgatoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Elgato button based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/elgato/light.py b/homeassistant/components/elgato/light.py index 990a0606fce..7d2010f7ba4 100644 --- a/homeassistant/components/elgato/light.py +++ b/homeassistant/components/elgato/light.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.util import color as color_util @@ -31,7 +31,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: ElgatoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Elgato Light based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/elgato/sensor.py b/homeassistant/components/elgato/sensor.py index 529d2f7c76e..02dbc2aeef6 100644 --- a/homeassistant/components/elgato/sensor.py +++ b/homeassistant/components/elgato/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElgatoConfigEntry, ElgatoData, ElgatoDataUpdateCoordinator from .entity import ElgatoEntity @@ -104,7 +104,7 @@ SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: ElgatoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Elgato sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/elgato/switch.py b/homeassistant/components/elgato/switch.py index 3b2420b0ace..1b24f621807 100644 --- a/homeassistant/components/elgato/switch.py +++ b/homeassistant/components/elgato/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElgatoConfigEntry, ElgatoData, ElgatoDataUpdateCoordinator from .entity import ElgatoEntity @@ -54,7 +54,7 @@ SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: ElgatoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Elgato switches based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/elkm1/alarm_control_panel.py b/homeassistant/components/elkm1/alarm_control_panel.py index ab51b6fe281..8113a4d99a6 100644 --- a/homeassistant/components/elkm1/alarm_control_panel.py +++ b/homeassistant/components/elkm1/alarm_control_panel.py @@ -20,7 +20,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import VolDictType @@ -55,7 +55,7 @@ SERVICE_ALARM_CLEAR_BYPASS = "alarm_clear_bypass" async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ElkM1 alarm platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/binary_sensor.py b/homeassistant/components/elkm1/binary_sensor.py index 73f6b925e8c..ba6a375c29b 100644 --- a/homeassistant/components/elkm1/binary_sensor.py +++ b/homeassistant/components/elkm1/binary_sensor.py @@ -10,7 +10,7 @@ from elkm1_lib.zones import Zone from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElkM1ConfigEntry from .entity import ElkAttachedEntity, ElkEntity @@ -19,7 +19,7 @@ from .entity import ElkAttachedEntity, ElkEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 sensor platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/climate.py b/homeassistant/components/elkm1/climate.py index 1448acc6079..55af0cfa29c 100644 --- a/homeassistant/components/elkm1/climate.py +++ b/homeassistant/components/elkm1/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import PRECISION_WHOLE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from . import ElkM1ConfigEntry @@ -60,7 +60,7 @@ ELK_TO_HASS_FAN_MODES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 thermostat platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/light.py b/homeassistant/components/elkm1/light.py index c041c9c9d65..b5e2f0acacf 100644 --- a/homeassistant/components/elkm1/light.py +++ b/homeassistant/components/elkm1/light.py @@ -10,7 +10,7 @@ from elkm1_lib.lights import Light from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElkM1ConfigEntry from .entity import ElkEntity, create_elk_entities @@ -20,7 +20,7 @@ from .models import ELKM1Data async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Elk light platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/scene.py b/homeassistant/components/elkm1/scene.py index d8a1d83f326..5da240aee2d 100644 --- a/homeassistant/components/elkm1/scene.py +++ b/homeassistant/components/elkm1/scene.py @@ -8,7 +8,7 @@ from elkm1_lib.tasks import Task from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElkM1ConfigEntry from .entity import ElkAttachedEntity, ElkEntity, create_elk_entities @@ -17,7 +17,7 @@ from .entity import ElkAttachedEntity, ElkEntity, create_elk_entities async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 scene platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/sensor.py b/homeassistant/components/elkm1/sensor.py index 2ca932ec134..328672edbed 100644 --- a/homeassistant/components/elkm1/sensor.py +++ b/homeassistant/components/elkm1/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import EntityCategory, UnitOfElectricPotential from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import ElkM1ConfigEntry @@ -40,7 +40,7 @@ ELK_SET_COUNTER_SERVICE_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 sensor platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elkm1/switch.py b/homeassistant/components/elkm1/switch.py index 3e0f4849518..d91d65512a2 100644 --- a/homeassistant/components/elkm1/switch.py +++ b/homeassistant/components/elkm1/switch.py @@ -12,7 +12,7 @@ from elkm1_lib.thermostats import Thermostat from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ElkM1ConfigEntry from .entity import ElkAttachedEntity, ElkEntity, create_elk_entities @@ -22,7 +22,7 @@ from .models import ELKM1Data async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 switch platform.""" elk_data = config_entry.runtime_data diff --git a/homeassistant/components/elmax/alarm_control_panel.py b/homeassistant/components/elmax/alarm_control_panel.py index 139c9080c15..a90c8f2652c 100644 --- a/homeassistant/components/elmax/alarm_control_panel.py +++ b/homeassistant/components/elmax/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError, InvalidStateError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ElmaxConfigEntry @@ -25,7 +25,7 @@ from .entity import ElmaxEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ElmaxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Elmax area platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/elmax/binary_sensor.py b/homeassistant/components/elmax/binary_sensor.py index 351c386a084..d9ec3e75901 100644 --- a/homeassistant/components/elmax/binary_sensor.py +++ b/homeassistant/components/elmax/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElmaxConfigEntry from .entity import ElmaxEntity @@ -18,7 +18,7 @@ from .entity import ElmaxEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ElmaxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Elmax sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/elmax/cover.py b/homeassistant/components/elmax/cover.py index e98477fe496..6993d5e44be 100644 --- a/homeassistant/components/elmax/cover.py +++ b/homeassistant/components/elmax/cover.py @@ -10,7 +10,7 @@ from elmax_api.model.cover_status import CoverStatus from homeassistant.components.cover import CoverEntity, CoverEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElmaxConfigEntry from .entity import ElmaxEntity @@ -27,7 +27,7 @@ _COMMAND_BY_MOTION_STATUS = { # Maps the stop command to use for every cover mo async def async_setup_entry( hass: HomeAssistant, config_entry: ElmaxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Elmax cover platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/elmax/switch.py b/homeassistant/components/elmax/switch.py index 70faa44cf01..28a97fefd91 100644 --- a/homeassistant/components/elmax/switch.py +++ b/homeassistant/components/elmax/switch.py @@ -9,7 +9,7 @@ from elmax_api.model.panel import PanelStatus from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ElmaxConfigEntry from .entity import ElmaxEntity @@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ElmaxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Elmax switch platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/emoncms/sensor.py b/homeassistant/components/emoncms/sensor.py index e3483d3f5d7..6321ccfafcd 100644 --- a/homeassistant/components/emoncms/sensor.py +++ b/homeassistant/components/emoncms/sensor.py @@ -39,7 +39,10 @@ from homeassistant.const import ( from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback from homeassistant.data_entry_flow import FlowResultType from homeassistant.helpers import config_validation as cv, template -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -289,7 +292,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: EmonCMSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the emoncms sensors.""" name = sensor_name(entry.data[CONF_URL]) diff --git a/homeassistant/components/emonitor/sensor.py b/homeassistant/components/emonitor/sensor.py index 39ed61741ae..be9e2ecb4cc 100644 --- a/homeassistant/components/emonitor/sensor.py +++ b/homeassistant/components/emonitor/sensor.py @@ -14,7 +14,7 @@ from homeassistant.const import UnitOfPower from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -38,7 +38,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EmonitorConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/energenie_power_sockets/switch.py b/homeassistant/components/energenie_power_sockets/switch.py index e4fb7653e5e..825566887bc 100644 --- a/homeassistant/components/energenie_power_sockets/switch.py +++ b/homeassistant/components/energenie_power_sockets/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EnergenieConfigEntry from .const import DOMAIN @@ -19,7 +19,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: EnergenieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add EGPS sockets for passed config_entry in HA.""" powerstrip = config_entry.runtime_data diff --git a/homeassistant/components/energyzero/sensor.py b/homeassistant/components/energyzero/sensor.py index 141ac793fba..38349b89ff7 100644 --- a/homeassistant/components/energyzero/sensor.py +++ b/homeassistant/components/energyzero/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, SERVICE_TYPE_DEVICE_NAMES @@ -147,7 +147,7 @@ def get_gas_price(data: EnergyZeroData, hours: int) -> float | None: async def async_setup_entry( hass: HomeAssistant, entry: EnergyZeroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EnergyZero Sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/enigma2/media_player.py b/homeassistant/components/enigma2/media_player.py index 9a2a4564d1c..a3cdd1858ed 100644 --- a/homeassistant/components/enigma2/media_player.py +++ b/homeassistant/components/enigma2/media_player.py @@ -15,7 +15,7 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import Enigma2ConfigEntry, Enigma2UpdateCoordinator @@ -31,7 +31,7 @@ _LOGGER = getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: Enigma2ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Enigma2 media player platform.""" async_add_entities([Enigma2Device(entry.runtime_data)]) diff --git a/homeassistant/components/enphase_envoy/binary_sensor.py b/homeassistant/components/enphase_envoy/binary_sensor.py index 0258281661a..dcffef8271b 100644 --- a/homeassistant/components/enphase_envoy/binary_sensor.py +++ b/homeassistant/components/enphase_envoy/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import EnphaseConfigEntry, EnphaseUpdateCoordinator @@ -75,7 +75,7 @@ ENPOWER_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EnphaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up envoy binary sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/enphase_envoy/number.py b/homeassistant/components/enphase_envoy/number.py index a62913a4c0b..a88c282281b 100644 --- a/homeassistant/components/enphase_envoy/number.py +++ b/homeassistant/components/enphase_envoy/number.py @@ -19,7 +19,7 @@ from homeassistant.components.number import ( from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import EnphaseConfigEntry, EnphaseUpdateCoordinator @@ -73,7 +73,7 @@ STORAGE_RESERVE_SOC_ENTITY = EnvoyStorageSettingsNumberEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: EnphaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Enphase Envoy number platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/enphase_envoy/select.py b/homeassistant/components/enphase_envoy/select.py index 7dc275aab37..546470a19d5 100644 --- a/homeassistant/components/enphase_envoy/select.py +++ b/homeassistant/components/enphase_envoy/select.py @@ -14,7 +14,7 @@ from pyenphase.models.tariff import EnvoyStorageMode, EnvoyStorageSettings from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import EnphaseConfigEntry, EnphaseUpdateCoordinator @@ -130,7 +130,7 @@ STORAGE_MODE_ENTITY = EnvoyStorageSettingsSelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: EnphaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Enphase Envoy select platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/enphase_envoy/sensor.py b/homeassistant/components/enphase_envoy/sensor.py index dcf062a5417..594f5f34088 100644 --- a/homeassistant/components/enphase_envoy/sensor.py +++ b/homeassistant/components/enphase_envoy/sensor.py @@ -49,7 +49,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -806,7 +806,7 @@ AGGREGATE_BATTERY_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: EnphaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up envoy sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/enphase_envoy/switch.py b/homeassistant/components/enphase_envoy/switch.py index 8a3ca493562..bb4ed874b1d 100644 --- a/homeassistant/components/enphase_envoy/switch.py +++ b/homeassistant/components/enphase_envoy/switch.py @@ -14,7 +14,7 @@ from pyenphase.models.tariff import EnvoyStorageSettings from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import EnphaseConfigEntry, EnphaseUpdateCoordinator @@ -78,7 +78,7 @@ CHARGE_FROM_GRID_SWITCH = EnvoyStorageSettingsSwitchEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: EnphaseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Enphase Envoy switch platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/environment_canada/camera.py b/homeassistant/components/environment_canada/camera.py index 3ba059e2206..b051c572816 100644 --- a/homeassistant/components/environment_canada/camera.py +++ b/homeassistant/components/environment_canada/camera.py @@ -8,7 +8,7 @@ import voluptuous as vol from homeassistant.components.camera import Camera from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.typing import VolDictType @@ -26,7 +26,7 @@ SET_RADAR_TYPE_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ECConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" coordinator = config_entry.runtime_data.radar_coordinator diff --git a/homeassistant/components/environment_canada/sensor.py b/homeassistant/components/environment_canada/sensor.py index 989667fb1ac..93f3a0f0d80 100644 --- a/homeassistant/components/environment_canada/sensor.py +++ b/homeassistant/components/environment_canada/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTR_STATION @@ -253,7 +253,7 @@ ALERT_TYPES: tuple[ECSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ECConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" weather_coordinator = config_entry.runtime_data.weather_coordinator diff --git a/homeassistant/components/environment_canada/weather.py b/homeassistant/components/environment_canada/weather.py index 156b9f4152b..c7e51a32f68 100644 --- a/homeassistant/components/environment_canada/weather.py +++ b/homeassistant/components/environment_canada/weather.py @@ -37,7 +37,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ECConfigEntry, ECDataUpdateCoordinator @@ -63,7 +63,7 @@ ICON_CONDITION_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ECConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" entity_registry = er.async_get(hass) diff --git a/homeassistant/components/epic_games_store/calendar.py b/homeassistant/components/epic_games_store/calendar.py index 5df1d6b756d..41edb5e31a7 100644 --- a/homeassistant/components/epic_games_store/calendar.py +++ b/homeassistant/components/epic_games_store/calendar.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, CalendarType @@ -21,7 +21,7 @@ DateRange = namedtuple("DateRange", ["start", "end"]) # noqa: PYI024 async def async_setup_entry( hass: HomeAssistant, entry: EGSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the local calendar platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/epion/sensor.py b/homeassistant/components/epion/sensor.py index 78027813ffa..360c1f1d8a7 100644 --- a/homeassistant/components/epion/sensor.py +++ b/homeassistant/components/epion/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -59,7 +59,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: EpionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add an Epion entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/epson/media_player.py b/homeassistant/components/epson/media_player.py index e0eac4a1cfb..c1582d6f0e5 100644 --- a/homeassistant/components/epson/media_player.py +++ b/homeassistant/components/epson/media_player.py @@ -43,7 +43,7 @@ from homeassistant.helpers import ( entity_registry as er, ) from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import EpsonConfigEntry from .const import ATTR_CMODE, DOMAIN, SERVICE_SELECT_CMODE @@ -54,7 +54,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: EpsonConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Epson projector from a config entry.""" projector_entity = EpsonProjectorMediaPlayer( diff --git a/homeassistant/components/eq3btsmart/binary_sensor.py b/homeassistant/components/eq3btsmart/binary_sensor.py index 27525d47972..55b1f4d6ced 100644 --- a/homeassistant/components/eq3btsmart/binary_sensor.py +++ b/homeassistant/components/eq3btsmart/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Eq3ConfigEntry from .const import ENTITY_KEY_BATTERY, ENTITY_KEY_DST, ENTITY_KEY_WINDOW @@ -51,7 +51,7 @@ BINARY_SENSOR_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: Eq3ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the entry.""" diff --git a/homeassistant/components/eq3btsmart/climate.py b/homeassistant/components/eq3btsmart/climate.py index ae01d0fc9a7..738efa99187 100644 --- a/homeassistant/components/eq3btsmart/climate.py +++ b/homeassistant/components/eq3btsmart/climate.py @@ -19,7 +19,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Eq3ConfigEntry from .const import ( @@ -37,7 +37,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: Eq3ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Handle config entry setup.""" diff --git a/homeassistant/components/eq3btsmart/number.py b/homeassistant/components/eq3btsmart/number.py index 2e069180fa3..c3cbd8eae31 100644 --- a/homeassistant/components/eq3btsmart/number.py +++ b/homeassistant/components/eq3btsmart/number.py @@ -21,7 +21,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Eq3ConfigEntry from .const import ( @@ -109,7 +109,7 @@ NUMBER_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: Eq3ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the entry.""" diff --git a/homeassistant/components/eq3btsmart/sensor.py b/homeassistant/components/eq3btsmart/sensor.py index bd2605042f4..aab3cbf1925 100644 --- a/homeassistant/components/eq3btsmart/sensor.py +++ b/homeassistant/components/eq3btsmart/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.components.sensor.const import SensorStateClass from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Eq3ConfigEntry from .const import ENTITY_KEY_AWAY_UNTIL, ENTITY_KEY_VALVE @@ -51,7 +51,7 @@ SENSOR_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: Eq3ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the entry.""" diff --git a/homeassistant/components/eq3btsmart/switch.py b/homeassistant/components/eq3btsmart/switch.py index 7525d8ca494..61da133cb71 100644 --- a/homeassistant/components/eq3btsmart/switch.py +++ b/homeassistant/components/eq3btsmart/switch.py @@ -9,7 +9,7 @@ from eq3btsmart.models import Status from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Eq3ConfigEntry from .const import ENTITY_KEY_AWAY, ENTITY_KEY_BOOST, ENTITY_KEY_LOCK @@ -49,7 +49,7 @@ SWITCH_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: Eq3ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the entry.""" diff --git a/homeassistant/components/escea/climate.py b/homeassistant/components/escea/climate.py index c3fb0015e68..a1ac83844a2 100644 --- a/homeassistant/components/escea/climate.py +++ b/homeassistant/components/escea/climate.py @@ -21,7 +21,7 @@ from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTempera from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DATA_DISCOVERY_SERVICE, @@ -47,7 +47,7 @@ _HA_FAN_TO_ESCEA = {v: k for k, v in _ESCEA_FAN_TO_HA.items()} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize an Escea Controller.""" discovery_service = hass.data[DATA_DISCOVERY_SERVICE] diff --git a/homeassistant/components/esphome/assist_satellite.py b/homeassistant/components/esphome/assist_satellite.py index f60668b0a06..016b1c3494d 100644 --- a/homeassistant/components/esphome/assist_satellite.py +++ b/homeassistant/components/esphome/assist_satellite.py @@ -39,7 +39,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import EsphomeAssistEntity @@ -87,7 +87,7 @@ _CONFIG_TIMEOUT_SEC = 5 async def async_setup_entry( hass: HomeAssistant, entry: ESPHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Assist satellite entity.""" entry_data = entry.runtime_data diff --git a/homeassistant/components/esphome/binary_sensor.py b/homeassistant/components/esphome/binary_sensor.py index ac759aa7b17..02b13748fb6 100644 --- a/homeassistant/components/esphome/binary_sensor.py +++ b/homeassistant/components/esphome/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import issue_registry as ir -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from .const import DOMAIN @@ -24,7 +24,7 @@ from .entry_data import ESPHomeConfigEntry async def async_setup_entry( hass: HomeAssistant, entry: ESPHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ESPHome binary sensors based on a config entry.""" await platform_async_setup_entry( diff --git a/homeassistant/components/esphome/select.py b/homeassistant/components/esphome/select.py index 71a21186d3d..67bcbbbd221 100644 --- a/homeassistant/components/esphome/select.py +++ b/homeassistant/components/esphome/select.py @@ -13,7 +13,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import restore_state -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import ( @@ -29,7 +29,7 @@ from .entry_data import ESPHomeConfigEntry, RuntimeEntryData async def async_setup_entry( hass: HomeAssistant, entry: ESPHomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up esphome selects based on a config entry.""" await platform_async_setup_entry( diff --git a/homeassistant/components/esphome/sensor.py b/homeassistant/components/esphome/sensor.py index 670c92d291e..26f33f4fb47 100644 --- a/homeassistant/components/esphome/sensor.py +++ b/homeassistant/components/esphome/sensor.py @@ -22,7 +22,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from homeassistant.util.enum import try_parse_enum @@ -31,7 +31,9 @@ from .enum_mapper import EsphomeEnumMapper async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up esphome sensors based on a config entry.""" await platform_async_setup_entry( diff --git a/homeassistant/components/esphome/update.py b/homeassistant/components/esphome/update.py index 2b593051742..60d4989063b 100644 --- a/homeassistant/components/esphome/update.py +++ b/homeassistant/components/esphome/update.py @@ -23,7 +23,7 @@ from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.enum import try_parse_enum @@ -46,7 +46,7 @@ NO_FEATURES = UpdateEntityFeature(0) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ESPHome update based on a config entry.""" await platform_async_setup_entry( diff --git a/homeassistant/components/eufylife_ble/sensor.py b/homeassistant/components/eufylife_ble/sensor.py index d9cef45ce4d..0c65be89879 100644 --- a/homeassistant/components/eufylife_ble/sensor.py +++ b/homeassistant/components/eufylife_ble/sensor.py @@ -16,7 +16,7 @@ from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, UnitOfMass from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM from .models import EufyLifeConfigEntry, EufyLifeData @@ -27,7 +27,7 @@ IGNORED_STATES = {STATE_UNAVAILABLE, STATE_UNKNOWN} async def async_setup_entry( hass: HomeAssistant, entry: EufyLifeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the EufyLife sensors.""" data = entry.runtime_data diff --git a/homeassistant/components/evil_genius_labs/light.py b/homeassistant/components/evil_genius_labs/light.py index a6d1d9531b5..3dd9b763ae1 100644 --- a/homeassistant/components/evil_genius_labs/light.py +++ b/homeassistant/components/evil_genius_labs/light.py @@ -8,7 +8,7 @@ from typing import Any, cast from homeassistant.components import light from homeassistant.components.light import ColorMode, LightEntity, LightEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EvilGeniusConfigEntry, EvilGeniusUpdateCoordinator from .entity import EvilGeniusEntity @@ -21,7 +21,7 @@ FIB_NO_EFFECT = "Solid Color" async def async_setup_entry( hass: HomeAssistant, config_entry: EvilGeniusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Evil Genius light platform.""" async_add_entities([EvilGeniusLight(config_entry.runtime_data)]) diff --git a/homeassistant/components/ezviz/alarm_control_panel.py b/homeassistant/components/ezviz/alarm_control_panel.py index 66a76df2cdc..08fa0a68ee8 100644 --- a/homeassistant/components/ezviz/alarm_control_panel.py +++ b/homeassistant/components/ezviz/alarm_control_panel.py @@ -18,7 +18,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, MANUFACTURER from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator @@ -50,7 +50,7 @@ ALARM_TYPE = EzvizAlarmControlPanelEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ezviz alarm control panel.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/binary_sensor.py b/homeassistant/components/ezviz/binary_sensor.py index 6f0d87c8218..5e069e0277a 100644 --- a/homeassistant/components/ezviz/binary_sensor.py +++ b/homeassistant/components/ezviz/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -34,7 +34,7 @@ BINARY_SENSOR_TYPES: dict[str, BinarySensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/button.py b/homeassistant/components/ezviz/button.py index b99674b0693..6dbb419c903 100644 --- a/homeassistant/components/ezviz/button.py +++ b/homeassistant/components/ezviz/button.py @@ -13,7 +13,7 @@ from pyezviz.exceptions import HTTPError, PyEzvizError from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -68,7 +68,7 @@ BUTTON_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ button based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/camera.py b/homeassistant/components/ezviz/camera.py index d96fc949c86..54879fd6a9b 100644 --- a/homeassistant/components/ezviz/camera.py +++ b/homeassistant/components/ezviz/camera.py @@ -15,7 +15,7 @@ from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.helpers import discovery_flow from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -36,7 +36,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ cameras based on a config entry.""" diff --git a/homeassistant/components/ezviz/image.py b/homeassistant/components/ezviz/image.py index d4c7a267b1e..f335406a367 100644 --- a/homeassistant/components/ezviz/image.py +++ b/homeassistant/components/ezviz/image.py @@ -11,7 +11,7 @@ from homeassistant.components.image import Image, ImageEntity, ImageEntityDescri from homeassistant.config_entries import SOURCE_IGNORE from homeassistant.const import CONF_PASSWORD from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -29,7 +29,7 @@ IMAGE_TYPE = ImageEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ image entities based on a config entry.""" diff --git a/homeassistant/components/ezviz/light.py b/homeassistant/components/ezviz/light.py index 145c8b1ca20..ba398dd3ed4 100644 --- a/homeassistant/components/ezviz/light.py +++ b/homeassistant/components/ezviz/light.py @@ -10,7 +10,7 @@ from pyezviz.exceptions import HTTPError, PyEzvizError from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -26,7 +26,7 @@ BRIGHTNESS_RANGE = (1, 255) async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ lights based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/number.py b/homeassistant/components/ezviz/number.py index 9e8a20f36dd..9bdd1feb81d 100644 --- a/homeassistant/components/ezviz/number.py +++ b/homeassistant/components/ezviz/number.py @@ -19,7 +19,7 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizBaseEntity @@ -51,7 +51,7 @@ NUMBER_TYPE = EzvizNumberEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/select.py b/homeassistant/components/ezviz/select.py index 8e037fe6c33..486564bff6e 100644 --- a/homeassistant/components/ezviz/select.py +++ b/homeassistant/components/ezviz/select.py @@ -11,7 +11,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -38,7 +38,7 @@ SELECT_TYPE = EzvizSelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ select entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/sensor.py b/homeassistant/components/ezviz/sensor.py index f3d50836bc7..c441b34b42d 100644 --- a/homeassistant/components/ezviz/sensor.py +++ b/homeassistant/components/ezviz/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -72,7 +72,7 @@ SENSOR_TYPES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/siren.py b/homeassistant/components/ezviz/siren.py index 5a612aa0772..a2c88f58972 100644 --- a/homeassistant/components/ezviz/siren.py +++ b/homeassistant/components/ezviz/siren.py @@ -17,7 +17,7 @@ from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import event as evt -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator @@ -35,7 +35,7 @@ SIREN_ENTITY_TYPE = SirenEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/switch.py b/homeassistant/components/ezviz/switch.py index 1a347c931a6..01f7cac1a55 100644 --- a/homeassistant/components/ezviz/switch.py +++ b/homeassistant/components/ezviz/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -107,7 +107,7 @@ SWITCH_TYPES: dict[int, EzvizSwitchEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ switch based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ezviz/update.py b/homeassistant/components/ezviz/update.py index 3027e048688..c9f8038b336 100644 --- a/homeassistant/components/ezviz/update.py +++ b/homeassistant/components/ezviz/update.py @@ -14,7 +14,7 @@ from homeassistant.components.update import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import EzvizConfigEntry, EzvizDataUpdateCoordinator from .entity import EzvizEntity @@ -30,7 +30,7 @@ UPDATE_ENTITY_TYPES = UpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: EzvizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up EZVIZ sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/faa_delays/binary_sensor.py b/homeassistant/components/faa_delays/binary_sensor.py index 0fbc028f111..6822e2620fd 100644 --- a/homeassistant/components/faa_delays/binary_sensor.py +++ b/homeassistant/components/faa_delays/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import FAAConfigEntry, FAADataUpdateCoordinator @@ -83,7 +83,9 @@ FAA_BINARY_SENSORS: tuple[FaaDelaysBinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: FAAConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: FAAConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a FAA sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fastdotcom/sensor.py b/homeassistant/components/fastdotcom/sensor.py index b633cb25628..5b6429b0754 100644 --- a/homeassistant/components/fastdotcom/sensor.py +++ b/homeassistant/components/fastdotcom/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfDataRate from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -20,7 +20,7 @@ from .coordinator import FastdotcomConfigEntry, FastdotcomDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: FastdotcomConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fast.com sensor.""" async_add_entities([SpeedtestSensor(entry.entry_id, entry.runtime_data)]) diff --git a/homeassistant/components/feedreader/event.py b/homeassistant/components/feedreader/event.py index ad6aed0fc76..578b5b1e175 100644 --- a/homeassistant/components/feedreader/event.py +++ b/homeassistant/components/feedreader/event.py @@ -10,7 +10,7 @@ from feedparser import FeedParserDict from homeassistant.components.event import EventEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import FeedReaderConfigEntry @@ -28,7 +28,7 @@ ATTR_TITLE = "title" async def async_setup_entry( hass: HomeAssistant, entry: FeedReaderConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up event entities for feedreader.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fibaro/binary_sensor.py b/homeassistant/components/fibaro/binary_sensor.py index 16e79c0c1d0..14c8f03f3ec 100644 --- a/homeassistant/components/fibaro/binary_sensor.py +++ b/homeassistant/components/fibaro/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -42,7 +42,7 @@ SENSOR_TYPES = { async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Fibaro controller devices.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/climate.py b/homeassistant/components/fibaro/climate.py index 45f700026a0..d601450a70f 100644 --- a/homeassistant/components/fibaro/climate.py +++ b/homeassistant/components/fibaro/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -110,7 +110,7 @@ OP_MODE_ACTIONS = ("setMode", "setOperatingMode", "setThermostatMode") async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Fibaro controller devices.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/cover.py b/homeassistant/components/fibaro/cover.py index bfebbf87bd2..0008b56345e 100644 --- a/homeassistant/components/fibaro/cover.py +++ b/homeassistant/components/fibaro/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -24,7 +24,7 @@ from .entity import FibaroEntity async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fibaro covers.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/event.py b/homeassistant/components/fibaro/event.py index a2d5da7f877..0beea2e336e 100644 --- a/homeassistant/components/fibaro/event.py +++ b/homeassistant/components/fibaro/event.py @@ -12,7 +12,7 @@ from homeassistant.components.event import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -21,7 +21,7 @@ from .entity import FibaroEntity async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fibaro event entities.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/light.py b/homeassistant/components/fibaro/light.py index d40e26244f3..446b9b9f7ff 100644 --- a/homeassistant/components/fibaro/light.py +++ b/homeassistant/components/fibaro/light.py @@ -19,7 +19,7 @@ from homeassistant.components.light import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -51,7 +51,7 @@ def scaleto99(value: int | None) -> int: async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Fibaro controller devices.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/lock.py b/homeassistant/components/fibaro/lock.py index 62a9dfa43b1..a1e76109e2d 100644 --- a/homeassistant/components/fibaro/lock.py +++ b/homeassistant/components/fibaro/lock.py @@ -9,7 +9,7 @@ from pyfibaro.fibaro_device import DeviceModel from homeassistant.components.lock import ENTITY_ID_FORMAT, LockEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -18,7 +18,7 @@ from .entity import FibaroEntity async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fibaro locks.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/scene.py b/homeassistant/components/fibaro/scene.py index a4c0f1bd7f1..8a594506f27 100644 --- a/homeassistant/components/fibaro/scene.py +++ b/homeassistant/components/fibaro/scene.py @@ -9,7 +9,7 @@ from pyfibaro.fibaro_scene import SceneModel from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from . import FibaroConfigEntry, FibaroController @@ -19,7 +19,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Fibaro scenes.""" controller = entry.runtime_data diff --git a/homeassistant/components/fibaro/sensor.py b/homeassistant/components/fibaro/sensor.py index 245a0d087d8..9034bd7d05e 100644 --- a/homeassistant/components/fibaro/sensor.py +++ b/homeassistant/components/fibaro/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import convert from . import FibaroConfigEntry @@ -102,7 +102,7 @@ FIBARO_TO_HASS_UNIT: dict[str, str] = { async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fibaro controller devices.""" diff --git a/homeassistant/components/fibaro/switch.py b/homeassistant/components/fibaro/switch.py index f67683dff6a..8d77685c1e7 100644 --- a/homeassistant/components/fibaro/switch.py +++ b/homeassistant/components/fibaro/switch.py @@ -9,7 +9,7 @@ from pyfibaro.fibaro_device import DeviceModel from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FibaroConfigEntry from .entity import FibaroEntity @@ -18,7 +18,7 @@ from .entity import FibaroEntity async def async_setup_entry( hass: HomeAssistant, entry: FibaroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fibaro switches.""" controller = entry.runtime_data diff --git a/homeassistant/components/file/notify.py b/homeassistant/components/file/notify.py index 3d61dbb04e0..90af1677bce 100644 --- a/homeassistant/components/file/notify.py +++ b/homeassistant/components/file/notify.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_FILE_PATH, CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import CONF_TIMESTAMP, DEFAULT_NAME, DOMAIN, FILE_ICON @@ -23,7 +23,7 @@ from .const import CONF_TIMESTAMP, DEFAULT_NAME, DOMAIN, FILE_ICON async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up notify entity.""" unique_id = entry.entry_id diff --git a/homeassistant/components/file/sensor.py b/homeassistant/components/file/sensor.py index 879c06e29f3..b8d174afe2c 100644 --- a/homeassistant/components/file/sensor.py +++ b/homeassistant/components/file/sensor.py @@ -16,7 +16,7 @@ from homeassistant.const import ( CONF_VALUE_TEMPLATE, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.template import Template from .const import DEFAULT_NAME, FILE_ICON @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the file sensor.""" config = dict(entry.data) diff --git a/homeassistant/components/filesize/sensor.py b/homeassistant/components/filesize/sensor.py index bd8b9b6c462..966e253660d 100644 --- a/homeassistant/components/filesize/sensor.py +++ b/homeassistant/components/filesize/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import EntityCategory, UnitOfInformation from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -59,7 +59,7 @@ SENSOR_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: FileSizeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config entry.""" async_add_entities( diff --git a/homeassistant/components/filter/sensor.py b/homeassistant/components/filter/sensor.py index 330e61f499e..eb1337002e4 100644 --- a/homeassistant/components/filter/sensor.py +++ b/homeassistant/components/filter/sensor.py @@ -44,7 +44,10 @@ from homeassistant.core import ( callback, ) from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.start import async_at_started @@ -201,7 +204,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Filter sensor entry.""" name: str = entry.options[CONF_NAME] diff --git a/homeassistant/components/fireservicerota/binary_sensor.py b/homeassistant/components/fireservicerota/binary_sensor.py index b6d3aa67a0a..b8a542cf37c 100644 --- a/homeassistant/components/fireservicerota/binary_sensor.py +++ b/homeassistant/components/fireservicerota/binary_sensor.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DATA_CLIENT, DATA_COORDINATOR, DOMAIN as FIRESERVICEROTA_DOMAIN @@ -15,7 +15,9 @@ from .coordinator import FireServiceRotaClient, FireServiceUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up FireServiceRota binary sensor based on a config entry.""" diff --git a/homeassistant/components/fireservicerota/sensor.py b/homeassistant/components/fireservicerota/sensor.py index b09d1295025..682c7bcc0fd 100644 --- a/homeassistant/components/fireservicerota/sensor.py +++ b/homeassistant/components/fireservicerota/sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import DATA_CLIENT, DOMAIN as FIRESERVICEROTA_DOMAIN @@ -17,7 +17,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up FireServiceRota sensor based on a config entry.""" client = hass.data[FIRESERVICEROTA_DOMAIN][entry.entry_id][DATA_CLIENT] diff --git a/homeassistant/components/fireservicerota/switch.py b/homeassistant/components/fireservicerota/switch.py index affd46c91bd..602a02a8e4a 100644 --- a/homeassistant/components/fireservicerota/switch.py +++ b/homeassistant/components/fireservicerota/switch.py @@ -7,7 +7,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DATA_COORDINATOR, DOMAIN as FIRESERVICEROTA_DOMAIN from .coordinator import FireServiceRotaClient, FireServiceUpdateCoordinator @@ -16,7 +16,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up FireServiceRota switch based on a config entry.""" client = hass.data[FIRESERVICEROTA_DOMAIN][entry.entry_id][DATA_CLIENT] diff --git a/homeassistant/components/firmata/binary_sensor.py b/homeassistant/components/firmata/binary_sensor.py index 4973afa6960..de79f676ae6 100644 --- a/homeassistant/components/firmata/binary_sensor.py +++ b/homeassistant/components/firmata/binary_sensor.py @@ -5,7 +5,7 @@ import logging from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.const import CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FirmataConfigEntry from .const import CONF_NEGATE_STATE, CONF_PIN_MODE @@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: FirmataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Firmata binary sensors.""" new_entities = [] diff --git a/homeassistant/components/firmata/light.py b/homeassistant/components/firmata/light.py index 4f27143b774..f866ce9dbe5 100644 --- a/homeassistant/components/firmata/light.py +++ b/homeassistant/components/firmata/light.py @@ -9,7 +9,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_MAXIMUM, CONF_MINIMUM, CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FirmataConfigEntry from .board import FirmataPinType @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: FirmataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Firmata lights.""" new_entities = [] diff --git a/homeassistant/components/firmata/sensor.py b/homeassistant/components/firmata/sensor.py index 569d97fe1ec..7b49950e948 100644 --- a/homeassistant/components/firmata/sensor.py +++ b/homeassistant/components/firmata/sensor.py @@ -5,7 +5,7 @@ import logging from homeassistant.components.sensor import SensorEntity from homeassistant.const import CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FirmataConfigEntry from .const import CONF_DIFFERENTIAL, CONF_PIN_MODE @@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: FirmataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Firmata sensors.""" new_entities = [] diff --git a/homeassistant/components/firmata/switch.py b/homeassistant/components/firmata/switch.py index 33953b78974..e84b18e9c74 100644 --- a/homeassistant/components/firmata/switch.py +++ b/homeassistant/components/firmata/switch.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.const import CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FirmataConfigEntry from .const import CONF_INITIAL_STATE, CONF_NEGATE_STATE, CONF_PIN_MODE @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: FirmataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Firmata switches.""" new_entities = [] diff --git a/homeassistant/components/fitbit/sensor.py b/homeassistant/components/fitbit/sensor.py index bbb3da46e52..f5c8a81ca26 100644 --- a/homeassistant/components/fitbit/sensor.py +++ b/homeassistant/components/fitbit/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -524,7 +524,7 @@ FITBIT_RESOURCE_BATTERY_LEVEL = FitbitSensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: FitbitConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fitbit sensor platform.""" diff --git a/homeassistant/components/fivem/binary_sensor.py b/homeassistant/components/fivem/binary_sensor.py index 42119939d4a..92aab58349b 100644 --- a/homeassistant/components/fivem/binary_sensor.py +++ b/homeassistant/components/fivem/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NAME_STATUS from .coordinator import FiveMConfigEntry @@ -34,7 +34,7 @@ BINARY_SENSORS: tuple[FiveMBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FiveMConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FiveM binary sensor platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fivem/sensor.py b/homeassistant/components/fivem/sensor.py index 88290171756..c4f5856c636 100644 --- a/homeassistant/components/fivem/sensor.py +++ b/homeassistant/components/fivem/sensor.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -50,7 +50,7 @@ SENSORS: tuple[FiveMSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FiveMConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FiveM sensor platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fjaraskupan/__init__.py b/homeassistant/components/fjaraskupan/__init__.py index 2703fc5a30e..961be04fd8d 100644 --- a/homeassistant/components/fjaraskupan/__init__.py +++ b/homeassistant/components/fjaraskupan/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations from collections.abc import Callable -from dataclasses import dataclass import logging from fjaraskupan import Device @@ -16,7 +15,6 @@ from homeassistant.components.bluetooth import ( async_rediscover_address, async_register_callback, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr @@ -29,7 +27,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DISPATCH_DETECTION, DOMAIN -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator PLATFORMS = [ Platform.BINARY_SENSOR, @@ -42,26 +40,17 @@ PLATFORMS = [ _LOGGER = logging.getLogger(__name__) -@dataclass -class EntryState: - """Store state of config entry.""" - - coordinators: dict[str, FjaraskupanCoordinator] - - -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: FjaraskupanConfigEntry) -> bool: """Set up Fjäråskupan from a config entry.""" - state = EntryState({}) - hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN][entry.entry_id] = state + entry.runtime_data = {} def detection_callback( service_info: BluetoothServiceInfoBleak, change: BluetoothChange ) -> None: if change != BluetoothChange.ADVERTISEMENT: return - if data := state.coordinators.get(service_info.address): + if data := entry.runtime_data.get(service_info.address): _LOGGER.debug("Update: %s", service_info) data.detection_callback(service_info) else: @@ -80,7 +69,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) coordinator.detection_callback(service_info) - state.coordinators[service_info.address] = coordinator + entry.runtime_data[service_info.address] = coordinator async_dispatcher_send( hass, f"{DISPATCH_DETECTION}.{entry.entry_id}", coordinator ) @@ -105,16 +94,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @callback def async_setup_entry_platform( hass: HomeAssistant, - entry: ConfigEntry, + entry: FjaraskupanConfigEntry, async_add_entities: AddEntitiesCallback, constructor: Callable[[FjaraskupanCoordinator], list[Entity]], ) -> None: """Set up a platform with added entities.""" - entry_state: EntryState = hass.data[DOMAIN][entry.entry_id] async_add_entities( entity - for coordinator in entry_state.coordinators.values() + for coordinator in entry.runtime_data.values() for entity in constructor(coordinator) ) @@ -129,12 +117,12 @@ def async_setup_entry_platform( ) -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry( + hass: HomeAssistant, entry: FjaraskupanConfigEntry +) -> bool: """Unload a config entry.""" unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) - for device_entry in dr.async_entries_for_config_entry( dr.async_get(hass), entry.entry_id ): diff --git a/homeassistant/components/fjaraskupan/binary_sensor.py b/homeassistant/components/fjaraskupan/binary_sensor.py index 93886a2ac6a..7364fa85b2e 100644 --- a/homeassistant/components/fjaraskupan/binary_sensor.py +++ b/homeassistant/components/fjaraskupan/binary_sensor.py @@ -12,15 +12,14 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import async_setup_entry_platform -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator @dataclass(frozen=True) @@ -48,8 +47,8 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FjaraskupanConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors dynamically through discovery.""" diff --git a/homeassistant/components/fjaraskupan/coordinator.py b/homeassistant/components/fjaraskupan/coordinator.py index bfea5e5f4fc..7fc4585a722 100644 --- a/homeassistant/components/fjaraskupan/coordinator.py +++ b/homeassistant/components/fjaraskupan/coordinator.py @@ -29,6 +29,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN +type FjaraskupanConfigEntry = ConfigEntry[dict[str, FjaraskupanCoordinator]] + _LOGGER = logging.getLogger(__name__) @@ -65,12 +67,12 @@ class UnableToConnect(HomeAssistantError): class FjaraskupanCoordinator(DataUpdateCoordinator[State]): """Update coordinator for each device.""" - config_entry: ConfigEntry + config_entry: FjaraskupanConfigEntry def __init__( self, hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: FjaraskupanConfigEntry, device: Device, device_info: DeviceInfo, ) -> None: diff --git a/homeassistant/components/fjaraskupan/fan.py b/homeassistant/components/fjaraskupan/fan.py index 540a7dd410d..b35bb728131 100644 --- a/homeassistant/components/fjaraskupan/fan.py +++ b/homeassistant/components/fjaraskupan/fan.py @@ -13,11 +13,10 @@ from fjaraskupan import ( ) from homeassistant.components.fan import FanEntity, FanEntityFeature -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.percentage import ( ordered_list_item_to_percentage, @@ -25,7 +24,7 @@ from homeassistant.util.percentage import ( ) from . import async_setup_entry_platform -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator ORDERED_NAMED_FAN_SPEEDS = ["1", "2", "3", "4", "5", "6", "7", "8"] @@ -51,8 +50,8 @@ class UnsupportedPreset(HomeAssistantError): async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FjaraskupanConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors dynamically through discovery.""" diff --git a/homeassistant/components/fjaraskupan/light.py b/homeassistant/components/fjaraskupan/light.py index f0083591d4d..c39e3ca4736 100644 --- a/homeassistant/components/fjaraskupan/light.py +++ b/homeassistant/components/fjaraskupan/light.py @@ -5,21 +5,20 @@ from __future__ import annotations from typing import Any from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import async_setup_entry_platform -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FjaraskupanConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tuya sensors dynamically through tuya discovery.""" diff --git a/homeassistant/components/fjaraskupan/number.py b/homeassistant/components/fjaraskupan/number.py index 1828c4cdea5..93fd31273e9 100644 --- a/homeassistant/components/fjaraskupan/number.py +++ b/homeassistant/components/fjaraskupan/number.py @@ -3,22 +3,21 @@ from __future__ import annotations from homeassistant.components.number import NumberEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import async_setup_entry_platform -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FjaraskupanConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities dynamically through discovery.""" diff --git a/homeassistant/components/fjaraskupan/sensor.py b/homeassistant/components/fjaraskupan/sensor.py index 36db4d7ed9f..039feb5913c 100644 --- a/homeassistant/components/fjaraskupan/sensor.py +++ b/homeassistant/components/fjaraskupan/sensor.py @@ -9,23 +9,22 @@ from homeassistant.components.sensor import ( SensorEntity, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import SIGNAL_STRENGTH_DECIBELS_MILLIWATT, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import async_setup_entry_platform -from .coordinator import FjaraskupanCoordinator +from .coordinator import FjaraskupanConfigEntry, FjaraskupanCoordinator async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FjaraskupanConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors dynamically through discovery.""" diff --git a/homeassistant/components/flexit_bacnet/__init__.py b/homeassistant/components/flexit_bacnet/__init__.py index b0ebc5a40fd..01e0051f53f 100644 --- a/homeassistant/components/flexit_bacnet/__init__.py +++ b/homeassistant/components/flexit_bacnet/__init__.py @@ -2,12 +2,10 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from .const import DOMAIN -from .coordinator import FlexitCoordinator +from .coordinator import FlexitConfigEntry, FlexitCoordinator PLATFORMS: list[Platform] = [ Platform.BINARY_SENSOR, @@ -18,21 +16,18 @@ PLATFORMS: list[Platform] = [ ] -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: FlexitConfigEntry) -> bool: """Set up Flexit Nordic (BACnet) from a config entry.""" coordinator = FlexitCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator + entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: FlexitConfigEntry) -> bool: """Unload the Flexit Nordic (BACnet) config entry.""" - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/flexit_bacnet/binary_sensor.py b/homeassistant/components/flexit_bacnet/binary_sensor.py index 901cc52de47..faee803e915 100644 --- a/homeassistant/components/flexit_bacnet/binary_sensor.py +++ b/homeassistant/components/flexit_bacnet/binary_sensor.py @@ -10,12 +10,10 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FlexitCoordinator -from .const import DOMAIN +from .coordinator import FlexitConfigEntry, FlexitCoordinator from .entity import FlexitEntity @@ -38,11 +36,11 @@ SENSOR_TYPES: tuple[FlexitBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FlexitConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Flexit (bacnet) binary sensor from a config entry.""" - coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id] + coordinator = config_entry.runtime_data async_add_entities( FlexitBinarySensor(coordinator, description) for description in SENSOR_TYPES diff --git a/homeassistant/components/flexit_bacnet/climate.py b/homeassistant/components/flexit_bacnet/climate.py index a2291dea9d6..abfa59d0a6d 100644 --- a/homeassistant/components/flexit_bacnet/climate.py +++ b/homeassistant/components/flexit_bacnet/climate.py @@ -19,32 +19,28 @@ from homeassistant.components.climate import ( HVACAction, HVACMode, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( - DOMAIN, MAX_TEMP, MIN_TEMP, PRESET_TO_VENTILATION_MODE_MAP, VENTILATION_TO_PRESET_MODE_MAP, ) -from .coordinator import FlexitCoordinator +from .coordinator import FlexitConfigEntry, FlexitCoordinator from .entity import FlexitEntity async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FlexitConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flexit Nordic unit.""" - coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id] - - async_add_entities([FlexitClimateEntity(coordinator)]) + async_add_entities([FlexitClimateEntity(config_entry.runtime_data)]) class FlexitClimateEntity(FlexitEntity, ClimateEntity): diff --git a/homeassistant/components/flexit_bacnet/coordinator.py b/homeassistant/components/flexit_bacnet/coordinator.py index f723117c9ef..da9415f2b87 100644 --- a/homeassistant/components/flexit_bacnet/coordinator.py +++ b/homeassistant/components/flexit_bacnet/coordinator.py @@ -1,5 +1,7 @@ """DataUpdateCoordinator for Flexit Nordic (BACnet) integration..""" +from __future__ import annotations + import asyncio.exceptions from datetime import timedelta import logging @@ -17,13 +19,15 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) +type FlexitConfigEntry = ConfigEntry[FlexitCoordinator] + class FlexitCoordinator(DataUpdateCoordinator[FlexitBACnet]): """Class to manage fetching data from a Flexit Nordic (BACnet) device.""" - config_entry: ConfigEntry + config_entry: FlexitConfigEntry - def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: + def __init__(self, hass: HomeAssistant, config_entry: FlexitConfigEntry) -> None: """Initialize my coordinator.""" super().__init__( hass, diff --git a/homeassistant/components/flexit_bacnet/icons.json b/homeassistant/components/flexit_bacnet/icons.json index a0c5ccd5a6e..d03cffab9ad 100644 --- a/homeassistant/components/flexit_bacnet/icons.json +++ b/homeassistant/components/flexit_bacnet/icons.json @@ -47,6 +47,12 @@ "state": { "off": "mdi:fireplace-off" } + }, + "cooker_hood_mode": { + "default": "mdi:kettle-steam", + "state": { + "off": "mdi:kettle" + } } } } diff --git a/homeassistant/components/flexit_bacnet/number.py b/homeassistant/components/flexit_bacnet/number.py index 30df5370868..dfcfc193692 100644 --- a/homeassistant/components/flexit_bacnet/number.py +++ b/homeassistant/components/flexit_bacnet/number.py @@ -13,14 +13,12 @@ from homeassistant.components.number import ( NumberEntityDescription, NumberMode, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FlexitCoordinator -from .const import DOMAIN +from .coordinator import FlexitConfigEntry, FlexitCoordinator from .entity import FlexitEntity _MAX_FAN_SETPOINT = 100 @@ -196,11 +194,11 @@ NUMBERS: tuple[FlexitNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FlexitConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Flexit (bacnet) number from a config entry.""" - coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id] + coordinator = config_entry.runtime_data async_add_entities( FlexitNumber(coordinator, description) for description in NUMBERS diff --git a/homeassistant/components/flexit_bacnet/sensor.py b/homeassistant/components/flexit_bacnet/sensor.py index be5f12e480e..23d8f20da36 100644 --- a/homeassistant/components/flexit_bacnet/sensor.py +++ b/homeassistant/components/flexit_bacnet/sensor.py @@ -11,7 +11,6 @@ from homeassistant.components.sensor import ( SensorEntityDescription, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( PERCENTAGE, REVOLUTIONS_PER_MINUTE, @@ -20,11 +19,10 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import FlexitCoordinator -from .const import DOMAIN +from .coordinator import FlexitConfigEntry, FlexitCoordinator from .entity import FlexitEntity @@ -152,11 +150,11 @@ SENSOR_TYPES: tuple[FlexitSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FlexitConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Flexit (bacnet) sensor from a config entry.""" - coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id] + coordinator = config_entry.runtime_data async_add_entities( FlexitSensor(coordinator, description) for description in SENSOR_TYPES diff --git a/homeassistant/components/flexit_bacnet/strings.json b/homeassistant/components/flexit_bacnet/strings.json index 8888b02a3ef..f7c54c88050 100644 --- a/homeassistant/components/flexit_bacnet/strings.json +++ b/homeassistant/components/flexit_bacnet/strings.json @@ -110,6 +110,9 @@ }, "fireplace_mode": { "name": "Fireplace mode" + }, + "cooker_hood_mode": { + "name": "Cooker hood mode" } } } diff --git a/homeassistant/components/flexit_bacnet/switch.py b/homeassistant/components/flexit_bacnet/switch.py index 7f12a7524b6..283d0e1ec3b 100644 --- a/homeassistant/components/flexit_bacnet/switch.py +++ b/homeassistant/components/flexit_bacnet/switch.py @@ -13,13 +13,11 @@ from homeassistant.components.switch import ( SwitchEntity, SwitchEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FlexitCoordinator -from .const import DOMAIN +from .coordinator import FlexitConfigEntry, FlexitCoordinator from .entity import FlexitEntity @@ -47,16 +45,23 @@ SWITCHES: tuple[FlexitSwitchEntityDescription, ...] = ( turn_on_fn=lambda data: data.trigger_fireplace_mode(), turn_off_fn=lambda data: data.trigger_fireplace_mode(), ), + FlexitSwitchEntityDescription( + key="cooker_hood_mode", + translation_key="cooker_hood_mode", + is_on_fn=lambda data: data.cooker_hood_status, + turn_on_fn=lambda data: data.activate_cooker_hood(), + turn_off_fn=lambda data: data.deactivate_cooker_hood(), + ), ) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FlexitConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Flexit (bacnet) switch from a config entry.""" - coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id] + coordinator = config_entry.runtime_data async_add_entities( FlexitSwitch(coordinator, description) for description in SWITCHES diff --git a/homeassistant/components/flick_electric/sensor.py b/homeassistant/components/flick_electric/sensor.py index 73b6f8793fb..636d12525ad 100644 --- a/homeassistant/components/flick_electric/sensor.py +++ b/homeassistant/components/flick_electric/sensor.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.sensor import SensorEntity from homeassistant.const import CURRENCY_CENT, UnitOfEnergy from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTR_COMPONENTS, ATTR_END_AT, ATTR_START_AT @@ -21,7 +21,7 @@ SCAN_INTERVAL = timedelta(minutes=5) async def async_setup_entry( hass: HomeAssistant, entry: FlickConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Flick Sensor Setup.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/flipr/binary_sensor.py b/homeassistant/components/flipr/binary_sensor.py index 07357b81af0..899d045ad86 100644 --- a/homeassistant/components/flipr/binary_sensor.py +++ b/homeassistant/components/flipr/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FliprConfigEntry from .entity import FliprEntity @@ -30,7 +30,7 @@ BINARY_SENSORS_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FliprConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup of flipr binary sensors.""" diff --git a/homeassistant/components/flipr/coordinator.py b/homeassistant/components/flipr/coordinator.py index 0d86b43711a..82de5ae34d5 100644 --- a/homeassistant/components/flipr/coordinator.py +++ b/homeassistant/components/flipr/coordinator.py @@ -1,5 +1,7 @@ """DataUpdateCoordinator for flipr integration.""" +from __future__ import annotations + from dataclasses import dataclass from datetime import timedelta import logging @@ -19,8 +21,8 @@ _LOGGER = logging.getLogger(__name__) class FliprData: """The Flipr data class.""" - flipr_coordinators: list["FliprDataUpdateCoordinator"] - hub_coordinators: list["FliprHubDataUpdateCoordinator"] + flipr_coordinators: list[FliprDataUpdateCoordinator] + hub_coordinators: list[FliprHubDataUpdateCoordinator] type FliprConfigEntry = ConfigEntry[FliprData] diff --git a/homeassistant/components/flipr/select.py b/homeassistant/components/flipr/select.py index 79515be6ed4..c10e9c6e91b 100644 --- a/homeassistant/components/flipr/select.py +++ b/homeassistant/components/flipr/select.py @@ -4,7 +4,7 @@ import logging from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FliprConfigEntry from .entity import FliprEntity @@ -23,7 +23,7 @@ SELECT_TYPES: tuple[SelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FliprConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select for Flipr hub mode.""" coordinators = config_entry.runtime_data.hub_coordinators diff --git a/homeassistant/components/flipr/sensor.py b/homeassistant/components/flipr/sensor.py index 2594186f24a..296bcaac68d 100644 --- a/homeassistant/components/flipr/sensor.py +++ b/homeassistant/components/flipr/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfElectricPotential, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FliprConfigEntry from .entity import FliprEntity @@ -57,7 +57,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FliprConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinators = config_entry.runtime_data.flipr_coordinators diff --git a/homeassistant/components/flipr/switch.py b/homeassistant/components/flipr/switch.py index 03df7f34d12..4db8b54af8a 100644 --- a/homeassistant/components/flipr/switch.py +++ b/homeassistant/components/flipr/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FliprConfigEntry from .entity import FliprEntity @@ -23,7 +23,7 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FliprConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch for Flipr hub.""" coordinators = config_entry.runtime_data.hub_coordinators diff --git a/homeassistant/components/flo/__init__.py b/homeassistant/components/flo/__init__.py index 6a497f5140d..88824b041e7 100644 --- a/homeassistant/components/flo/__init__.py +++ b/homeassistant/components/flo/__init__.py @@ -6,27 +6,23 @@ import logging from aioflo import async_get_api from aioflo.errors import RequestError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .const import CLIENT, DOMAIN -from .coordinator import FloDeviceDataUpdateCoordinator +from .coordinator import FloConfigEntry, FloDeviceDataUpdateCoordinator, FloRuntimeData _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.SWITCH] -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: FloConfigEntry) -> bool: """Set up flo from a config entry.""" session = async_get_clientsession(hass) - hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN][entry.entry_id] = {} try: - hass.data[DOMAIN][entry.entry_id][CLIENT] = client = await async_get_api( + client = await async_get_api( entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], session=session ) except RequestError as err: @@ -36,7 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: _LOGGER.debug("Flo user information with locations: %s", user_info) - hass.data[DOMAIN][entry.entry_id]["devices"] = devices = [ + devices = [ FloDeviceDataUpdateCoordinator( hass, entry, client, location["id"], device["id"] ) @@ -47,14 +43,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: tasks = [device.async_refresh() for device in devices] await asyncio.gather(*tasks) + entry.runtime_data = FloRuntimeData(client=client, devices=devices) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: FloConfigEntry) -> bool: """Unload a config entry.""" - unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) - if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/flo/binary_sensor.py b/homeassistant/components/flo/binary_sensor.py index 20f5d7822d2..89f317fd3c6 100644 --- a/homeassistant/components/flo/binary_sensor.py +++ b/homeassistant/components/flo/binary_sensor.py @@ -6,24 +6,20 @@ from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN as FLO_DOMAIN -from .coordinator import FloDeviceDataUpdateCoordinator +from .coordinator import FloConfigEntry from .entity import FloEntity async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FloConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flo sensors from config entry.""" - devices: list[FloDeviceDataUpdateCoordinator] = hass.data[FLO_DOMAIN][ - config_entry.entry_id - ]["devices"] + devices = config_entry.runtime_data.devices entities: list[BinarySensorEntity] = [] for device in devices: if device.device_type == "puck_oem": diff --git a/homeassistant/components/flo/const.py b/homeassistant/components/flo/const.py index 9eb00ebfa62..5b1d926d9f4 100644 --- a/homeassistant/components/flo/const.py +++ b/homeassistant/components/flo/const.py @@ -4,7 +4,6 @@ import logging LOGGER = logging.getLogger(__package__) -CLIENT = "client" DOMAIN = "flo" FLO_HOME = "home" FLO_AWAY = "away" diff --git a/homeassistant/components/flo/coordinator.py b/homeassistant/components/flo/coordinator.py index f5dc34a50cd..9f540b230f4 100644 --- a/homeassistant/components/flo/coordinator.py +++ b/homeassistant/components/flo/coordinator.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio +from dataclasses import dataclass from datetime import datetime, timedelta from typing import Any @@ -17,6 +18,16 @@ from homeassistant.util import dt as dt_util from .const import DOMAIN as FLO_DOMAIN, LOGGER +type FloConfigEntry = ConfigEntry[FloRuntimeData] + + +@dataclass +class FloRuntimeData: + """Flo runtime data.""" + + client: API + devices: list[FloDeviceDataUpdateCoordinator] + class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator): """Flo device object.""" diff --git a/homeassistant/components/flo/sensor.py b/homeassistant/components/flo/sensor.py index 7419b0a1c3b..ca763839b87 100644 --- a/homeassistant/components/flo/sensor.py +++ b/homeassistant/components/flo/sensor.py @@ -7,7 +7,6 @@ from homeassistant.components.sensor import ( SensorEntity, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( PERCENTAGE, UnitOfPressure, @@ -16,22 +15,19 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN as FLO_DOMAIN -from .coordinator import FloDeviceDataUpdateCoordinator +from .coordinator import FloConfigEntry from .entity import FloEntity async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FloConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flo sensors from config entry.""" - devices: list[FloDeviceDataUpdateCoordinator] = hass.data[FLO_DOMAIN][ - config_entry.entry_id - ]["devices"] + devices = config_entry.runtime_data.devices entities = [] for device in devices: if device.device_type == "puck_oem": diff --git a/homeassistant/components/flo/switch.py b/homeassistant/components/flo/switch.py index f0460839837..12e242db5c8 100644 --- a/homeassistant/components/flo/switch.py +++ b/homeassistant/components/flo/switch.py @@ -8,13 +8,11 @@ from aioflo.location import SLEEP_MINUTE_OPTIONS, SYSTEM_MODE_HOME, SYSTEM_REVER import voluptuous as vol from homeassistant.components.switch import SwitchEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN as FLO_DOMAIN -from .coordinator import FloDeviceDataUpdateCoordinator +from .coordinator import FloConfigEntry, FloDeviceDataUpdateCoordinator from .entity import FloEntity ATTR_REVERT_TO_MODE = "revert_to_mode" @@ -27,13 +25,11 @@ SERVICE_RUN_HEALTH_TEST = "run_health_test" async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: FloConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flo switches from config entry.""" - devices: list[FloDeviceDataUpdateCoordinator] = hass.data[FLO_DOMAIN][ - config_entry.entry_id - ]["devices"] + devices = config_entry.runtime_data.devices async_add_entities( [FloSwitch(device) for device in devices if device.device_type != "puck_oem"] diff --git a/homeassistant/components/flume/binary_sensor.py b/homeassistant/components/flume/binary_sensor.py index cb0add90443..2c2dc285036 100644 --- a/homeassistant/components/flume/binary_sensor.py +++ b/homeassistant/components/flume/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( FLUME_TYPE_BRIDGE, @@ -69,7 +69,7 @@ FLUME_BINARY_NOTIFICATION_SENSORS: tuple[FlumeBinarySensorEntityDescription, ... async def async_setup_entry( hass: HomeAssistant, config_entry: FlumeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Flume binary sensor..""" flume_domain_data = config_entry.runtime_data diff --git a/homeassistant/components/flume/sensor.py b/homeassistant/components/flume/sensor.py index aea0aa60093..0f0213ec984 100644 --- a/homeassistant/components/flume/sensor.py +++ b/homeassistant/components/flume/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfVolume from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -108,7 +108,7 @@ def make_flume_datas( async def async_setup_entry( hass: HomeAssistant, config_entry: FlumeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flume sensor.""" diff --git a/homeassistant/components/flux_led/__init__.py b/homeassistant/components/flux_led/__init__.py index 7597a7c9c9a..7515b6b8dfc 100644 --- a/homeassistant/components/flux_led/__init__.py +++ b/homeassistant/components/flux_led/__init__.py @@ -11,7 +11,6 @@ from flux_led.aio import AIOWifiLedBulb from flux_led.const import ATTR_ID, WhiteChannelType from flux_led.scanner import FluxLEDDiscovery -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady @@ -39,7 +38,7 @@ from .const import ( FLUX_LED_EXCEPTIONS, SIGNAL_STATE_UPDATED, ) -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry, FluxLedUpdateCoordinator from .discovery import ( async_build_cached_discovery, async_clear_discovery_cache, @@ -113,7 +112,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return True -async def _async_migrate_unique_ids(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def _async_migrate_unique_ids( + hass: HomeAssistant, entry: FluxLedConfigEntry +) -> None: """Migrate entities when the mac address gets discovered.""" @callback @@ -146,14 +147,16 @@ async def _async_migrate_unique_ids(hass: HomeAssistant, entry: ConfigEntry) -> await er.async_migrate_entries(hass, entry.entry_id, _async_migrator) -async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def _async_update_listener( + hass: HomeAssistant, entry: FluxLedConfigEntry +) -> None: """Handle options update.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data if entry.title != coordinator.title: await hass.config_entries.async_reload(entry.entry_id) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: FluxLedConfigEntry) -> bool: """Set up Flux LED/MagicLight from a config entry.""" host = entry.data[CONF_HOST] discovery_cached = True @@ -206,7 +209,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await _async_migrate_unique_ids(hass, entry) coordinator = FluxLedUpdateCoordinator(hass, device, entry) - hass.data[DOMAIN][entry.entry_id] = coordinator + entry.runtime_data = coordinator platforms = PLATFORMS_BY_TYPE[device.device_type] await hass.config_entries.async_forward_entry_setups(entry, platforms) @@ -239,13 +242,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: FluxLedConfigEntry) -> bool: """Unload a config entry.""" - device: AIOWifiLedBulb = hass.data[DOMAIN][entry.entry_id].device + device = entry.runtime_data.device platforms = PLATFORMS_BY_TYPE[device.device_type] if unload_ok := await hass.config_entries.async_unload_platforms(entry, platforms): # Make sure we probe the device again in case something has changed externally async_clear_discovery_cache(hass, entry.data[CONF_HOST]) - del hass.data[DOMAIN][entry.entry_id] await device.async_stop() return unload_ok diff --git a/homeassistant/components/flux_led/button.py b/homeassistant/components/flux_led/button.py index 90918a55bb2..c4a7ff6569c 100644 --- a/homeassistant/components/flux_led/button.py +++ b/homeassistant/components/flux_led/button.py @@ -5,7 +5,6 @@ from __future__ import annotations from flux_led.aio import AIOWifiLedBulb from flux_led.protocol import RemoteConfig -from homeassistant import config_entries from homeassistant.components.button import ( ButtonDeviceClass, ButtonEntity, @@ -13,10 +12,9 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry from .entity import FluxBaseEntity _RESTART_KEY = "restart" @@ -34,11 +32,11 @@ UNPAIR_REMOTES_DESCRIPTION = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Magic Home button based on a config entry.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data device = coordinator.device entities: list[FluxButton] = [ FluxButton(coordinator.device, entry, RESTART_BUTTON_DESCRIPTION) @@ -59,7 +57,7 @@ class FluxButton(FluxBaseEntity, ButtonEntity): def __init__( self, device: AIOWifiLedBulb, - entry: config_entries.ConfigEntry, + entry: FluxLedConfigEntry, description: ButtonEntityDescription, ) -> None: """Initialize the button.""" diff --git a/homeassistant/components/flux_led/config_flow.py b/homeassistant/components/flux_led/config_flow.py index 035be5b115c..754ed0525b9 100644 --- a/homeassistant/components/flux_led/config_flow.py +++ b/homeassistant/components/flux_led/config_flow.py @@ -18,7 +18,6 @@ import voluptuous as vol from homeassistant.config_entries import ( SOURCE_IGNORE, - ConfigEntry, ConfigEntryState, ConfigFlow, ConfigFlowResult, @@ -46,6 +45,7 @@ from .const import ( TRANSITION_JUMP, TRANSITION_STROBE, ) +from .coordinator import FluxLedConfigEntry from .discovery import ( async_discover_device, async_discover_devices, @@ -72,7 +72,7 @@ class FluxLedConfigFlow(ConfigFlow, domain=DOMAIN): @staticmethod @callback def async_get_options_flow( - config_entry: ConfigEntry, + config_entry: FluxLedConfigEntry, ) -> FluxLedOptionsFlow: """Get the options flow for the Flux LED component.""" return FluxLedOptionsFlow() diff --git a/homeassistant/components/flux_led/coordinator.py b/homeassistant/components/flux_led/coordinator.py index a879d894bcc..78d8bb947fd 100644 --- a/homeassistant/components/flux_led/coordinator.py +++ b/homeassistant/components/flux_led/coordinator.py @@ -20,14 +20,16 @@ _LOGGER = logging.getLogger(__name__) REQUEST_REFRESH_DELAY: Final = 2.0 +type FluxLedConfigEntry = ConfigEntry[FluxLedUpdateCoordinator] + class FluxLedUpdateCoordinator(DataUpdateCoordinator[None]): """DataUpdateCoordinator to gather data for a specific flux_led device.""" - config_entry: ConfigEntry + config_entry: FluxLedConfigEntry def __init__( - self, hass: HomeAssistant, device: AIOWifiLedBulb, entry: ConfigEntry + self, hass: HomeAssistant, device: AIOWifiLedBulb, entry: FluxLedConfigEntry ) -> None: """Initialize DataUpdateCoordinator to gather data for specific device.""" self.device = device diff --git a/homeassistant/components/flux_led/diagnostics.py b/homeassistant/components/flux_led/diagnostics.py index e24c1aff9a4..683aa362377 100644 --- a/homeassistant/components/flux_led/diagnostics.py +++ b/homeassistant/components/flux_led/diagnostics.py @@ -4,22 +4,19 @@ from __future__ import annotations from typing import Any -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from .const import DOMAIN -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry async def async_get_config_entry_diagnostics( - hass: HomeAssistant, entry: ConfigEntry + hass: HomeAssistant, entry: FluxLedConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] return { "entry": { "title": entry.title, "data": dict(entry.data), }, - "data": coordinator.device.diagnostics, + "data": entry.runtime_data.device.diagnostics, } diff --git a/homeassistant/components/flux_led/discovery.py b/homeassistant/components/flux_led/discovery.py index d55f560193f..c3a3c5df3a7 100644 --- a/homeassistant/components/flux_led/discovery.py +++ b/homeassistant/components/flux_led/discovery.py @@ -23,9 +23,8 @@ from flux_led.const import ( from flux_led.models_db import get_model_description from flux_led.scanner import FluxLEDDiscovery -from homeassistant import config_entries from homeassistant.components import network -from homeassistant.config_entries import ConfigEntry, ConfigEntryState +from homeassistant.config_entries import SOURCE_INTEGRATION_DISCOVERY, ConfigEntryState from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, discovery_flow @@ -44,6 +43,7 @@ from .const import ( DOMAIN, FLUX_LED_DISCOVERY, ) +from .coordinator import FluxLedConfigEntry from .util import format_as_flux_mac, mac_matches_by_one _LOGGER = logging.getLogger(__name__) @@ -63,7 +63,7 @@ CONF_TO_DISCOVERY: Final = { @callback -def async_build_cached_discovery(entry: ConfigEntry) -> FluxLEDDiscovery: +def async_build_cached_discovery(entry: FluxLedConfigEntry) -> FluxLEDDiscovery: """When discovery is unavailable, load it from the config entry.""" data = entry.data return FluxLEDDiscovery( @@ -116,7 +116,7 @@ def async_populate_data_from_discovery( @callback def async_update_entry_from_discovery( hass: HomeAssistant, - entry: config_entries.ConfigEntry, + entry: FluxLedConfigEntry, device: FluxLEDDiscovery, model_num: int | None, allow_update_mac: bool, @@ -230,6 +230,6 @@ def async_trigger_discovery( discovery_flow.async_create_flow( hass, DOMAIN, - context={"source": config_entries.SOURCE_INTEGRATION_DISCOVERY}, + context={"source": SOURCE_INTEGRATION_DISCOVERY}, data={**device}, ) diff --git a/homeassistant/components/flux_led/light.py b/homeassistant/components/flux_led/light.py index 2a0b5795970..79dae33a2a5 100644 --- a/homeassistant/components/flux_led/light.py +++ b/homeassistant/components/flux_led/light.py @@ -11,7 +11,6 @@ from flux_led.protocol import MusicMode from flux_led.utils import rgbcw_brightness, rgbcw_to_rgbwc, rgbw_brightness import voluptuous as vol -from homeassistant import config_entries from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_TEMP_KELVIN, @@ -26,7 +25,7 @@ from homeassistant.components.light import ( from homeassistant.const import CONF_EFFECT from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -38,7 +37,6 @@ from .const import ( CONF_SPEED_PCT, CONF_TRANSITION, DEFAULT_EFFECT_SPEED, - DOMAIN, MIN_CCT_BRIGHTNESS, MIN_RGB_BRIGHTNESS, MULTI_BRIGHTNESS_COLOR_MODES, @@ -46,7 +44,7 @@ from .const import ( TRANSITION_JUMP, TRANSITION_STROBE, ) -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry, FluxLedUpdateCoordinator from .entity import FluxOnOffEntity from .util import ( _effect_brightness, @@ -134,11 +132,11 @@ SET_ZONES_DICT: VolDictType = { async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flux lights.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data platform = entity_platform.async_get_current_platform() platform.async_register_entity_service( diff --git a/homeassistant/components/flux_led/number.py b/homeassistant/components/flux_led/number.py index 93687c0c579..edf6b8c9654 100644 --- a/homeassistant/components/flux_led/number.py +++ b/homeassistant/components/flux_led/number.py @@ -16,18 +16,16 @@ from flux_led.protocol import ( SEGMENTS_MAX, ) -from homeassistant import config_entries from homeassistant.components.light import EFFECT_RANDOM from homeassistant.components.number import NumberEntity, NumberMode from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.debounce import Debouncer -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry, FluxLedUpdateCoordinator from .entity import FluxEntity from .util import _effect_brightness @@ -38,11 +36,11 @@ DEBOUNCE_TIME = 1 async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flux lights.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data device = coordinator.device entities: list[ FluxSpeedNumber diff --git a/homeassistant/components/flux_led/select.py b/homeassistant/components/flux_led/select.py index 33329ebb3f3..bcb44c995b8 100644 --- a/homeassistant/components/flux_led/select.py +++ b/homeassistant/components/flux_led/select.py @@ -13,14 +13,13 @@ from flux_led.const import ( ) from flux_led.protocol import PowerRestoreState, RemoteConfig -from homeassistant import config_entries from homeassistant.components.select import SelectEntity from homeassistant.const import CONF_NAME, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import CONF_WHITE_CHANNEL_TYPE, DOMAIN, FLUX_COLOR_MODE_RGBW -from .coordinator import FluxLedUpdateCoordinator +from .const import CONF_WHITE_CHANNEL_TYPE, FLUX_COLOR_MODE_RGBW +from .coordinator import FluxLedConfigEntry, FluxLedUpdateCoordinator from .entity import FluxBaseEntity, FluxEntity from .util import _human_readable_option @@ -29,9 +28,7 @@ NAME_TO_POWER_RESTORE_STATE = { } -async def _async_delayed_reload( - hass: HomeAssistant, entry: config_entries.ConfigEntry -) -> None: +async def _async_delayed_reload(hass: HomeAssistant, entry: FluxLedConfigEntry) -> None: """Reload after making a change that will effect the operation of the device.""" await asyncio.sleep(STATE_CHANGE_LATENCY) hass.async_create_task(hass.config_entries.async_reload(entry.entry_id)) @@ -39,11 +36,11 @@ async def _async_delayed_reload( async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flux selects.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data device = coordinator.device entities: list[ FluxPowerStateSelect @@ -97,7 +94,7 @@ class FluxPowerStateSelect(FluxConfigAtStartSelect, SelectEntity): def __init__( self, device: AIOWifiLedBulb, - entry: config_entries.ConfigEntry, + entry: FluxLedConfigEntry, ) -> None: """Initialize the power state select.""" super().__init__(device, entry) @@ -228,7 +225,7 @@ class FluxWhiteChannelSelect(FluxConfigAtStartSelect): def __init__( self, device: AIOWifiLedBulb, - entry: config_entries.ConfigEntry, + entry: FluxLedConfigEntry, ) -> None: """Initialize the white channel select.""" super().__init__(device, entry) diff --git a/homeassistant/components/flux_led/sensor.py b/homeassistant/components/flux_led/sensor.py index 5a6633669ae..ad4b9bacbbe 100644 --- a/homeassistant/components/flux_led/sensor.py +++ b/homeassistant/components/flux_led/sensor.py @@ -2,24 +2,22 @@ from __future__ import annotations -from homeassistant import config_entries from homeassistant.components.sensor import SensorEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry from .entity import FluxEntity async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Magic Home sensors.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data if coordinator.device.paired_remotes is not None: async_add_entities( [ diff --git a/homeassistant/components/flux_led/switch.py b/homeassistant/components/flux_led/switch.py index 3adcd9a9da9..5dea5408c84 100644 --- a/homeassistant/components/flux_led/switch.py +++ b/homeassistant/components/flux_led/switch.py @@ -8,31 +8,29 @@ from flux_led import DeviceType from flux_led.aio import AIOWifiLedBulb from flux_led.const import MODE_MUSIC -from homeassistant import config_entries from homeassistant.components.switch import SwitchEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( CONF_REMOTE_ACCESS_ENABLED, CONF_REMOTE_ACCESS_HOST, CONF_REMOTE_ACCESS_PORT, - DOMAIN, ) -from .coordinator import FluxLedUpdateCoordinator +from .coordinator import FluxLedConfigEntry, FluxLedUpdateCoordinator from .discovery import async_clear_discovery_cache from .entity import FluxBaseEntity, FluxEntity, FluxOnOffEntity async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: FluxLedConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Flux lights.""" - coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data entities: list[FluxSwitch | FluxRemoteAccessSwitch | FluxMusicSwitch] = [] base_unique_id = entry.unique_id or entry.entry_id @@ -70,7 +68,7 @@ class FluxRemoteAccessSwitch(FluxBaseEntity, SwitchEntity): def __init__( self, device: AIOWifiLedBulb, - entry: config_entries.ConfigEntry, + entry: FluxLedConfigEntry, ) -> None: """Initialize the light.""" super().__init__(device, entry) diff --git a/homeassistant/components/folder_watcher/event.py b/homeassistant/components/folder_watcher/event.py index 7158930e116..472599c4ead 100644 --- a/homeassistant/components/folder_watcher/event.py +++ b/homeassistant/components/folder_watcher/event.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -25,7 +25,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Folder Watcher event.""" diff --git a/homeassistant/components/forecast_solar/sensor.py b/homeassistant/components/forecast_solar/sensor.py index c1fa971a89d..13a4d5c2d23 100644 --- a/homeassistant/components/forecast_solar/sensor.py +++ b/homeassistant/components/forecast_solar/sensor.py @@ -19,7 +19,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -135,7 +135,7 @@ SENSORS: tuple[ForecastSolarSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ForecastSolarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/forked_daapd/media_player.py b/homeassistant/components/forked_daapd/media_player.py index 8e61df3de45..6bc69a64eaa 100644 --- a/homeassistant/components/forked_daapd/media_player.py +++ b/homeassistant/components/forked_daapd/media_player.py @@ -36,7 +36,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .browse_media import ( @@ -82,7 +82,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up forked-daapd from a config entry.""" host = config_entry.data[CONF_HOST] diff --git a/homeassistant/components/foscam/camera.py b/homeassistant/components/foscam/camera.py index ed5ba1d4c21..353c7397d81 100644 --- a/homeassistant/components/foscam/camera.py +++ b/homeassistant/components/foscam/camera.py @@ -10,7 +10,7 @@ from homeassistant.components.camera import Camera, CameraEntityFeature from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_RTSP_PORT, CONF_STREAM, LOGGER, SERVICE_PTZ, SERVICE_PTZ_PRESET from .coordinator import FoscamConfigEntry, FoscamCoordinator @@ -49,7 +49,7 @@ PTZ_GOTO_PRESET_COMMAND = "ptz_goto_preset" async def async_setup_entry( hass: HomeAssistant, config_entry: FoscamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a Foscam IP camera from a config entry.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/foscam/switch.py b/homeassistant/components/foscam/switch.py index 189271d2746..24b05b5aeaa 100644 --- a/homeassistant/components/foscam/switch.py +++ b/homeassistant/components/foscam/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER from .coordinator import FoscamConfigEntry, FoscamCoordinator @@ -17,7 +17,7 @@ from .entity import FoscamEntity async def async_setup_entry( hass: HomeAssistant, config_entry: FoscamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up foscam switch from a config entry.""" diff --git a/homeassistant/components/freebox/alarm_control_panel.py b/homeassistant/components/freebox/alarm_control_panel.py index 9d8e85a14ca..89462b33a2f 100644 --- a/homeassistant/components/freebox/alarm_control_panel.py +++ b/homeassistant/components/freebox/alarm_control_panel.py @@ -9,7 +9,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, FreeboxHomeCategory from .entity import FreeboxHomeEntity @@ -28,7 +28,9 @@ FREEBOX_TO_STATUS = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up alarm panel.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/freebox/binary_sensor.py b/homeassistant/components/freebox/binary_sensor.py index 20c124efea6..9fc9929b869 100644 --- a/homeassistant/components/freebox/binary_sensor.py +++ b/homeassistant/components/freebox/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, FreeboxHomeCategory from .entity import FreeboxHomeEntity @@ -34,7 +34,9 @@ RAID_SENSORS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/freebox/button.py b/homeassistant/components/freebox/button.py index 79e3c98b8b7..4f676fd46a1 100644 --- a/homeassistant/components/freebox/button.py +++ b/homeassistant/components/freebox/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .router import FreeboxRouter @@ -44,7 +44,9 @@ BUTTON_DESCRIPTIONS: tuple[FreeboxButtonEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the buttons.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/freebox/camera.py b/homeassistant/components/freebox/camera.py index 33919df74f6..45bb5a34063 100644 --- a/homeassistant/components/freebox/camera.py +++ b/homeassistant/components/freebox/camera.py @@ -17,7 +17,7 @@ from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_DETECTION, DOMAIN, FreeboxHomeCategory from .entity import FreeboxHomeEntity @@ -27,7 +27,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cameras.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] @@ -49,7 +51,7 @@ async def async_setup_entry( def add_entities( hass: HomeAssistant, router: FreeboxRouter, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: set[str], ) -> None: """Add new cameras from the router.""" diff --git a/homeassistant/components/freebox/device_tracker.py b/homeassistant/components/freebox/device_tracker.py index 1fa37ebc270..dcb6eb104b2 100644 --- a/homeassistant/components/freebox/device_tracker.py +++ b/homeassistant/components/freebox/device_tracker.py @@ -9,14 +9,16 @@ from homeassistant.components.device_tracker import ScannerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEFAULT_DEVICE_NAME, DEVICE_ICONS, DOMAIN from .router import FreeboxRouter async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Freebox component.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] @@ -36,7 +38,9 @@ async def async_setup_entry( @callback def add_entities( - router: FreeboxRouter, async_add_entities: AddEntitiesCallback, tracked: set[str] + router: FreeboxRouter, + async_add_entities: AddConfigEntryEntitiesCallback, + tracked: set[str], ) -> None: """Add new tracker entities from the router.""" new_tracked = [] diff --git a/homeassistant/components/freebox/sensor.py b/homeassistant/components/freebox/sensor.py index 588992a7f21..cc62de9ae0d 100644 --- a/homeassistant/components/freebox/sensor.py +++ b/homeassistant/components/freebox/sensor.py @@ -15,7 +15,7 @@ from homeassistant.const import PERCENTAGE, UnitOfDataRate, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -60,7 +60,9 @@ DISK_PARTITION_SENSORS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/freebox/switch.py b/homeassistant/components/freebox/switch.py index 96c3bcc2496..c4618b014bf 100644 --- a/homeassistant/components/freebox/switch.py +++ b/homeassistant/components/freebox/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .router import FreeboxRouter @@ -29,7 +29,9 @@ SWITCH_DESCRIPTIONS = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch.""" router: FreeboxRouter = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/freedompro/binary_sensor.py b/homeassistant/components/freedompro/binary_sensor.py index 840150e807d..9ff62446176 100644 --- a/homeassistant/components/freedompro/binary_sensor.py +++ b/homeassistant/components/freedompro/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -34,7 +34,7 @@ SUPPORTED_SENSORS = {"smokeSensor", "occupancySensor", "motionSensor", "contactS async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro binary_sensor.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/freedompro/climate.py b/homeassistant/components/freedompro/climate.py index a0146dc70b3..0145dea27bb 100644 --- a/homeassistant/components/freedompro/climate.py +++ b/homeassistant/components/freedompro/climate.py @@ -19,7 +19,7 @@ from homeassistant.const import ATTR_TEMPERATURE, CONF_API_KEY, UnitOfTemperatur from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -45,7 +45,7 @@ SUPPORTED_HVAC_MODES = [ async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro climate.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/freedompro/cover.py b/homeassistant/components/freedompro/cover.py index ee61612428c..01e1b39d08f 100644 --- a/homeassistant/components/freedompro/cover.py +++ b/homeassistant/components/freedompro/cover.py @@ -15,7 +15,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -35,7 +35,7 @@ SUPPORTED_SENSORS = {"windowCovering", "gate", "garageDoor", "door", "window"} async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro cover.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/freedompro/fan.py b/homeassistant/components/freedompro/fan.py index ad520ac8eb8..c65afb3a0e2 100644 --- a/homeassistant/components/freedompro/fan.py +++ b/homeassistant/components/freedompro/fan.py @@ -12,7 +12,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -22,7 +22,7 @@ from .coordinator import FreedomproConfigEntry, FreedomproDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro fan.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/freedompro/light.py b/homeassistant/components/freedompro/light.py index c1b2e0ea17b..f9d90420c5d 100644 --- a/homeassistant/components/freedompro/light.py +++ b/homeassistant/components/freedompro/light.py @@ -17,7 +17,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -27,7 +27,7 @@ from .coordinator import FreedomproConfigEntry, FreedomproDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro light.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/freedompro/lock.py b/homeassistant/components/freedompro/lock.py index 70423bb9514..4aee252abbe 100644 --- a/homeassistant/components/freedompro/lock.py +++ b/homeassistant/components/freedompro/lock.py @@ -10,7 +10,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -20,7 +20,7 @@ from .coordinator import FreedomproConfigEntry, FreedomproDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro lock.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/freedompro/sensor.py b/homeassistant/components/freedompro/sensor.py index eaa96ac9fed..dbe1449d6e5 100644 --- a/homeassistant/components/freedompro/sensor.py +++ b/homeassistant/components/freedompro/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import LIGHT_LUX, PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -42,7 +42,7 @@ SUPPORTED_SENSORS = {"temperatureSensor", "humiditySensor", "lightSensor"} async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro sensor.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/freedompro/switch.py b/homeassistant/components/freedompro/switch.py index 12346825474..bda13b147b1 100644 --- a/homeassistant/components/freedompro/switch.py +++ b/homeassistant/components/freedompro/switch.py @@ -10,7 +10,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -20,7 +20,7 @@ from .coordinator import FreedomproConfigEntry, FreedomproDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: FreedomproConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Freedompro switch.""" api_key: str = entry.data[CONF_API_KEY] diff --git a/homeassistant/components/fritz/binary_sensor.py b/homeassistant/components/fritz/binary_sensor.py index 7553328a64c..6bc8bb571d4 100644 --- a/homeassistant/components/fritz/binary_sensor.py +++ b/homeassistant/components/fritz/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ConnectionInfo, FritzConfigEntry from .entity import FritzBoxBaseCoordinatorEntity, FritzEntityDescription @@ -51,7 +51,7 @@ SENSOR_TYPES: tuple[FritzBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" _LOGGER.debug("Setting up FRITZ!Box binary sensors") diff --git a/homeassistant/components/fritz/button.py b/homeassistant/components/fritz/button.py index f3ffbe42099..74e8ab5e43e 100644 --- a/homeassistant/components/fritz/button.py +++ b/homeassistant/components/fritz/button.py @@ -16,7 +16,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import BUTTON_TYPE_WOL, CONNECTION_TYPE_LAN, DOMAIN, MeshRoles from .coordinator import ( @@ -72,7 +72,7 @@ BUTTONS: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set buttons for device.""" _LOGGER.debug("Setting up buttons") diff --git a/homeassistant/components/fritz/device_tracker.py b/homeassistant/components/fritz/device_tracker.py index ba3c9a5aab6..e066219342e 100644 --- a/homeassistant/components/fritz/device_tracker.py +++ b/homeassistant/components/fritz/device_tracker.py @@ -8,7 +8,7 @@ import logging from homeassistant.components.device_tracker import ScannerEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ( FRITZ_DATA_KEY, @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for FRITZ!Box component.""" _LOGGER.debug("Starting FRITZ!Box device tracker") @@ -48,7 +48,7 @@ async def async_setup_entry( @callback def _async_add_entities( avm_wrapper: AvmWrapper, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, data_fritz: FritzData, ) -> None: """Add new tracker entities from the AVM device.""" diff --git a/homeassistant/components/fritz/image.py b/homeassistant/components/fritz/image.py index d305551b097..d329ec318c5 100644 --- a/homeassistant/components/fritz/image.py +++ b/homeassistant/components/fritz/image.py @@ -10,7 +10,7 @@ from requests.exceptions import RequestException from homeassistant.components.image import ImageEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util, slugify from .coordinator import AvmWrapper, FritzConfigEntry @@ -22,7 +22,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up guest WiFi QR code for device.""" avm_wrapper = entry.runtime_data diff --git a/homeassistant/components/fritz/sensor.py b/homeassistant/components/fritz/sensor.py index 81b50bd21ac..bcee590460f 100644 --- a/homeassistant/components/fritz/sensor.py +++ b/homeassistant/components/fritz/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfInformation, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow @@ -268,7 +268,7 @@ SENSOR_TYPES: tuple[FritzSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" _LOGGER.debug("Setting up FRITZ!Box sensors") diff --git a/homeassistant/components/fritz/switch.py b/homeassistant/components/fritz/switch.py index 9c12fe0cecc..1548f8fc755 100644 --- a/homeassistant/components/fritz/switch.py +++ b/homeassistant/components/fritz/switch.py @@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import slugify @@ -222,7 +222,7 @@ async def async_all_entities_list( async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" _LOGGER.debug("Setting up switches") diff --git a/homeassistant/components/fritz/update.py b/homeassistant/components/fritz/update.py index ad23a076ca6..5d064dc3035 100644 --- a/homeassistant/components/fritz/update.py +++ b/homeassistant/components/fritz/update.py @@ -13,7 +13,7 @@ from homeassistant.components.update import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import AvmWrapper, FritzConfigEntry from .entity import FritzBoxBaseCoordinatorEntity, FritzEntityDescription @@ -29,7 +29,7 @@ class FritzUpdateEntityDescription(UpdateEntityDescription, FritzEntityDescripti async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AVM FRITZ!Box update entities.""" _LOGGER.debug("Setting up AVM FRITZ!Box update entities") diff --git a/homeassistant/components/fritzbox/binary_sensor.py b/homeassistant/components/fritzbox/binary_sensor.py index 3c9cb6ada5c..75683017cb7 100644 --- a/homeassistant/components/fritzbox/binary_sensor.py +++ b/homeassistant/components/fritzbox/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FritzboxConfigEntry from .entity import FritzBoxDeviceEntity @@ -66,7 +66,7 @@ BINARY_SENSOR_TYPES: Final[tuple[FritzBinarySensorEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome binary sensor from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/button.py b/homeassistant/components/fritzbox/button.py index 44a6697e1c0..54baa97b11a 100644 --- a/homeassistant/components/fritzbox/button.py +++ b/homeassistant/components/fritzbox/button.py @@ -5,7 +5,7 @@ from pyfritzhome.devicetypes import FritzhomeTemplate from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import FritzboxConfigEntry @@ -15,7 +15,7 @@ from .entity import FritzBoxEntity async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome template from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/climate.py b/homeassistant/components/fritzbox/climate.py index 87a87ac691f..c25113f1bca 100644 --- a/homeassistant/components/fritzbox/climate.py +++ b/homeassistant/components/fritzbox/climate.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_STATE_BATTERY_LOW, @@ -59,7 +59,7 @@ OFF_REPORT_SET_TEMPERATURE = 0.0 async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome thermostat from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/cover.py b/homeassistant/components/fritzbox/cover.py index 070bb868298..c7ecfef6a32 100644 --- a/homeassistant/components/fritzbox/cover.py +++ b/homeassistant/components/fritzbox/cover.py @@ -11,7 +11,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FritzboxConfigEntry from .entity import FritzBoxDeviceEntity @@ -20,7 +20,7 @@ from .entity import FritzBoxDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome cover from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/light.py b/homeassistant/components/fritzbox/light.py index 94d7d320704..8603840630c 100644 --- a/homeassistant/components/fritzbox/light.py +++ b/homeassistant/components/fritzbox/light.py @@ -12,7 +12,7 @@ from homeassistant.components.light import ( LightEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import COLOR_MODE, LOGGER from .coordinator import FritzboxConfigEntry, FritzboxDataUpdateCoordinator @@ -22,7 +22,7 @@ from .entity import FritzBoxDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome light from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/sensor.py b/homeassistant/components/fritzbox/sensor.py index e610fd80f3e..bed7004bd6a 100644 --- a/homeassistant/components/fritzbox/sensor.py +++ b/homeassistant/components/fritzbox/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utc_from_timestamp @@ -229,7 +229,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome sensor from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox/switch.py b/homeassistant/components/fritzbox/switch.py index d83793c77dc..c2679ef5243 100644 --- a/homeassistant/components/fritzbox/switch.py +++ b/homeassistant/components/fritzbox/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import FritzboxConfigEntry @@ -17,7 +17,7 @@ from .entity import FritzBoxDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: FritzboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FRITZ!SmartHome switch from ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fritzbox_callmonitor/sensor.py b/homeassistant/components/fritzbox_callmonitor/sensor.py index df18ae5702a..574ae9ef7f2 100644 --- a/homeassistant/components/fritzbox_callmonitor/sensor.py +++ b/homeassistant/components/fritzbox_callmonitor/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.const import CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FritzBoxCallMonitorConfigEntry from .base import Contact, FritzBoxPhonebook @@ -48,7 +48,7 @@ class CallState(StrEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: FritzBoxCallMonitorConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fritzbox_callmonitor sensor from config_entry.""" fritzbox_phonebook = config_entry.runtime_data diff --git a/homeassistant/components/fronius/sensor.py b/homeassistant/components/fronius/sensor.py index c6c3ff4b602..c65f6072ba6 100644 --- a/homeassistant/components/fronius/sensor.py +++ b/homeassistant/components/fronius/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -64,7 +64,7 @@ ENERGY_VOLT_AMPERE_REACTIVE_HOUR: Final = "varh" async def async_setup_entry( hass: HomeAssistant, config_entry: FroniusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Fronius sensor entities based on a config entry.""" solar_net = config_entry.runtime_data diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index d27785dcea5..912ce508e00 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -21,5 +21,5 @@ "documentation": "https://www.home-assistant.io/integrations/frontend", "integration_type": "system", "quality_scale": "internal", - "requirements": ["home-assistant-frontend==20250205.0"] + "requirements": ["home-assistant-frontend==20250210.0"] } diff --git a/homeassistant/components/frontier_silicon/media_player.py b/homeassistant/components/frontier_silicon/media_player.py index 6b0f987baa2..4f5e55d1536 100644 --- a/homeassistant/components/frontier_silicon/media_player.py +++ b/homeassistant/components/frontier_silicon/media_player.py @@ -22,7 +22,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FrontierSiliconConfigEntry from .browse_media import browse_node, browse_top_level @@ -34,7 +34,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: FrontierSiliconConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Frontier Silicon entity.""" diff --git a/homeassistant/components/fujitsu_fglair/climate.py b/homeassistant/components/fujitsu_fglair/climate.py index 5df6573e638..bf1df07823c 100644 --- a/homeassistant/components/fujitsu_fglair/climate.py +++ b/homeassistant/components/fujitsu_fglair/climate.py @@ -25,7 +25,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FGLairConfigEntry, FGLairCoordinator from .entity import FGLairEntity @@ -60,7 +60,7 @@ FUJI_TO_HA_SWING = {value: key for key, value in HA_TO_FUJI_SWING.items()} async def async_setup_entry( hass: HomeAssistant, entry: FGLairConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up one Fujitsu HVAC device.""" async_add_entities( diff --git a/homeassistant/components/fujitsu_fglair/sensor.py b/homeassistant/components/fujitsu_fglair/sensor.py index e095a566dcb..0ad5bec3117 100644 --- a/homeassistant/components/fujitsu_fglair/sensor.py +++ b/homeassistant/components/fujitsu_fglair/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FGLairConfigEntry, FGLairCoordinator from .entity import FGLairEntity @@ -18,7 +18,7 @@ from .entity import FGLairEntity async def async_setup_entry( hass: HomeAssistant, entry: FGLairConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up one Fujitsu HVAC device.""" async_add_entities( diff --git a/homeassistant/components/fully_kiosk/binary_sensor.py b/homeassistant/components/fully_kiosk/binary_sensor.py index c039baa0397..8a25376f635 100644 --- a/homeassistant/components/fully_kiosk/binary_sensor.py +++ b/homeassistant/components/fully_kiosk/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -38,7 +38,7 @@ SENSORS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser sensor.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/button.py b/homeassistant/components/fully_kiosk/button.py index 4b172d45ae2..112ead983b9 100644 --- a/homeassistant/components/fully_kiosk/button.py +++ b/homeassistant/components/fully_kiosk/button.py @@ -15,7 +15,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -68,7 +68,7 @@ BUTTONS: tuple[FullyButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser button entities.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/camera.py b/homeassistant/components/fully_kiosk/camera.py index 7dfbe9e9257..6357660f8e8 100644 --- a/homeassistant/components/fully_kiosk/camera.py +++ b/homeassistant/components/fully_kiosk/camera.py @@ -7,7 +7,7 @@ from fullykiosk import FullyKioskError from homeassistant.components.camera import Camera, CameraEntityFeature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import FullyKioskEntity async def async_setup_entry( hass: HomeAssistant, entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the cameras.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/image.py b/homeassistant/components/fully_kiosk/image.py index e1a4240c9e9..158eae8671c 100644 --- a/homeassistant/components/fully_kiosk/image.py +++ b/homeassistant/components/fully_kiosk/image.py @@ -11,7 +11,7 @@ from fullykiosk import FullyKiosk, FullyKioskError from homeassistant.components.image import ImageEntity, ImageEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import FullyKioskConfigEntry @@ -38,7 +38,7 @@ IMAGES: tuple[FullyImageEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser image entities.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/media_player.py b/homeassistant/components/fully_kiosk/media_player.py index 24f002a7544..f6333a2941d 100644 --- a/homeassistant/components/fully_kiosk/media_player.py +++ b/homeassistant/components/fully_kiosk/media_player.py @@ -14,7 +14,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .const import AUDIOMANAGER_STREAM_MUSIC, MEDIA_SUPPORT_FULLYKIOSK @@ -25,7 +25,7 @@ from .entity import FullyKioskEntity async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser media player entity.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/notify.py b/homeassistant/components/fully_kiosk/notify.py index bddc07439b3..0a0c24c60e2 100644 --- a/homeassistant/components/fully_kiosk/notify.py +++ b/homeassistant/components/fully_kiosk/notify.py @@ -9,7 +9,7 @@ from fullykiosk import FullyKioskError from homeassistant.components.notify import NotifyEntity, NotifyEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -40,7 +40,7 @@ NOTIFIERS: tuple[FullyNotifyEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser notify entities.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/number.py b/homeassistant/components/fully_kiosk/number.py index ef25a69f1ee..8c386e85418 100644 --- a/homeassistant/components/fully_kiosk/number.py +++ b/homeassistant/components/fully_kiosk/number.py @@ -7,7 +7,7 @@ from contextlib import suppress from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -54,7 +54,7 @@ ENTITY_TYPES: tuple[NumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser number entities.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/sensor.py b/homeassistant/components/fully_kiosk/sensor.py index d92c5c17341..6094a6c4c23 100644 --- a/homeassistant/components/fully_kiosk/sensor.py +++ b/homeassistant/components/fully_kiosk/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfInformation from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import FullyKioskConfigEntry @@ -114,7 +114,7 @@ SENSORS: tuple[FullySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser sensor.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fully_kiosk/switch.py b/homeassistant/components/fully_kiosk/switch.py index 4adf8e8c924..804233dcc9e 100644 --- a/homeassistant/components/fully_kiosk/switch.py +++ b/homeassistant/components/fully_kiosk/switch.py @@ -11,7 +11,7 @@ from fullykiosk import FullyKiosk from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import FullyKioskConfigEntry from .coordinator import FullyKioskDataUpdateCoordinator @@ -84,7 +84,7 @@ SWITCHES: tuple[FullySwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: FullyKioskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fully Kiosk Browser switch.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/fyta/binary_sensor.py b/homeassistant/components/fyta/binary_sensor.py index 66e5b2feeca..ac092f1d9cb 100644 --- a/homeassistant/components/fyta/binary_sensor.py +++ b/homeassistant/components/fyta/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FytaConfigEntry from .entity import FytaPlantEntity @@ -83,7 +83,9 @@ BINARY_SENSORS: Final[list[FytaBinarySensorEntityDescription]] = [ async def async_setup_entry( - hass: HomeAssistant, entry: FytaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: FytaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FYTA binary sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fyta/image.py b/homeassistant/components/fyta/image.py index 4a0b32f605b..326f2ddf570 100644 --- a/homeassistant/components/fyta/image.py +++ b/homeassistant/components/fyta/image.py @@ -7,14 +7,16 @@ from datetime import datetime from homeassistant.components.image import ImageEntity, ImageEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import FytaConfigEntry, FytaCoordinator from .entity import FytaPlantEntity async def async_setup_entry( - hass: HomeAssistant, entry: FytaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: FytaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FYTA plant images.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/fyta/sensor.py b/homeassistant/components/fyta/sensor.py index 66c96ab697b..622945ae102 100644 --- a/homeassistant/components/fyta/sensor.py +++ b/homeassistant/components/fyta/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import FytaConfigEntry, FytaCoordinator @@ -154,7 +154,9 @@ SENSORS: Final[list[FytaSensorEntityDescription]] = [ async def async_setup_entry( - hass: HomeAssistant, entry: FytaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: FytaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the FYTA sensors.""" coordinator: FytaCoordinator = entry.runtime_data diff --git a/homeassistant/components/garages_amsterdam/binary_sensor.py b/homeassistant/components/garages_amsterdam/binary_sensor.py index cf4b29f0af8..6cfd68c8a00 100644 --- a/homeassistant/components/garages_amsterdam/binary_sensor.py +++ b/homeassistant/components/garages_amsterdam/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ( GaragesAmsterdamConfigEntry, @@ -42,7 +42,7 @@ BINARY_SENSORS: tuple[GaragesAmsterdamBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GaragesAmsterdamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/garages_amsterdam/sensor.py b/homeassistant/components/garages_amsterdam/sensor.py index 8c16260c58b..5467ae73b1e 100644 --- a/homeassistant/components/garages_amsterdam/sensor.py +++ b/homeassistant/components/garages_amsterdam/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import ( @@ -59,7 +59,7 @@ SENSORS: tuple[GaragesAmsterdamSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GaragesAmsterdamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/binary_sensor.py b/homeassistant/components/gardena_bluetooth/binary_sensor.py index 4ee3dd511e9..b41988afd8c 100644 --- a/homeassistant/components/gardena_bluetooth/binary_sensor.py +++ b/homeassistant/components/gardena_bluetooth/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GardenaBluetoothConfigEntry from .entity import GardenaBluetoothDescriptorEntity @@ -53,7 +53,7 @@ DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/button.py b/homeassistant/components/gardena_bluetooth/button.py index 8390baa5943..6a4f0395fe0 100644 --- a/homeassistant/components/gardena_bluetooth/button.py +++ b/homeassistant/components/gardena_bluetooth/button.py @@ -10,7 +10,7 @@ from gardena_bluetooth.parse import CharacteristicBool from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GardenaBluetoothConfigEntry from .entity import GardenaBluetoothDescriptorEntity @@ -42,7 +42,7 @@ DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/number.py b/homeassistant/components/gardena_bluetooth/number.py index eb95d9ff814..41b4f1e79ba 100644 --- a/homeassistant/components/gardena_bluetooth/number.py +++ b/homeassistant/components/gardena_bluetooth/number.py @@ -19,7 +19,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GardenaBluetoothConfigEntry, GardenaBluetoothCoordinator from .entity import GardenaBluetoothDescriptorEntity, GardenaBluetoothEntity @@ -105,7 +105,7 @@ DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entity based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/sensor.py b/homeassistant/components/gardena_bluetooth/sensor.py index 29d1a3155de..602f5bdfd6e 100644 --- a/homeassistant/components/gardena_bluetooth/sensor.py +++ b/homeassistant/components/gardena_bluetooth/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import GardenaBluetoothConfigEntry, GardenaBluetoothCoordinator @@ -95,7 +95,7 @@ DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Gardena Bluetooth sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/switch.py b/homeassistant/components/gardena_bluetooth/switch.py index 73c4867d040..de1fbe22470 100644 --- a/homeassistant/components/gardena_bluetooth/switch.py +++ b/homeassistant/components/gardena_bluetooth/switch.py @@ -9,7 +9,7 @@ from gardena_bluetooth.const import Valve from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GardenaBluetoothConfigEntry, GardenaBluetoothCoordinator from .entity import GardenaBluetoothEntity @@ -18,7 +18,7 @@ from .entity import GardenaBluetoothEntity async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gardena_bluetooth/valve.py b/homeassistant/components/gardena_bluetooth/valve.py index e51e5aa22ca..4138c7c4472 100644 --- a/homeassistant/components/gardena_bluetooth/valve.py +++ b/homeassistant/components/gardena_bluetooth/valve.py @@ -8,7 +8,7 @@ from gardena_bluetooth.const import Valve from homeassistant.components.valve import ValveEntity, ValveEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GardenaBluetoothConfigEntry, GardenaBluetoothCoordinator from .entity import GardenaBluetoothEntity @@ -19,7 +19,7 @@ FALLBACK_WATERING_TIME_IN_SECONDS = 60 * 60 async def async_setup_entry( hass: HomeAssistant, entry: GardenaBluetoothConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/gdacs/geo_location.py b/homeassistant/components/gdacs/geo_location.py index 3f693241b24..d277ee54f6b 100644 --- a/homeassistant/components/gdacs/geo_location.py +++ b/homeassistant/components/gdacs/geo_location.py @@ -15,7 +15,7 @@ from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import DistanceConverter from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM @@ -52,7 +52,9 @@ SOURCE = "gdacs" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GDACS Feed platform.""" manager: GdacsFeedEntityManager = hass.data[DOMAIN][FEED][entry.entry_id] diff --git a/homeassistant/components/gdacs/sensor.py b/homeassistant/components/gdacs/sensor.py index c8205730da4..a204addd414 100644 --- a/homeassistant/components/gdacs/sensor.py +++ b/homeassistant/components/gdacs/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import GdacsFeedEntityManager @@ -37,7 +37,9 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GDACS Feed platform.""" manager: GdacsFeedEntityManager = hass.data[DOMAIN][FEED][entry.entry_id] diff --git a/homeassistant/components/generic/camera.py b/homeassistant/components/generic/camera.py index edefbc55ca6..6821300fadf 100644 --- a/homeassistant/components/generic/camera.py +++ b/homeassistant/components/generic/camera.py @@ -29,7 +29,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import TemplateError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.template import Template @@ -47,7 +47,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a generic IP Camera.""" diff --git a/homeassistant/components/generic_hygrostat/humidifier.py b/homeassistant/components/generic_hygrostat/humidifier.py index 69c4fb3cdf4..6e699745279 100644 --- a/homeassistant/components/generic_hygrostat/humidifier.py +++ b/homeassistant/components/generic_hygrostat/humidifier.py @@ -43,7 +43,10 @@ from homeassistant.core import ( ) from homeassistant.helpers import condition, config_validation as cv from homeassistant.helpers.device import async_device_info_to_link_from_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import ( async_track_state_change_event, async_track_state_report_event, @@ -94,7 +97,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" @@ -116,7 +119,7 @@ async def _async_setup_config( hass: HomeAssistant, config: Mapping[str, Any], unique_id: str | None, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback, ) -> None: name: str = config[CONF_NAME] switch_entity_id: str = config[CONF_HUMIDIFIER] diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index fe6f0253f48..190caa58b3f 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -49,7 +49,10 @@ from homeassistant.core import ( from homeassistant.exceptions import ConditionError from homeassistant.helpers import condition, config_validation as cv from homeassistant.helpers.device import async_device_info_to_link_from_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import ( async_track_state_change_event, async_track_time_interval, @@ -123,7 +126,7 @@ PLATFORM_SCHEMA = CLIMATE_PLATFORM_SCHEMA.extend(PLATFORM_SCHEMA_COMMON.schema) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" await _async_setup_config( @@ -152,7 +155,7 @@ async def _async_setup_config( hass: HomeAssistant, config: Mapping[str, Any], unique_id: str | None, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback, ) -> None: """Set up the generic thermostat platform.""" diff --git a/homeassistant/components/geniushub/binary_sensor.py b/homeassistant/components/geniushub/binary_sensor.py index 01ccc950fd6..c2f25532453 100644 --- a/homeassistant/components/geniushub/binary_sensor.py +++ b/homeassistant/components/geniushub/binary_sensor.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GeniusHubConfigEntry from .entity import GeniusDevice @@ -16,7 +16,7 @@ GH_TYPE = "Receiver" async def async_setup_entry( hass: HomeAssistant, entry: GeniusHubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Genius Hub binary sensor entities.""" diff --git a/homeassistant/components/geniushub/climate.py b/homeassistant/components/geniushub/climate.py index e20d649541e..3c5cc4d4ad9 100644 --- a/homeassistant/components/geniushub/climate.py +++ b/homeassistant/components/geniushub/climate.py @@ -11,7 +11,7 @@ from homeassistant.components.climate import ( HVACMode, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GeniusHubConfigEntry from .entity import GeniusHeatingZone @@ -29,7 +29,7 @@ GH_ZONES = ["radiator", "wet underfloor"] async def async_setup_entry( hass: HomeAssistant, entry: GeniusHubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Genius Hub climate entities.""" diff --git a/homeassistant/components/geniushub/sensor.py b/homeassistant/components/geniushub/sensor.py index a558ad18672..de7c047e934 100644 --- a/homeassistant/components/geniushub/sensor.py +++ b/homeassistant/components/geniushub/sensor.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import GeniusHubConfigEntry @@ -26,7 +26,7 @@ GH_LEVEL_MAPPING = { async def async_setup_entry( hass: HomeAssistant, entry: GeniusHubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Genius Hub sensor entities.""" diff --git a/homeassistant/components/geniushub/switch.py b/homeassistant/components/geniushub/switch.py index 3af82eb4e92..890ca1578be 100644 --- a/homeassistant/components/geniushub/switch.py +++ b/homeassistant/components/geniushub/switch.py @@ -10,7 +10,7 @@ import voluptuous as vol from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import ATTR_DURATION, GeniusHubConfigEntry @@ -31,7 +31,7 @@ SET_SWITCH_OVERRIDE_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, entry: GeniusHubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Genius Hub switch entities.""" diff --git a/homeassistant/components/geniushub/water_heater.py b/homeassistant/components/geniushub/water_heater.py index 2807bd60611..60acf8f2cca 100644 --- a/homeassistant/components/geniushub/water_heater.py +++ b/homeassistant/components/geniushub/water_heater.py @@ -8,7 +8,7 @@ from homeassistant.components.water_heater import ( ) from homeassistant.const import STATE_OFF from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GeniusHubConfigEntry from .entity import GeniusHeatingZone @@ -36,7 +36,7 @@ GH_HEATERS = ["hot water temperature"] async def async_setup_entry( hass: HomeAssistant, entry: GeniusHubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Genius Hub water heater entities.""" diff --git a/homeassistant/components/geo_json_events/geo_location.py b/homeassistant/components/geo_json_events/geo_location.py index e0067bcfdc9..dce4aac1630 100644 --- a/homeassistant/components/geo_json_events/geo_location.py +++ b/homeassistant/components/geo_json_events/geo_location.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GeoJsonFeedEntityManager from .const import ( @@ -28,7 +28,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GeoJSON Events platform.""" manager: GeoJsonFeedEntityManager = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/geocaching/sensor.py b/homeassistant/components/geocaching/sensor.py index c082e5308a1..c7894afc5ac 100644 --- a/homeassistant/components/geocaching/sensor.py +++ b/homeassistant/components/geocaching/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import SensorEntity, SensorEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -64,7 +64,9 @@ SENSORS: tuple[GeocachingSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Geocaching sensor entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/geofency/device_tracker.py b/homeassistant/components/geofency/device_tracker.py index 2ad3c1772de..c74dad1cebb 100644 --- a/homeassistant/components/geofency/device_tracker.py +++ b/homeassistant/components/geofency/device_tracker.py @@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import DOMAIN as GF_DOMAIN, TRACKER_UPDATE @@ -16,7 +16,7 @@ from . import DOMAIN as GF_DOMAIN, TRACKER_UPDATE async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Geofency config entry.""" diff --git a/homeassistant/components/geonetnz_quakes/geo_location.py b/homeassistant/components/geonetnz_quakes/geo_location.py index 78313e102e0..96a1c3c09b2 100644 --- a/homeassistant/components/geonetnz_quakes/geo_location.py +++ b/homeassistant/components/geonetnz_quakes/geo_location.py @@ -14,7 +14,7 @@ from homeassistant.const import ATTR_TIME, UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import DistanceConverter from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM @@ -38,7 +38,9 @@ SOURCE = "geonetnz_quakes" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GeoNet NZ Quakes Feed platform.""" manager: GeonetnzQuakesFeedEntityManager = hass.data[DOMAIN][FEED][entry.entry_id] diff --git a/homeassistant/components/geonetnz_quakes/sensor.py b/homeassistant/components/geonetnz_quakes/sensor.py index 2fce3e93d12..b8a1e2dd4db 100644 --- a/homeassistant/components/geonetnz_quakes/sensor.py +++ b/homeassistant/components/geonetnz_quakes/sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN, FEED @@ -31,7 +31,9 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GeoNet NZ Quakes Feed platform.""" manager = hass.data[DOMAIN][FEED][entry.entry_id] diff --git a/homeassistant/components/geonetnz_volcano/sensor.py b/homeassistant/components/geonetnz_volcano/sensor.py index 980679cc64f..bde04acb895 100644 --- a/homeassistant/components/geonetnz_volcano/sensor.py +++ b/homeassistant/components/geonetnz_volcano/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE, UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from homeassistant.util.unit_conversion import DistanceConverter @@ -31,7 +31,9 @@ ATTR_LAST_UPDATE_SUCCESSFUL = "feed_last_update_successful" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GeoNet NZ Volcano Feed platform.""" manager = hass.data[DOMAIN][FEED][entry.entry_id] diff --git a/homeassistant/components/gios/sensor.py b/homeassistant/components/gios/sensor.py index 096ea838a41..67997a01dc6 100644 --- a/homeassistant/components/gios/sensor.py +++ b/homeassistant/components/gios/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, CONF_N from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -158,7 +158,9 @@ SENSOR_TYPES: tuple[GiosSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: GiosConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: GiosConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a GIOS entities from a config_entry.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/github/sensor.py b/homeassistant/components/github/sensor.py index a7ecb4ec8da..35985ed50d5 100644 --- a/homeassistant/components/github/sensor.py +++ b/homeassistant/components/github/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -139,7 +139,7 @@ SENSOR_DESCRIPTIONS: tuple[GitHubSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GithubConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up GitHub sensor based on a config entry.""" repositories = entry.runtime_data diff --git a/homeassistant/components/glances/sensor.py b/homeassistant/components/glances/sensor.py index 61d88b744bf..67f57ee0fbf 100644 --- a/homeassistant/components/glances/sensor.py +++ b/homeassistant/components/glances/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CPU_ICON, DOMAIN @@ -288,7 +288,7 @@ SENSOR_TYPES = { async def async_setup_entry( hass: HomeAssistant, config_entry: GlancesConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Glances sensors.""" diff --git a/homeassistant/components/goalzero/binary_sensor.py b/homeassistant/components/goalzero/binary_sensor.py index 6bd061879eb..86287dc35eb 100644 --- a/homeassistant/components/goalzero/binary_sensor.py +++ b/homeassistant/components/goalzero/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GoalZeroConfigEntry from .entity import GoalZeroEntity @@ -44,7 +44,7 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GoalZeroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Goal Zero Yeti sensor.""" async_add_entities( diff --git a/homeassistant/components/goalzero/sensor.py b/homeassistant/components/goalzero/sensor.py index f565c216745..7b5f8955947 100644 --- a/homeassistant/components/goalzero/sensor.py +++ b/homeassistant/components/goalzero/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import GoalZeroConfigEntry @@ -131,7 +131,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GoalZeroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Goal Zero Yeti sensor.""" async_add_entities( diff --git a/homeassistant/components/goalzero/switch.py b/homeassistant/components/goalzero/switch.py index daff4ee5fec..00a1ad936d8 100644 --- a/homeassistant/components/goalzero/switch.py +++ b/homeassistant/components/goalzero/switch.py @@ -6,7 +6,7 @@ from typing import Any, cast from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import GoalZeroConfigEntry from .entity import GoalZeroEntity @@ -30,7 +30,7 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: GoalZeroConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Goal Zero Yeti switch.""" async_add_entities( diff --git a/homeassistant/components/gogogate2/cover.py b/homeassistant/components/gogogate2/cover.py index 6bd38a0bc01..9492108d4b2 100644 --- a/homeassistant/components/gogogate2/cover.py +++ b/homeassistant/components/gogogate2/cover.py @@ -18,7 +18,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import cover_unique_id, get_data_update_coordinator from .coordinator import DeviceDataUpdateCoordinator @@ -28,7 +28,7 @@ from .entity import GoGoGate2Entity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the config entry.""" data_update_coordinator = get_data_update_coordinator(hass, config_entry) diff --git a/homeassistant/components/gogogate2/sensor.py b/homeassistant/components/gogogate2/sensor.py index c7740e24825..ce86ca9ac43 100644 --- a/homeassistant/components/gogogate2/sensor.py +++ b/homeassistant/components/gogogate2/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import get_data_update_coordinator, sensor_unique_id from .coordinator import DeviceDataUpdateCoordinator @@ -26,7 +26,7 @@ SENSOR_ID_WIRED = "WIRE" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the config entry.""" data_update_coordinator = get_data_update_coordinator(hass, config_entry) diff --git a/homeassistant/components/goodwe/button.py b/homeassistant/components/goodwe/button.py index d3d96a19a76..e93b23570db 100644 --- a/homeassistant/components/goodwe/button.py +++ b/homeassistant/components/goodwe/button.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, KEY_DEVICE_INFO, KEY_INVERTER @@ -37,7 +37,7 @@ SYNCHRONIZE_CLOCK = GoodweButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the inverter button entities from a config entry.""" inverter = hass.data[DOMAIN][config_entry.entry_id][KEY_INVERTER] diff --git a/homeassistant/components/goodwe/number.py b/homeassistant/components/goodwe/number.py index ce36bb35bf9..0a61ac19d64 100644 --- a/homeassistant/components/goodwe/number.py +++ b/homeassistant/components/goodwe/number.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, KEY_DEVICE_INFO, KEY_INVERTER @@ -87,7 +87,7 @@ NUMBERS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the inverter select entities from a config entry.""" inverter = hass.data[DOMAIN][config_entry.entry_id][KEY_INVERTER] diff --git a/homeassistant/components/goodwe/select.py b/homeassistant/components/goodwe/select.py index 4fa84c8401f..340e10bfa0f 100644 --- a/homeassistant/components/goodwe/select.py +++ b/homeassistant/components/goodwe/select.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, KEY_DEVICE_INFO, KEY_INVERTER @@ -40,7 +40,7 @@ OPERATION_MODE = SelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the inverter select entities from a config entry.""" inverter = hass.data[DOMAIN][config_entry.entry_id][KEY_INVERTER] diff --git a/homeassistant/components/goodwe/sensor.py b/homeassistant/components/goodwe/sensor.py index 5a88ac612da..d2dce2770e4 100644 --- a/homeassistant/components/goodwe/sensor.py +++ b/homeassistant/components/goodwe/sensor.py @@ -33,7 +33,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_point_in_time from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -166,7 +166,7 @@ TEXT_SENSOR = GoodweSensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GoodWe inverter from a config entry.""" entities: list[InverterSensor] = [] diff --git a/homeassistant/components/google/calendar.py b/homeassistant/components/google/calendar.py index 82208420b8c..4f8ffba1d19 100644 --- a/homeassistant/components/google/calendar.py +++ b/homeassistant/components/google/calendar.py @@ -43,7 +43,7 @@ from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.exceptions import HomeAssistantError, PlatformNotReady from homeassistant.helpers import entity_platform, entity_registry as er from homeassistant.helpers.entity import generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -192,7 +192,7 @@ def _get_entity_descriptions( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the google calendar platform.""" calendar_service = hass.data[DOMAIN][config_entry.entry_id][DATA_SERVICE] diff --git a/homeassistant/components/google_assistant/button.py b/homeassistant/components/google_assistant/button.py index cf3a42e251b..58560d7b8d1 100644 --- a/homeassistant/components/google_assistant/button.py +++ b/homeassistant/components/google_assistant/button.py @@ -8,7 +8,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import CONF_PROJECT_ID, CONF_SERVICE_ACCOUNT, DATA_CONFIG, DOMAIN @@ -18,7 +18,7 @@ from .http import GoogleConfig async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform.""" yaml_config: ConfigType = hass.data[DOMAIN][DATA_CONFIG] diff --git a/homeassistant/components/google_cloud/stt.py b/homeassistant/components/google_cloud/stt.py index ebca586d1a3..41c5a6710b7 100644 --- a/homeassistant/components/google_cloud/stt.py +++ b/homeassistant/components/google_cloud/stt.py @@ -22,7 +22,7 @@ from homeassistant.components.stt import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_SERVICE_ACCOUNT_INFO, @@ -38,7 +38,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Google Cloud speech platform via config entry.""" service_account_info = config_entry.data[CONF_SERVICE_ACCOUNT_INFO] diff --git a/homeassistant/components/google_cloud/tts.py b/homeassistant/components/google_cloud/tts.py index 7f22dda4faf..1f5f838b593 100644 --- a/homeassistant/components/google_cloud/tts.py +++ b/homeassistant/components/google_cloud/tts.py @@ -21,7 +21,7 @@ from homeassistant.components.tts import ( from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import ( @@ -88,7 +88,7 @@ async def async_get_engine( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Google Cloud text-to-speech.""" service_account_info = config_entry.data[CONF_SERVICE_ACCOUNT_INFO] diff --git a/homeassistant/components/google_drive/api.py b/homeassistant/components/google_drive/api.py index 475eddb6231..c21d42e0f3a 100644 --- a/homeassistant/components/google_drive/api.py +++ b/homeassistant/components/google_drive/api.py @@ -146,9 +146,10 @@ class DriveClient: backup.backup_id, backup_metadata, ) - await self._api.upload_file( + await self._api.resumable_upload_file( backup_metadata, open_stream, + backup.size, timeout=ClientTimeout(total=_UPLOAD_AND_DOWNLOAD_TIMEOUT), ) _LOGGER.debug( diff --git a/homeassistant/components/google_drive/manifest.json b/homeassistant/components/google_drive/manifest.json index a1abb9b260a..6b199a5d3eb 100644 --- a/homeassistant/components/google_drive/manifest.json +++ b/homeassistant/components/google_drive/manifest.json @@ -10,5 +10,5 @@ "iot_class": "cloud_polling", "loggers": ["google_drive_api"], "quality_scale": "platinum", - "requirements": ["python-google-drive-api==0.0.2"] + "requirements": ["python-google-drive-api==0.1.0"] } diff --git a/homeassistant/components/google_generative_ai_conversation/conversation.py b/homeassistant/components/google_generative_ai_conversation/conversation.py index 0f26c93da25..4e0dc92f140 100644 --- a/homeassistant/components/google_generative_ai_conversation/conversation.py +++ b/homeassistant/components/google_generative_ai_conversation/conversation.py @@ -19,7 +19,7 @@ from homeassistant.const import CONF_LLM_HASS_API, MATCH_ALL from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import chat_session, device_registry as dr, intent, llm -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_CHAT_MODEL, @@ -49,7 +49,7 @@ MAX_TOOL_ITERATIONS = 10 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up conversation entities.""" agent = GoogleGenerativeAIConversationEntity(config_entry) diff --git a/homeassistant/components/google_mail/sensor.py b/homeassistant/components/google_mail/sensor.py index c832104d719..781ea9192f0 100644 --- a/homeassistant/components/google_mail/sensor.py +++ b/homeassistant/components/google_mail/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( SensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GoogleMailConfigEntry from .entity import GoogleMailEntity @@ -29,7 +29,7 @@ SENSOR_TYPE = SensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: GoogleMailConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Google Mail sensor.""" async_add_entities([GoogleMailSensor(entry.runtime_data, SENSOR_TYPE)], True) diff --git a/homeassistant/components/google_pubsub/manifest.json b/homeassistant/components/google_pubsub/manifest.json index 9ea747898b2..d3e57c26e39 100644 --- a/homeassistant/components/google_pubsub/manifest.json +++ b/homeassistant/components/google_pubsub/manifest.json @@ -5,5 +5,5 @@ "documentation": "https://www.home-assistant.io/integrations/google_pubsub", "iot_class": "cloud_push", "quality_scale": "legacy", - "requirements": ["google-cloud-pubsub==2.23.0"] + "requirements": ["google-cloud-pubsub==2.28.0"] } diff --git a/homeassistant/components/google_tasks/todo.py b/homeassistant/components/google_tasks/todo.py index 6d1969d9a8a..d8e3c64bad8 100644 --- a/homeassistant/components/google_tasks/todo.py +++ b/homeassistant/components/google_tasks/todo.py @@ -12,7 +12,7 @@ from homeassistant.components.todo import ( TodoListEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -68,7 +68,7 @@ def _convert_api_item(item: dict[str, str]) -> TodoItem: async def async_setup_entry( hass: HomeAssistant, entry: GoogleTasksConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Google Tasks todo platform.""" async_add_entities( diff --git a/homeassistant/components/google_translate/tts.py b/homeassistant/components/google_translate/tts.py index 13e0ca4c273..201300d95b4 100644 --- a/homeassistant/components/google_translate/tts.py +++ b/homeassistant/components/google_translate/tts.py @@ -19,7 +19,7 @@ from homeassistant.components.tts import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import ( @@ -55,7 +55,7 @@ async def async_get_engine( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Google Translate speech platform via config entry.""" default_language = config_entry.data[CONF_LANG] diff --git a/homeassistant/components/google_travel_time/sensor.py b/homeassistant/components/google_travel_time/sensor.py index a3f9c236136..cac792dca53 100644 --- a/homeassistant/components/google_travel_time/sensor.py +++ b/homeassistant/components/google_travel_time/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( ) from homeassistant.core import CoreState, HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.location import find_coordinates from homeassistant.util import dt as dt_util @@ -55,7 +55,7 @@ def convert_time_to_utc(timestr): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Google travel time sensor entry.""" api_key = config_entry.data[CONF_API_KEY] diff --git a/homeassistant/components/govee_ble/binary_sensor.py b/homeassistant/components/govee_ble/binary_sensor.py index 7b7a1fb5a50..c3c71714e90 100644 --- a/homeassistant/components/govee_ble/binary_sensor.py +++ b/homeassistant/components/govee_ble/binary_sensor.py @@ -20,7 +20,7 @@ from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothProcessorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import GoveeBLEPassiveBluetoothDataProcessor @@ -76,7 +76,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the govee-ble BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/govee_ble/event.py b/homeassistant/components/govee_ble/event.py index 5e5aa6354be..03f74f37f6a 100644 --- a/homeassistant/components/govee_ble/event.py +++ b/homeassistant/components/govee_ble/event.py @@ -16,7 +16,7 @@ from homeassistant.components.event import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import GoveeBLEConfigEntry, format_event_dispatcher_name @@ -90,7 +90,7 @@ class GoveeBluetoothEventEntity(EventEntity): async def async_setup_entry( hass: HomeAssistant, entry: GoveeBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a govee ble event.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/govee_ble/sensor.py b/homeassistant/components/govee_ble/sensor.py index 383f50e5c46..fa0b828176c 100644 --- a/homeassistant/components/govee_ble/sensor.py +++ b/homeassistant/components/govee_ble/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import GoveeBLEConfigEntry, GoveeBLEPassiveBluetoothDataProcessor @@ -105,7 +105,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: GoveeBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Govee BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/govee_light_local/light.py b/homeassistant/components/govee_light_local/light.py index c7799a7ffc4..11ca53b53a1 100644 --- a/homeassistant/components/govee_light_local/light.py +++ b/homeassistant/components/govee_light_local/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER @@ -29,7 +29,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: GoveeLocalConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Govee light setup.""" diff --git a/homeassistant/components/gpsd/sensor.py b/homeassistant/components/gpsd/sensor.py index 86d3ab7cc04..cc2257c88f7 100644 --- a/homeassistant/components/gpsd/sensor.py +++ b/homeassistant/components/gpsd/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -156,7 +156,7 @@ SENSOR_TYPES: tuple[GpsdSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: GPSDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the GPSD component.""" async_add_entities( diff --git a/homeassistant/components/gpslogger/device_tracker.py b/homeassistant/components/gpslogger/device_tracker.py index 3ed68ed1b06..be38382098d 100644 --- a/homeassistant/components/gpslogger/device_tracker.py +++ b/homeassistant/components/gpslogger/device_tracker.py @@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import DOMAIN as GPL_DOMAIN, TRACKER_UPDATE @@ -26,7 +26,9 @@ from .const import ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure a dispatcher connection based on a config entry.""" diff --git a/homeassistant/components/gree/climate.py b/homeassistant/components/gree/climate.py index f197f21a4e1..f703ded1ea2 100644 --- a/homeassistant/components/gree/climate.py +++ b/homeassistant/components/gree/climate.py @@ -40,7 +40,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( COORDINATORS, @@ -88,7 +88,7 @@ SWING_MODES = [SWING_OFF, SWING_VERTICAL, SWING_HORIZONTAL, SWING_BOTH] async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Gree HVAC device from a config entry.""" diff --git a/homeassistant/components/gree/switch.py b/homeassistant/components/gree/switch.py index c1612ce99de..67dc10138d1 100644 --- a/homeassistant/components/gree/switch.py +++ b/homeassistant/components/gree/switch.py @@ -16,7 +16,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import COORDINATORS, DISPATCH_DEVICE_DISCOVERED, DOMAIN from .entity import GreeEntity @@ -93,7 +93,7 @@ GREE_SWITCHES: tuple[GreeSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Gree HVAC device from a config entry.""" diff --git a/homeassistant/components/group/binary_sensor.py b/homeassistant/components/group/binary_sensor.py index 06c810c2643..fa1777d5510 100644 --- a/homeassistant/components/group/binary_sensor.py +++ b/homeassistant/components/group/binary_sensor.py @@ -26,7 +26,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -70,7 +73,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Binary Sensor Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/button.py b/homeassistant/components/group/button.py index a18e074b775..c96d60067a1 100644 --- a/homeassistant/components/group/button.py +++ b/homeassistant/components/group/button.py @@ -22,7 +22,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -62,7 +65,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize button group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/cover.py b/homeassistant/components/group/cover.py index b2e5c6eef37..64baba6d1e8 100644 --- a/homeassistant/components/group/cover.py +++ b/homeassistant/components/group/cover.py @@ -37,7 +37,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -80,7 +83,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Cover Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/event.py b/homeassistant/components/group/event.py index e7f7938edf3..4009c788362 100644 --- a/homeassistant/components/group/event.py +++ b/homeassistant/components/group/event.py @@ -27,7 +27,10 @@ from homeassistant.const import ( ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -68,7 +71,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize event group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/fan.py b/homeassistant/components/group/fan.py index 87d9cb281f4..78745cb74c6 100644 --- a/homeassistant/components/group/fan.py +++ b/homeassistant/components/group/fan.py @@ -37,7 +37,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -82,7 +85,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Fan Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/light.py b/homeassistant/components/group/light.py index 228645df974..259832d6152 100644 --- a/homeassistant/components/group/light.py +++ b/homeassistant/components/group/light.py @@ -48,7 +48,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -98,7 +101,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Light Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/lock.py b/homeassistant/components/group/lock.py index e22e1ecd85c..7b460aa4632 100644 --- a/homeassistant/components/group/lock.py +++ b/homeassistant/components/group/lock.py @@ -28,7 +28,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -70,7 +73,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Lock Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/media_player.py b/homeassistant/components/group/media_player.py index ab8ee64b3e1..3371e56b1dc 100644 --- a/homeassistant/components/group/media_player.py +++ b/homeassistant/components/group/media_player.py @@ -54,7 +54,10 @@ from homeassistant.core import ( callback, ) from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -99,7 +102,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize MediaPlayer Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/notify.py b/homeassistant/components/group/notify.py index d6a9a6fd3c7..e710485c46f 100644 --- a/homeassistant/components/group/notify.py +++ b/homeassistant/components/group/notify.py @@ -29,7 +29,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -129,7 +129,7 @@ class GroupNotifyPlatform(BaseNotificationService): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Notify Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/sensor.py b/homeassistant/components/group/sensor.py index 4a3e191e511..9f0cc64ecf0 100644 --- a/homeassistant/components/group/sensor.py +++ b/homeassistant/components/group/sensor.py @@ -44,7 +44,10 @@ from homeassistant.helpers.entity import ( get_device_class, get_unit_of_measurement, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -130,7 +133,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Switch Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/group/switch.py b/homeassistant/components/group/switch.py index 101c42d354f..29e625ca8e3 100644 --- a/homeassistant/components/group/switch.py +++ b/homeassistant/components/group/switch.py @@ -26,7 +26,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .entity import GroupEntity @@ -71,7 +74,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Switch Group config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/growatt_server/sensor/__init__.py b/homeassistant/components/growatt_server/sensor/__init__.py index e77660e6a3a..2794403811d 100644 --- a/homeassistant/components/growatt_server/sensor/__init__.py +++ b/homeassistant/components/growatt_server/sensor/__init__.py @@ -14,7 +14,7 @@ from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_URL, CONF_USERNAM from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle, dt as dt_util from ..const import ( @@ -61,7 +61,7 @@ def get_device_list(api, config): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Growatt sensor.""" config = {**config_entry.data} diff --git a/homeassistant/components/guardian/binary_sensor.py b/homeassistant/components/guardian/binary_sensor.py index 84bb61da0e5..7d5f97bdb65 100644 --- a/homeassistant/components/guardian/binary_sensor.py +++ b/homeassistant/components/guardian/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GuardianData from .const import ( @@ -86,7 +86,9 @@ VALVE_CONTROLLER_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Guardian switches based on a config entry.""" data: GuardianData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/guardian/button.py b/homeassistant/components/guardian/button.py index f4881a9d94b..01bac63c6e3 100644 --- a/homeassistant/components/guardian/button.py +++ b/homeassistant/components/guardian/button.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_send -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GuardianData from .const import API_SYSTEM_DIAGNOSTICS, DOMAIN @@ -68,7 +68,9 @@ BUTTON_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Guardian buttons based on a config entry.""" data: GuardianData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/guardian/sensor.py b/homeassistant/components/guardian/sensor.py index 3f9547e652a..13dd8e01296 100644 --- a/homeassistant/components/guardian/sensor.py +++ b/homeassistant/components/guardian/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import GuardianData @@ -137,7 +137,9 @@ VALVE_CONTROLLER_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Guardian switches based on a config entry.""" data: GuardianData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/guardian/switch.py b/homeassistant/components/guardian/switch.py index fccf4f55a1f..a2c9ca282be 100644 --- a/homeassistant/components/guardian/switch.py +++ b/homeassistant/components/guardian/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GuardianData from .const import API_VALVE_STATUS, API_WIFI_STATUS, DOMAIN @@ -110,7 +110,9 @@ VALVE_CONTROLLER_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Guardian switches based on a config entry.""" data: GuardianData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/guardian/valve.py b/homeassistant/components/guardian/valve.py index 8c9749958bf..6847b3211c5 100644 --- a/homeassistant/components/guardian/valve.py +++ b/homeassistant/components/guardian/valve.py @@ -17,7 +17,7 @@ from homeassistant.components.valve import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import GuardianData from .const import API_VALVE_STATUS, DOMAIN @@ -109,7 +109,9 @@ VALVE_CONTROLLER_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Guardian switches based on a config entry.""" data: GuardianData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/habitica/__init__.py b/homeassistant/components/habitica/__init__.py index 1972e89c58a..217b5e739d1 100644 --- a/homeassistant/components/habitica/__init__.py +++ b/homeassistant/components/habitica/__init__.py @@ -9,9 +9,8 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.typing import ConfigType from .const import CONF_API_USER, DOMAIN, X_CLIENT -from .coordinator import HabiticaDataUpdateCoordinator +from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator from .services import async_setup_services -from .types import HabiticaConfigEntry CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) @@ -51,7 +50,7 @@ async def async_setup_entry( x_client=X_CLIENT, ) - coordinator = HabiticaDataUpdateCoordinator(hass, api) + coordinator = HabiticaDataUpdateCoordinator(hass, config_entry, api) await coordinator.async_config_entry_first_refresh() config_entry.runtime_data = coordinator diff --git a/homeassistant/components/habitica/binary_sensor.py b/homeassistant/components/habitica/binary_sensor.py index 5e3040e0606..c6f7ee0fb83 100644 --- a/homeassistant/components/habitica/binary_sensor.py +++ b/homeassistant/components/habitica/binary_sensor.py @@ -13,11 +13,11 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ASSETS_URL +from .coordinator import HabiticaConfigEntry from .entity import HabiticaBase -from .types import HabiticaConfigEntry PARALLEL_UPDATES = 1 @@ -56,7 +56,7 @@ BINARY_SENSOR_DESCRIPTIONS: tuple[HabiticaBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, config_entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the habitica binary sensors.""" diff --git a/homeassistant/components/habitica/button.py b/homeassistant/components/habitica/button.py index 450a5cdcf20..c57ba39fb6a 100644 --- a/homeassistant/components/habitica/button.py +++ b/homeassistant/components/habitica/button.py @@ -25,12 +25,15 @@ from homeassistant.components.button import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ASSETS_URL, DOMAIN -from .coordinator import HabiticaData, HabiticaDataUpdateCoordinator +from .coordinator import ( + HabiticaConfigEntry, + HabiticaData, + HabiticaDataUpdateCoordinator, +) from .entity import HabiticaBase -from .types import HabiticaConfigEntry PARALLEL_UPDATES = 1 @@ -277,7 +280,7 @@ CLASS_SKILLS: tuple[HabiticaButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons from a config entry.""" diff --git a/homeassistant/components/habitica/calendar.py b/homeassistant/components/habitica/calendar.py index f33f3c3c12f..b87a49670b0 100644 --- a/homeassistant/components/habitica/calendar.py +++ b/homeassistant/components/habitica/calendar.py @@ -18,11 +18,10 @@ from homeassistant.components.calendar import ( CalendarEvent, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util -from . import HabiticaConfigEntry -from .coordinator import HabiticaDataUpdateCoordinator +from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator from .entity import HabiticaBase from .util import build_rrule, get_recurrence_rule @@ -41,7 +40,7 @@ class HabiticaCalendar(StrEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the calendar platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/habitica/config_flow.py b/homeassistant/components/habitica/config_flow.py index 7a7f369cb09..91a13bd7918 100644 --- a/homeassistant/components/habitica/config_flow.py +++ b/homeassistant/components/habitica/config_flow.py @@ -33,7 +33,6 @@ from homeassistant.helpers.selector import ( TextSelectorType, ) -from . import HabiticaConfigEntry from .const import ( CONF_API_USER, DEFAULT_URL, @@ -47,6 +46,7 @@ from .const import ( SITE_DATA_URL, X_CLIENT, ) +from .coordinator import HabiticaConfigEntry STEP_ADVANCED_DATA_SCHEMA = vol.Schema( { diff --git a/homeassistant/components/habitica/coordinator.py b/homeassistant/components/habitica/coordinator.py index f97b98410bb..3c3a16f591a 100644 --- a/homeassistant/components/habitica/coordinator.py +++ b/homeassistant/components/habitica/coordinator.py @@ -11,6 +11,7 @@ from typing import Any from aiohttp import ClientError from habiticalib import ( + Avatar, ContentData, Habitica, HabiticaException, @@ -19,7 +20,6 @@ from habiticalib import ( TaskFilter, TooManyRequestsError, UserData, - UserStyles, ) from homeassistant.config_entries import ConfigEntry @@ -46,16 +46,22 @@ class HabiticaData: tasks: list[TaskData] +type HabiticaConfigEntry = ConfigEntry[HabiticaDataUpdateCoordinator] + + class HabiticaDataUpdateCoordinator(DataUpdateCoordinator[HabiticaData]): """Habitica Data Update Coordinator.""" config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant, habitica: Habitica) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, habitica: Habitica + ) -> None: """Initialize the Habitica data coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=60), request_refresh_debouncer=Debouncer( @@ -159,12 +165,10 @@ class HabiticaDataUpdateCoordinator(DataUpdateCoordinator[HabiticaData]): else: await self.async_request_refresh() - async def generate_avatar(self, user_styles: UserStyles) -> bytes: + async def generate_avatar(self, avatar: Avatar) -> bytes: """Generate Avatar.""" - avatar = BytesIO() - await self.habitica.generate_avatar( - fp=avatar, user_styles=user_styles, fmt="PNG" - ) + png = BytesIO() + await self.habitica.generate_avatar(fp=png, avatar=avatar, fmt="PNG") - return avatar.getvalue() + return png.getvalue() diff --git a/homeassistant/components/habitica/diagnostics.py b/homeassistant/components/habitica/diagnostics.py index abfa0f35c4b..40a6d75b366 100644 --- a/homeassistant/components/habitica/diagnostics.py +++ b/homeassistant/components/habitica/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.const import CONF_URL from homeassistant.core import HomeAssistant from .const import CONF_API_USER -from .types import HabiticaConfigEntry +from .coordinator import HabiticaConfigEntry async def async_get_config_entry_diagnostics( @@ -23,5 +23,5 @@ async def async_get_config_entry_diagnostics( CONF_URL: config_entry.data[CONF_URL], CONF_API_USER: config_entry.data[CONF_API_USER], }, - "habitica_data": habitica_data.to_dict()["data"], + "habitica_data": habitica_data.to_dict(omit_none=False)["data"], } diff --git a/homeassistant/components/habitica/entity.py b/homeassistant/components/habitica/entity.py index 932fec69f83..692ea5e5ac1 100644 --- a/homeassistant/components/habitica/entity.py +++ b/homeassistant/components/habitica/entity.py @@ -4,6 +4,8 @@ from __future__ import annotations from typing import TYPE_CHECKING +from yarl import URL + from homeassistant.const import CONF_NAME, CONF_URL from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity import EntityDescription @@ -36,6 +38,10 @@ class HabiticaBase(CoordinatorEntity[HabiticaDataUpdateCoordinator]): manufacturer=MANUFACTURER, model=NAME, name=coordinator.config_entry.data[CONF_NAME], - configuration_url=coordinator.config_entry.data[CONF_URL], + configuration_url=( + URL(coordinator.config_entry.data[CONF_URL]) + / "profile" + / coordinator.config_entry.unique_id + ), identifiers={(DOMAIN, coordinator.config_entry.unique_id)}, ) diff --git a/homeassistant/components/habitica/image.py b/homeassistant/components/habitica/image.py index f1dbbc64d41..f1ade2cac44 100644 --- a/homeassistant/components/habitica/image.py +++ b/homeassistant/components/habitica/image.py @@ -2,18 +2,16 @@ from __future__ import annotations -from dataclasses import asdict from enum import StrEnum -from habiticalib import UserStyles +from habiticalib import Avatar, extract_avatar from homeassistant.components.image import ImageEntity, ImageEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util -from . import HabiticaConfigEntry -from .coordinator import HabiticaDataUpdateCoordinator +from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator from .entity import HabiticaBase PARALLEL_UPDATES = 1 @@ -28,7 +26,7 @@ class HabiticaImageEntity(StrEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the habitica image platform.""" @@ -45,7 +43,7 @@ class HabiticaImage(HabiticaBase, ImageEntity): translation_key=HabiticaImageEntity.AVATAR, ) _attr_content_type = "image/png" - _current_appearance: UserStyles | None = None + _current_appearance: Avatar | None = None _cache: bytes | None = None def __init__( @@ -60,7 +58,7 @@ class HabiticaImage(HabiticaBase, ImageEntity): def _handle_coordinator_update(self) -> None: """Check if equipped gear and other things have changed since last avatar image generation.""" - new_appearance = UserStyles.from_dict(asdict(self.coordinator.data.user)) + new_appearance = extract_avatar(self.coordinator.data.user) if self._current_appearance != new_appearance: self._current_appearance = new_appearance diff --git a/homeassistant/components/habitica/manifest.json b/homeassistant/components/habitica/manifest.json index 9ea346a0dcb..a58bd1296e0 100644 --- a/homeassistant/components/habitica/manifest.json +++ b/homeassistant/components/habitica/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/habitica", "iot_class": "cloud_polling", "loggers": ["habiticalib"], - "requirements": ["habiticalib==0.3.5"] + "requirements": ["habiticalib==0.3.7"] } diff --git a/homeassistant/components/habitica/sensor.py b/homeassistant/components/habitica/sensor.py index 57c391f5c12..e715dd6d07b 100644 --- a/homeassistant/components/habitica/sensor.py +++ b/homeassistant/components/habitica/sensor.py @@ -28,18 +28,18 @@ from homeassistant.components.sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, async_delete_issue, ) from homeassistant.helpers.typing import StateType +from homeassistant.util import dt as dt_util from .const import ASSETS_URL, DOMAIN -from .coordinator import HabiticaDataUpdateCoordinator +from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator from .entity import HabiticaBase -from .types import HabiticaConfigEntry from .util import get_attribute_points, get_attributes_total, inventory_list _LOGGER = logging.getLogger(__name__) @@ -106,6 +106,20 @@ SENSOR_DESCRIPTIONS: tuple[HabiticaSensorEntityDescription, ...] = ( key=HabiticaSensorEntity.DISPLAY_NAME, translation_key=HabiticaSensorEntity.DISPLAY_NAME, value_fn=lambda user, _: user.profile.name, + attributes_fn=lambda user, _: { + "blurb": user.profile.blurb, + "joined": ( + dt_util.as_local(joined).date() + if (joined := user.auth.timestamps.created) + else None + ), + "last_login": ( + dt_util.as_local(last).date() + if (last := user.auth.timestamps.loggedin) + else None + ), + "total_logins": user.loginIncentives, + }, ), HabiticaSensorEntityDescription( key=HabiticaSensorEntity.HEALTH, @@ -306,7 +320,7 @@ def entity_used_in(hass: HomeAssistant, entity_id: str) -> list[str]: async def async_setup_entry( hass: HomeAssistant, config_entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the habitica sensors.""" @@ -394,6 +408,11 @@ class HabiticaSensor(HabiticaBase, SensorEntity): ): return SVG_CLASS[_class] + if self.entity_description.key is HabiticaSensorEntity.DISPLAY_NAME and ( + img_url := self.coordinator.data.user.profile.imageUrl + ): + return img_url + if entity_picture := self.entity_description.entity_picture: return ( entity_picture diff --git a/homeassistant/components/habitica/services.py b/homeassistant/components/habitica/services.py index 2537655dbfb..59bcc8cc7cc 100644 --- a/homeassistant/components/habitica/services.py +++ b/homeassistant/components/habitica/services.py @@ -62,7 +62,7 @@ from .const import ( SERVICE_START_QUEST, SERVICE_TRANSFORMATION, ) -from .types import HabiticaConfigEntry +from .coordinator import HabiticaConfigEntry _LOGGER = logging.getLogger(__name__) @@ -510,7 +510,9 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901 or (task.notes and keyword in task.notes.lower()) or any(keyword in item.text.lower() for item in task.checklist) ] - result: dict[str, Any] = {"tasks": [task.to_dict() for task in response]} + result: dict[str, Any] = { + "tasks": [task.to_dict(omit_none=False) for task in response] + } return result diff --git a/homeassistant/components/habitica/strings.json b/homeassistant/components/habitica/strings.json index 4d353cec40e..a5f64dca7c2 100644 --- a/homeassistant/components/habitica/strings.json +++ b/homeassistant/components/habitica/strings.json @@ -199,7 +199,21 @@ }, "sensor": { "display_name": { - "name": "Display name" + "name": "Display name", + "state_attributes": { + "blurb": { + "name": "About" + }, + "joined": { + "name": "Joined" + }, + "last_login": { + "name": "Last login" + }, + "total_logins": { + "name": "Total logins" + } + } }, "health": { "name": "Health", diff --git a/homeassistant/components/habitica/switch.py b/homeassistant/components/habitica/switch.py index ddc0db27108..fb98460f7e5 100644 --- a/homeassistant/components/habitica/switch.py +++ b/homeassistant/components/habitica/switch.py @@ -13,11 +13,14 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import HabiticaData, HabiticaDataUpdateCoordinator +from .coordinator import ( + HabiticaConfigEntry, + HabiticaData, + HabiticaDataUpdateCoordinator, +) from .entity import HabiticaBase -from .types import HabiticaConfigEntry PARALLEL_UPDATES = 1 @@ -52,7 +55,7 @@ SWTICH_DESCRIPTIONS: tuple[HabiticaSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches from a config entry.""" diff --git a/homeassistant/components/habitica/todo.py b/homeassistant/components/habitica/todo.py index c1786059300..fd93f551916 100644 --- a/homeassistant/components/habitica/todo.py +++ b/homeassistant/components/habitica/todo.py @@ -26,13 +26,12 @@ from homeassistant.components.todo import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import ASSETS_URL, DOMAIN -from .coordinator import HabiticaDataUpdateCoordinator +from .coordinator import HabiticaConfigEntry, HabiticaDataUpdateCoordinator from .entity import HabiticaBase -from .types import HabiticaConfigEntry from .util import next_due_date _LOGGER = logging.getLogger(__name__) @@ -52,7 +51,7 @@ class HabiticaTodoList(StrEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: HabiticaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor from a config entry created in the integrations UI.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/habitica/types.py b/homeassistant/components/habitica/types.py deleted file mode 100644 index 9789a65dc40..00000000000 --- a/homeassistant/components/habitica/types.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Types for Habitica integration.""" - -from enum import StrEnum - -from homeassistant.config_entries import ConfigEntry - -from .coordinator import HabiticaDataUpdateCoordinator - -type HabiticaConfigEntry = ConfigEntry[HabiticaDataUpdateCoordinator] - - -class HabiticaTaskType(StrEnum): - """Habitica Entities.""" - - HABIT = "habit" - DAILY = "daily" - TODO = "todo" - REWARD = "reward" diff --git a/homeassistant/components/harmony/remote.py b/homeassistant/components/harmony/remote.py index 43bf0a348c0..d09dc3ff7e8 100644 --- a/homeassistant/components/harmony/remote.py +++ b/homeassistant/components/harmony/remote.py @@ -22,7 +22,7 @@ from homeassistant.components.remote import ( from homeassistant.core import HassJob, HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import VolDictType @@ -56,7 +56,7 @@ HARMONY_CHANGE_CHANNEL_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, entry: HarmonyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Harmony config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/harmony/select.py b/homeassistant/components/harmony/select.py index 731b6836386..3f45a23e26e 100644 --- a/homeassistant/components/harmony/select.py +++ b/homeassistant/components/harmony/select.py @@ -6,7 +6,7 @@ import logging from homeassistant.components.select import SelectEntity from homeassistant.core import HassJob, HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ACTIVITY_POWER_OFF, DOMAIN from .data import HarmonyConfigEntry, HarmonyData @@ -21,7 +21,7 @@ TRANSLATABLE_POWER_OFF = "power_off" async def async_setup_entry( hass: HomeAssistant, entry: HarmonyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up harmony activities select.""" async_add_entities([HarmonyActivitySelect(entry.runtime_data)]) diff --git a/homeassistant/components/hassio/binary_sensor.py b/homeassistant/components/hassio/binary_sensor.py index 9d6e2ba19da..e7c7427d728 100644 --- a/homeassistant/components/hassio/binary_sensor.py +++ b/homeassistant/components/hassio/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ADDONS_COORDINATOR, ATTR_STARTED, ATTR_STATE, DATA_KEY_ADDONS from .entity import HassioAddonEntity @@ -38,7 +38,7 @@ ADDON_ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Binary sensor set up for Hass.io config entry.""" coordinator = hass.data[ADDONS_COORDINATOR] diff --git a/homeassistant/components/hassio/sensor.py b/homeassistant/components/hassio/sensor.py index 039bf483682..9b62faaabcf 100644 --- a/homeassistant/components/hassio/sensor.py +++ b/homeassistant/components/hassio/sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ADDONS_COORDINATOR, @@ -111,7 +111,7 @@ HOST_ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Sensor set up for Hass.io config entry.""" coordinator = hass.data[ADDONS_COORDINATOR] diff --git a/homeassistant/components/hassio/update.py b/homeassistant/components/hassio/update.py index 8e0585892f5..4ea703e87c3 100644 --- a/homeassistant/components/hassio/update.py +++ b/homeassistant/components/hassio/update.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ICON, ATTR_NAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ADDONS_COORDINATOR, @@ -47,7 +47,7 @@ ENTITY_DESCRIPTION = UpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Supervisor update based on a config entry.""" coordinator = hass.data[ADDONS_COORDINATOR] diff --git a/homeassistant/components/heos/manifest.json b/homeassistant/components/heos/manifest.json index 22dbbf4da28..72472760951 100644 --- a/homeassistant/components/heos/manifest.json +++ b/homeassistant/components/heos/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_push", "loggers": ["pyheos"], "quality_scale": "silver", - "requirements": ["pyheos==1.0.1"], + "requirements": ["pyheos==1.0.2"], "single_config_entry": true, "ssdp": [ { diff --git a/homeassistant/components/heos/media_player.py b/homeassistant/components/heos/media_player.py index b53cb94d8e7..4dbaead67a7 100644 --- a/homeassistant/components/heos/media_player.py +++ b/homeassistant/components/heos/media_player.py @@ -35,7 +35,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utcnow @@ -88,7 +88,9 @@ HA_HEOS_REPEAT_TYPE_MAP = {v: k for k, v in HEOS_HA_REPEAT_TYPE_MAP.items()} async def async_setup_entry( - hass: HomeAssistant, entry: HeosConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: HeosConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add media players for a config entry.""" devices = [ diff --git a/homeassistant/components/here_travel_time/__init__.py b/homeassistant/components/here_travel_time/__init__.py index 1b99ba64827..132b12de4ce 100644 --- a/homeassistant/components/here_travel_time/__init__.py +++ b/homeassistant/components/here_travel_time/__init__.py @@ -56,7 +56,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b else: cls = HERERoutingDataUpdateCoordinator - data_coordinator = cls(hass, api_key, here_travel_time_config) + data_coordinator = cls(hass, config_entry, api_key, here_travel_time_config) hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = data_coordinator async def _async_update_at_start(_: HomeAssistant) -> None: diff --git a/homeassistant/components/here_travel_time/coordinator.py b/homeassistant/components/here_travel_time/coordinator.py index 65e1305e44e..a3345e78e4e 100644 --- a/homeassistant/components/here_travel_time/coordinator.py +++ b/homeassistant/components/here_travel_time/coordinator.py @@ -25,6 +25,7 @@ from here_transit import ( ) import voluptuous as vol +from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv @@ -44,9 +45,12 @@ _LOGGER = logging.getLogger(__name__) class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData]): """here_routing DataUpdateCoordinator.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, api_key: str, config: HERETravelTimeConfig, ) -> None: @@ -54,6 +58,7 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData] super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), ) @@ -168,9 +173,12 @@ class HERETransitDataUpdateCoordinator( ): """HERETravelTime DataUpdateCoordinator.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, api_key: str, config: HERETravelTimeConfig, ) -> None: @@ -178,6 +186,7 @@ class HERETransitDataUpdateCoordinator( super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), ) diff --git a/homeassistant/components/here_travel_time/sensor.py b/homeassistant/components/here_travel_time/sensor.py index 4d7566ef2e2..0f0cbb7d3cb 100644 --- a/homeassistant/components/here_travel_time/sensor.py +++ b/homeassistant/components/here_travel_time/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -78,7 +78,7 @@ def sensor_descriptions(travel_mode: str) -> tuple[SensorEntityDescription, ...] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add HERE travel time entities from a config_entry.""" diff --git a/homeassistant/components/hisense_aehw4a1/climate.py b/homeassistant/components/hisense_aehw4a1/climate.py index 1dc1eaabcaa..cd9f3666e08 100644 --- a/homeassistant/components/hisense_aehw4a1/climate.py +++ b/homeassistant/components/hisense_aehw4a1/climate.py @@ -28,7 +28,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import CONF_IP_ADDRESS, DOMAIN @@ -121,7 +121,7 @@ def _build_entity(device): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the AEH-W4A1 climate platform.""" # Priority 1: manual config diff --git a/homeassistant/components/history_stats/sensor.py b/homeassistant/components/history_stats/sensor.py index b25daf56598..6935b13bc3d 100644 --- a/homeassistant/components/history_stats/sensor.py +++ b/homeassistant/components/history_stats/sensor.py @@ -27,7 +27,10 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device import async_device_info_to_link_from_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -116,7 +119,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: HistoryStatsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the History stats sensor entry.""" diff --git a/homeassistant/components/hive/alarm_control_panel.py b/homeassistant/components/hive/alarm_control_panel.py index 2b196ce820b..c2fe47642a0 100644 --- a/homeassistant/components/hive/alarm_control_panel.py +++ b/homeassistant/components/hive/alarm_control_panel.py @@ -11,7 +11,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HiveEntity @@ -27,7 +27,9 @@ HIVETOHA = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hive/binary_sensor.py b/homeassistant/components/hive/binary_sensor.py index d2938896f92..2076d592a7c 100644 --- a/homeassistant/components/hive/binary_sensor.py +++ b/homeassistant/components/hive/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HiveEntity @@ -68,7 +68,9 @@ SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hive/climate.py b/homeassistant/components/hive/climate.py index c76379cf940..bd7553faa1a 100644 --- a/homeassistant/components/hive/climate.py +++ b/homeassistant/components/hive/climate.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import ( @@ -58,7 +58,9 @@ _LOGGER = logging.getLogger() async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hive/light.py b/homeassistant/components/hive/light.py index e941087c6fb..80a81583429 100644 --- a/homeassistant/components/hive/light.py +++ b/homeassistant/components/hive/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import refresh_system @@ -29,7 +29,9 @@ SCAN_INTERVAL = timedelta(seconds=15) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hive/sensor.py b/homeassistant/components/hive/sensor.py index 00a2116e268..0609e43c4a9 100644 --- a/homeassistant/components/hive/sensor.py +++ b/homeassistant/components/hive/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -89,7 +89,9 @@ SENSOR_TYPES: tuple[HiveSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" hive = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/hive/switch.py b/homeassistant/components/hive/switch.py index 1421616db57..d4fefea5a56 100644 --- a/homeassistant/components/hive/switch.py +++ b/homeassistant/components/hive/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import ATTR_MODE, DOMAIN @@ -33,7 +33,9 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hive/water_heater.py b/homeassistant/components/hive/water_heater.py index b038739d2ad..5f0a3d0f3fa 100644 --- a/homeassistant/components/hive/water_heater.py +++ b/homeassistant/components/hive/water_heater.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import ( @@ -45,7 +45,9 @@ SUPPORT_WATER_HEATER = [STATE_ECO, STATE_ON, STATE_OFF] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hive thermostat based on a config entry.""" diff --git a/homeassistant/components/hko/__init__.py b/homeassistant/components/hko/__init__.py index 5b06644580e..b7e21f731d8 100644 --- a/homeassistant/components/hko/__init__.py +++ b/homeassistant/components/hko/__init__.py @@ -25,7 +25,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: )[KEY_DISTRICT] websession = async_get_clientsession(hass) - coordinator = HKOUpdateCoordinator(hass, websession, district, location) + coordinator = HKOUpdateCoordinator(hass, entry, websession, district, location) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/hko/coordinator.py b/homeassistant/components/hko/coordinator.py index 566ba5dcf5e..5845e8831fe 100644 --- a/homeassistant/components/hko/coordinator.py +++ b/homeassistant/components/hko/coordinator.py @@ -26,6 +26,7 @@ from homeassistant.components.weather import ( ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_TIME, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -69,8 +70,15 @@ _LOGGER = logging.getLogger(__name__) class HKOUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """HKO Update Coordinator.""" + config_entry: ConfigEntry + def __init__( - self, hass: HomeAssistant, session: ClientSession, district: str, location: str + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + session: ClientSession, + district: str, + location: str, ) -> None: """Update data via library.""" self.location = location @@ -80,6 +88,7 @@ class HKOUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(minutes=15), ) diff --git a/homeassistant/components/hko/weather.py b/homeassistant/components/hko/weather.py index 6d3d12d8ab4..e746d4304d3 100644 --- a/homeassistant/components/hko/weather.py +++ b/homeassistant/components/hko/weather.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -28,7 +28,7 @@ from .coordinator import HKOUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a HKO weather entity from a config_entry.""" assert config_entry.unique_id is not None diff --git a/homeassistant/components/hlk_sw16/switch.py b/homeassistant/components/hlk_sw16/switch.py index 3911dd6eab9..c6e6f7f5201 100644 --- a/homeassistant/components/hlk_sw16/switch.py +++ b/homeassistant/components/hlk_sw16/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DATA_DEVICE_REGISTER from .const import DOMAIN @@ -26,7 +26,9 @@ def devices_from_entities(hass, entry): async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HLK-SW16 platform.""" async_add_entities(devices_from_entities(hass, entry)) diff --git a/homeassistant/components/holiday/calendar.py b/homeassistant/components/holiday/calendar.py index 6dccd972164..1c01319129b 100644 --- a/homeassistant/components/holiday/calendar.py +++ b/homeassistant/components/holiday/calendar.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_COUNTRY from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.util import dt as dt_util @@ -69,7 +69,7 @@ def _get_obj_holidays_and_language( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Holiday Calendar config entry.""" country: str = config_entry.data[CONF_COUNTRY] diff --git a/homeassistant/components/home_connect/binary_sensor.py b/homeassistant/components/home_connect/binary_sensor.py index 67e3d56e713..c0e978dbba4 100644 --- a/homeassistant/components/home_connect/binary_sensor.py +++ b/homeassistant/components/home_connect/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( 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 AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -133,7 +133,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect binary sensor.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/common.py b/homeassistant/components/home_connect/common.py index 6bd098a76fc..c27230c01d8 100644 --- a/homeassistant/components/home_connect/common.py +++ b/homeassistant/components/home_connect/common.py @@ -6,7 +6,7 @@ from typing import cast from aiohomeconnect.model import EventKey -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import HomeConnectApplianceData, HomeConnectConfigEntry from .entity import HomeConnectEntity @@ -18,7 +18,7 @@ def _handle_paired_or_connected_appliance( get_entities_for_appliance: Callable[ [HomeConnectConfigEntry, HomeConnectApplianceData], list[HomeConnectEntity] ], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Handle a new paired appliance or an appliance that has been connected. @@ -59,7 +59,7 @@ def setup_home_connect_entry( get_entities_for_appliance: Callable[ [HomeConnectConfigEntry, HomeConnectApplianceData], list[HomeConnectEntity] ], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the callbacks for paired and depaired appliances.""" known_entity_unique_ids: dict[str, str] = {} diff --git a/homeassistant/components/home_connect/config_flow.py b/homeassistant/components/home_connect/config_flow.py index 444ea24cb6b..02a3ca29335 100644 --- a/homeassistant/components/home_connect/config_flow.py +++ b/homeassistant/components/home_connect/config_flow.py @@ -1,7 +1,12 @@ """Config flow for Home Connect.""" +from collections.abc import Mapping import logging +from typing import Any +import voluptuous as vol + +from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlowResult from homeassistant.helpers import config_entry_oauth2_flow from .const import DOMAIN @@ -20,3 +25,29 @@ class OAuth2FlowHandler( def logger(self) -> logging.Logger: """Return logger.""" return logging.getLogger(__name__) + + async def async_step_reauth( + self, entry_data: Mapping[str, Any] + ) -> ConfigFlowResult: + """Perform reauth upon an API authentication error.""" + return await self.async_step_reauth_confirm() + + async def async_step_reauth_confirm( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Dialog that informs the user that reauth is required.""" + if user_input is None: + return self.async_show_form( + step_id="reauth_confirm", + data_schema=vol.Schema({}), + ) + return await self.async_step_user() + + async def async_oauth_create_entry(self, data: dict) -> ConfigFlowResult: + """Create an oauth config entry or update existing entry for reauth.""" + if self.source == SOURCE_REAUTH: + return self.async_update_reload_and_abort( + self._get_reauth_entry(), + data_updates=data, + ) + return await super().async_oauth_create_entry(data) diff --git a/homeassistant/components/home_connect/coordinator.py b/homeassistant/components/home_connect/coordinator.py index 68652936872..da47d8ec91c 100644 --- a/homeassistant/components/home_connect/coordinator.py +++ b/homeassistant/components/home_connect/coordinator.py @@ -1,5 +1,7 @@ """Coordinator for Home Connect.""" +from __future__ import annotations + import asyncio from collections import defaultdict from collections.abc import Callable @@ -24,12 +26,14 @@ from aiohomeconnect.model.error import ( HomeConnectApiError, HomeConnectError, HomeConnectRequestError, + UnauthorizedError, ) from aiohomeconnect.model.program import EnumerateProgram from propcache.api import cached_property from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback +from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -53,7 +57,7 @@ class HomeConnectApplianceData: settings: dict[SettingKey, GetSetting] status: dict[StatusKey, Status] - def update(self, other: "HomeConnectApplianceData") -> None: + def update(self, other: HomeConnectApplianceData) -> None: """Update data with data from other instance.""" self.events.update(other.events) self.info.connected = other.info.connected @@ -268,6 +272,12 @@ class HomeConnectCoordinator( """Fetch data from Home Connect.""" try: appliances = await self.client.get_home_appliances() + except UnauthorizedError as error: + raise ConfigEntryAuthFailed( + translation_domain=DOMAIN, + translation_key="auth_error", + translation_placeholders=get_dict_from_home_connect_error(error), + ) from error except HomeConnectError as error: raise UpdateFailed( translation_domain=DOMAIN, diff --git a/homeassistant/components/home_connect/light.py b/homeassistant/components/home_connect/light.py index 05c154d9153..9f9016855e9 100644 --- a/homeassistant/components/home_connect/light.py +++ b/homeassistant/components/home_connect/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .common import setup_home_connect_entry @@ -94,7 +94,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect light.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/number.py b/homeassistant/components/home_connect/number.py index aa0c4e4ae3f..b0adea508c1 100644 --- a/homeassistant/components/home_connect/number.py +++ b/homeassistant/components/home_connect/number.py @@ -13,7 +13,7 @@ from homeassistant.components.number import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import setup_home_connect_entry from .const import ( @@ -94,7 +94,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect number.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/select.py b/homeassistant/components/home_connect/select.py index 13518c5dea2..165842abf1c 100644 --- a/homeassistant/components/home_connect/select.py +++ b/homeassistant/components/home_connect/select.py @@ -12,7 +12,7 @@ from aiohomeconnect.model.program import Execution from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import setup_home_connect_entry from .const import APPLIANCES_WITH_PROGRAMS, DOMAIN, SVE_TRANSLATION_PLACEHOLDER_PROGRAM @@ -88,7 +88,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect select entities.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/sensor.py b/homeassistant/components/home_connect/sensor.py index 545df1d68b6..971f87d72fd 100644 --- a/homeassistant/components/home_connect/sensor.py +++ b/homeassistant/components/home_connect/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTime, UnitOfVolume from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util, slugify from .common import setup_home_connect_entry @@ -272,7 +272,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect sensor.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/strings.json b/homeassistant/components/home_connect/strings.json index d163d04a6f7..d07cfcdf854 100644 --- a/homeassistant/components/home_connect/strings.json +++ b/homeassistant/components/home_connect/strings.json @@ -7,9 +7,14 @@ "step": { "pick_implementation": { "title": "[%key:common::config_flow::title::oauth2_pick_implementation%]" + }, + "reauth_confirm": { + "title": "[%key:common::config_flow::title::reauth%]", + "description": "The Home Connect integration needs to re-authenticate your account" } }, "abort": { + "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", "missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]", "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]", "oauth_error": "[%key:common::config_flow::abort::oauth2_error%]", @@ -22,6 +27,9 @@ } }, "exceptions": { + "auth_error": { + "message": "Authentication error: {error}. Please, re-authenticate your account" + }, "appliance_not_found": { "message": "Appliance for device ID {device_id} not found" }, diff --git a/homeassistant/components/home_connect/switch.py b/homeassistant/components/home_connect/switch.py index e7fcd29e191..7dc375f430d 100644 --- a/homeassistant/components/home_connect/switch.py +++ b/homeassistant/components/home_connect/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -130,7 +130,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect switch.""" setup_home_connect_entry( diff --git a/homeassistant/components/home_connect/time.py b/homeassistant/components/home_connect/time.py index 48f651857d2..3d16dd37e21 100644 --- a/homeassistant/components/home_connect/time.py +++ b/homeassistant/components/home_connect/time.py @@ -9,7 +9,7 @@ from aiohomeconnect.model.error import HomeConnectError from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import setup_home_connect_entry from .const import ( @@ -46,7 +46,7 @@ def _get_entities_for_appliance( async def async_setup_entry( hass: HomeAssistant, entry: HomeConnectConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Home Connect switch.""" setup_home_connect_entry( diff --git a/homeassistant/components/homeassistant_alerts/coordinator.py b/homeassistant/components/homeassistant_alerts/coordinator.py index a81824d2376..542ebf857df 100644 --- a/homeassistant/components/homeassistant_alerts/coordinator.py +++ b/homeassistant/components/homeassistant_alerts/coordinator.py @@ -40,6 +40,7 @@ class AlertUpdateCoordinator(DataUpdateCoordinator[dict[str, IntegrationAlert]]) super().__init__( hass, _LOGGER, + config_entry=None, name=DOMAIN, update_interval=UPDATE_INTERVAL, ) diff --git a/homeassistant/components/homee/cover.py b/homeassistant/components/homee/cover.py index 2e6f7babaff..a3695f7ade6 100644 --- a/homeassistant/components/homee/cover.py +++ b/homeassistant/components/homee/cover.py @@ -14,7 +14,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HomeeConfigEntry from .entity import HomeeNodeEntity @@ -78,7 +78,7 @@ def get_device_class(node: HomeeNode) -> CoverDeviceClass | None: async def async_setup_entry( hass: HomeAssistant, config_entry: HomeeConfigEntry, - async_add_devices: AddEntitiesCallback, + async_add_devices: AddConfigEntryEntitiesCallback, ) -> None: """Add the homee platform for the cover integration.""" diff --git a/homeassistant/components/homee/manifest.json b/homeassistant/components/homee/manifest.json index d85ba25b6e7..e4622222be1 100644 --- a/homeassistant/components/homee/manifest.json +++ b/homeassistant/components/homee/manifest.json @@ -8,5 +8,5 @@ "iot_class": "local_push", "loggers": ["homee"], "quality_scale": "bronze", - "requirements": ["pyHomee==1.2.5"] + "requirements": ["pyHomee==1.2.7"] } diff --git a/homeassistant/components/homee/sensor.py b/homeassistant/components/homee/sensor.py index da01c2aa5b9..237b80915aa 100644 --- a/homeassistant/components/homee/sensor.py +++ b/homeassistant/components/homee/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HomeeConfigEntry from .const import ( @@ -262,7 +262,7 @@ NODE_SENSOR_DESCRIPTIONS: tuple[HomeeNodeSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: HomeeConfigEntry, - async_add_devices: AddEntitiesCallback, + async_add_devices: AddConfigEntryEntitiesCallback, ) -> None: """Add the homee platform for the sensor components.""" diff --git a/homeassistant/components/homekit_controller/alarm_control_panel.py b/homeassistant/components/homekit_controller/alarm_control_panel.py index b17f122dfa5..a0342203e4a 100644 --- a/homeassistant/components/homekit_controller/alarm_control_panel.py +++ b/homeassistant/components/homekit_controller/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_BATTERY_LEVEL, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -40,7 +40,7 @@ TARGET_STATE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit alarm control panel.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/binary_sensor.py b/homeassistant/components/homekit_controller/binary_sensor.py index 26e19c8944a..1c80da3cc9c 100644 --- a/homeassistant/components/homekit_controller/binary_sensor.py +++ b/homeassistant/components/homekit_controller/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -156,7 +156,7 @@ REJECT_CHAR_BY_TYPE = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit lighting.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/button.py b/homeassistant/components/homekit_controller/button.py index ac2133f61ca..730b3c8425d 100644 --- a/homeassistant/components/homekit_controller/button.py +++ b/homeassistant/components/homekit_controller/button.py @@ -20,7 +20,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -66,7 +66,7 @@ BUTTON_ENTITIES: dict[str, HomeKitButtonEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit buttons.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/camera.py b/homeassistant/components/homekit_controller/camera.py index 4332032867a..36bf30e5bab 100644 --- a/homeassistant/components/homekit_controller/camera.py +++ b/homeassistant/components/homekit_controller/camera.py @@ -9,7 +9,7 @@ from homeassistant.components.camera import Camera from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -39,7 +39,7 @@ class HomeKitCamera(AccessoryEntity, Camera): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit sensors.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/climate.py b/homeassistant/components/homekit_controller/climate.py index cbf4ad61c2f..7341bbd3a4a 100644 --- a/homeassistant/components/homekit_controller/climate.py +++ b/homeassistant/components/homekit_controller/climate.py @@ -41,7 +41,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -111,7 +111,7 @@ HASS_FAN_MODE_TO_HOMEKIT_ROTATION = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit climate.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/cover.py b/homeassistant/components/homekit_controller/cover.py index 4fff32002e2..5ea990f55e6 100644 --- a/homeassistant/components/homekit_controller/cover.py +++ b/homeassistant/components/homekit_controller/cover.py @@ -19,7 +19,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -51,7 +51,7 @@ CURRENT_WINDOW_STATE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit covers.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/event.py b/homeassistant/components/homekit_controller/event.py index 890c12c9bab..b90d561d60d 100644 --- a/homeassistant/components/homekit_controller/event.py +++ b/homeassistant/components/homekit_controller/event.py @@ -14,7 +14,7 @@ from homeassistant.components.event import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -86,7 +86,7 @@ class HomeKitEventEntity(BaseCharacteristicEntity, EventEntity): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit event.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/fan.py b/homeassistant/components/homekit_controller/fan.py index b7f1842392b..9ba476a0ef3 100644 --- a/homeassistant/components/homekit_controller/fan.py +++ b/homeassistant/components/homekit_controller/fan.py @@ -17,7 +17,7 @@ from homeassistant.components.fan import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -210,7 +210,7 @@ ENTITY_TYPES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit fans.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/humidifier.py b/homeassistant/components/homekit_controller/humidifier.py index b2b0e0b1026..7906d5ec52b 100644 --- a/homeassistant/components/homekit_controller/humidifier.py +++ b/homeassistant/components/homekit_controller/humidifier.py @@ -20,7 +20,7 @@ from homeassistant.components.humidifier import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -165,7 +165,7 @@ class HomeKitDehumidifier(HomeKitBaseHumidifier): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit humidifer.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/light.py b/homeassistant/components/homekit_controller/light.py index 04c75731731..5409df7c1a8 100644 --- a/homeassistant/components/homekit_controller/light.py +++ b/homeassistant/components/homekit_controller/light.py @@ -20,7 +20,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import KNOWN_DEVICES @@ -31,7 +31,7 @@ from .entity import HomeKitEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit lightbulb.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/lock.py b/homeassistant/components/homekit_controller/lock.py index 98974c4a514..06b8382c8af 100644 --- a/homeassistant/components/homekit_controller/lock.py +++ b/homeassistant/components/homekit_controller/lock.py @@ -11,7 +11,7 @@ from homeassistant.components.lock import LockEntity, LockState from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -32,7 +32,7 @@ REVERSED_TARGET_STATE_MAP = {v: k for k, v in TARGET_STATE_MAP.items()} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit lock.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/media_player.py b/homeassistant/components/homekit_controller/media_player.py index 4232d1b7649..5315c7c89f3 100644 --- a/homeassistant/components/homekit_controller/media_player.py +++ b/homeassistant/components/homekit_controller/media_player.py @@ -22,7 +22,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KNOWN_DEVICES from .connection import HKDevice @@ -41,7 +41,7 @@ HK_TO_HA_STATE = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit television.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/number.py b/homeassistant/components/homekit_controller/number.py index 340d31c91ae..96d6707d8eb 100644 --- a/homeassistant/components/homekit_controller/number.py +++ b/homeassistant/components/homekit_controller/number.py @@ -18,7 +18,7 @@ from homeassistant.components.number import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -68,7 +68,7 @@ NUMBER_ENTITIES: dict[str, NumberEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit numbers.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/select.py b/homeassistant/components/homekit_controller/select.py index f672f293122..f174743b12f 100644 --- a/homeassistant/components/homekit_controller/select.py +++ b/homeassistant/components/homekit_controller/select.py @@ -15,7 +15,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -148,7 +148,7 @@ class EcobeeModeSelect(BaseHomeKitSelect): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit select entities.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/sensor.py b/homeassistant/components/homekit_controller/sensor.py index 059be5bad99..c97b45152e0 100644 --- a/homeassistant/components/homekit_controller/sensor.py +++ b/homeassistant/components/homekit_controller/sensor.py @@ -43,7 +43,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -640,7 +640,7 @@ class RSSISensor(HomeKitEntity, SensorEntity): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit sensors.""" hkid = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homekit_controller/switch.py b/homeassistant/components/homekit_controller/switch.py index 5abed2a5c79..c24a4edf545 100644 --- a/homeassistant/components/homekit_controller/switch.py +++ b/homeassistant/components/homekit_controller/switch.py @@ -17,7 +17,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNOWN_DEVICES @@ -224,7 +224,7 @@ ENTITY_TYPES: dict[str, type[HomeKitSwitch | HomeKitFaucet | HomeKitValve]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homekit switches.""" hkid: str = config_entry.data["AccessoryPairingID"] diff --git a/homeassistant/components/homematicip_cloud/alarm_control_panel.py b/homeassistant/components/homematicip_cloud/alarm_control_panel.py index 4241316c2a4..d5b084644e3 100644 --- a/homeassistant/components/homematicip_cloud/alarm_control_panel.py +++ b/homeassistant/components/homematicip_cloud/alarm_control_panel.py @@ -14,7 +14,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .hap import AsyncHome, HomematicipHAP @@ -27,7 +27,7 @@ CONST_ALARM_CONTROL_PANEL_NAME = "HmIP Alarm Control Panel" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP alrm control panel from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index 38590e4505b..f0cd3732718 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -37,7 +37,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -76,7 +76,7 @@ SAM_DEVICE_ATTRIBUTES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP Cloud binary sensor from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/button.py b/homeassistant/components/homematicip_cloud/button.py index 244be47d7f6..fedc271714c 100644 --- a/homeassistant/components/homematicip_cloud/button.py +++ b/homeassistant/components/homematicip_cloud/button.py @@ -7,7 +7,7 @@ from homematicip.aio.device import AsyncWallMountedGarageDoorController from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -17,7 +17,7 @@ from .hap import HomematicipHAP async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP button from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/climate.py b/homeassistant/components/homematicip_cloud/climate.py index e7132fac83c..35bd18ff438 100644 --- a/homeassistant/components/homematicip_cloud/climate.py +++ b/homeassistant/components/homematicip_cloud/climate.py @@ -29,7 +29,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -57,7 +57,7 @@ HMIP_ECO_CM = "ECO" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP climate from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/cover.py b/homeassistant/components/homematicip_cloud/cover.py index 1db536afd4f..27a84abb572 100644 --- a/homeassistant/components/homematicip_cloud/cover.py +++ b/homeassistant/components/homematicip_cloud/cover.py @@ -23,7 +23,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -38,7 +38,7 @@ HMIP_SLATS_CLOSED = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP cover from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/event.py b/homeassistant/components/homematicip_cloud/event.py index 8fb558b2b34..654f56bb47f 100644 --- a/homeassistant/components/homematicip_cloud/event.py +++ b/homeassistant/components/homematicip_cloud/event.py @@ -12,7 +12,7 @@ from homeassistant.components.event import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -37,7 +37,7 @@ EVENT_DESCRIPTIONS = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP cover from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/light.py b/homeassistant/components/homematicip_cloud/light.py index cf051103a10..ad946809fd4 100644 --- a/homeassistant/components/homematicip_cloud/light.py +++ b/homeassistant/components/homematicip_cloud/light.py @@ -30,7 +30,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -40,7 +40,7 @@ from .hap import HomematicipHAP async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP Cloud lights from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/lock.py b/homeassistant/components/homematicip_cloud/lock.py index b00f42fc844..a054e95a80d 100644 --- a/homeassistant/components/homematicip_cloud/lock.py +++ b/homeassistant/components/homematicip_cloud/lock.py @@ -11,7 +11,7 @@ from homematicip.base.enums import LockState, MotorState from homeassistant.components.lock import LockEntity, LockEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -37,7 +37,7 @@ DEVICE_DLD_ATTRIBUTES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP locks from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/sensor.py b/homeassistant/components/homematicip_cloud/sensor.py index 9ed9b33d7c7..0280f5bc7d5 100644 --- a/homeassistant/components/homematicip_cloud/sensor.py +++ b/homeassistant/components/homematicip_cloud/sensor.py @@ -57,7 +57,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -96,7 +96,7 @@ ILLUMINATION_DEVICE_ATTRIBUTES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP Cloud sensors from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/switch.py b/homeassistant/components/homematicip_cloud/switch.py index 70bf14631cb..a9aa1c664d7 100644 --- a/homeassistant/components/homematicip_cloud/switch.py +++ b/homeassistant/components/homematicip_cloud/switch.py @@ -25,7 +25,7 @@ from homematicip.aio.group import AsyncExtendedLinkedSwitchingGroup, AsyncSwitch from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import ATTR_GROUP_MEMBER_UNREACHABLE, HomematicipGenericEntity @@ -35,7 +35,7 @@ from .hap import HomematicipHAP async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP switch from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homematicip_cloud/weather.py b/homeassistant/components/homematicip_cloud/weather.py index cbe7c2845b8..1125c73f8d4 100644 --- a/homeassistant/components/homematicip_cloud/weather.py +++ b/homeassistant/components/homematicip_cloud/weather.py @@ -25,7 +25,7 @@ from homeassistant.components.weather import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import HomematicipGenericEntity @@ -53,7 +53,7 @@ HOME_WEATHER_CONDITION = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the HomematicIP weather sensor from a config entry.""" hap = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/homewizard/__init__.py b/homeassistant/components/homewizard/__init__.py index 36c9681dcd2..3831146aed8 100644 --- a/homeassistant/components/homewizard/__init__.py +++ b/homeassistant/components/homewizard/__init__.py @@ -7,7 +7,7 @@ from homewizard_energy import ( has_v2_api, ) -from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry +from homeassistant.config_entries import SOURCE_REAUTH from homeassistant.const import CONF_IP_ADDRESS, CONF_TOKEN from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -15,9 +15,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from .const import DOMAIN, PLATFORMS -from .coordinator import HWEnergyDeviceUpdateCoordinator - -type HomeWizardConfigEntry = ConfigEntry[HWEnergyDeviceUpdateCoordinator] +from .coordinator import HomeWizardConfigEntry, HWEnergyDeviceUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: HomeWizardConfigEntry) -> bool: @@ -42,7 +40,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: HomeWizardConfigEntry) - if is_battery: await async_check_v2_support_and_create_issue(hass, entry) - coordinator = HWEnergyDeviceUpdateCoordinator(hass, api) + coordinator = HWEnergyDeviceUpdateCoordinator(hass, entry, api) try: await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/homewizard/button.py b/homeassistant/components/homewizard/button.py index b86f797ec2d..5a36cdb71f2 100644 --- a/homeassistant/components/homewizard/button.py +++ b/homeassistant/components/homewizard/button.py @@ -3,10 +3,9 @@ from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import HomeWizardConfigEntry -from .coordinator import HWEnergyDeviceUpdateCoordinator +from .coordinator import HomeWizardConfigEntry, HWEnergyDeviceUpdateCoordinator from .entity import HomeWizardEntity from .helpers import homewizard_exception_handler @@ -16,7 +15,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: HomeWizardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Identify button.""" if entry.runtime_data.data.device.supports_identify(): diff --git a/homeassistant/components/homewizard/coordinator.py b/homeassistant/components/homewizard/coordinator.py index 92beb99ad2c..e87381c5fa9 100644 --- a/homeassistant/components/homewizard/coordinator.py +++ b/homeassistant/components/homewizard/coordinator.py @@ -13,6 +13,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN, LOGGER, UPDATE_INTERVAL +type HomeWizardConfigEntry = ConfigEntry[HWEnergyDeviceUpdateCoordinator] + class HWEnergyDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceResponseEntry]): """Gather data for the energy device.""" @@ -20,11 +22,22 @@ class HWEnergyDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceResponseEntry] api: HomeWizardEnergy api_disabled: bool = False - config_entry: ConfigEntry + config_entry: HomeWizardConfigEntry - def __init__(self, hass: HomeAssistant, api: HomeWizardEnergy) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: HomeWizardConfigEntry, + api: HomeWizardEnergy, + ) -> None: """Initialize update coordinator.""" - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) + super().__init__( + hass, + LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=UPDATE_INTERVAL, + ) self.api = api async def _async_update_data(self) -> DeviceResponseEntry: diff --git a/homeassistant/components/homewizard/diagnostics.py b/homeassistant/components/homewizard/diagnostics.py index 12bd25671e0..a3ae2555173 100644 --- a/homeassistant/components/homewizard/diagnostics.py +++ b/homeassistant/components/homewizard/diagnostics.py @@ -9,7 +9,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_IP_ADDRESS from homeassistant.core import HomeAssistant -from . import HomeWizardConfigEntry +from .coordinator import HomeWizardConfigEntry TO_REDACT = { CONF_IP_ADDRESS, diff --git a/homeassistant/components/homewizard/number.py b/homeassistant/components/homewizard/number.py index 5806295fc81..a703043a63b 100644 --- a/homeassistant/components/homewizard/number.py +++ b/homeassistant/components/homewizard/number.py @@ -5,10 +5,9 @@ from __future__ import annotations from homeassistant.components.number import NumberEntity from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import HomeWizardConfigEntry -from .coordinator import HWEnergyDeviceUpdateCoordinator +from .coordinator import HomeWizardConfigEntry, HWEnergyDeviceUpdateCoordinator from .entity import HomeWizardEntity from .helpers import homewizard_exception_handler @@ -18,7 +17,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: HomeWizardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up numbers for device.""" if entry.runtime_data.data.device.supports_state(): diff --git a/homeassistant/components/homewizard/sensor.py b/homeassistant/components/homewizard/sensor.py index f6f5588956c..dd557532240 100644 --- a/homeassistant/components/homewizard/sensor.py +++ b/homeassistant/components/homewizard/sensor.py @@ -33,13 +33,12 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow -from . import HomeWizardConfigEntry from .const import DOMAIN -from .coordinator import HWEnergyDeviceUpdateCoordinator +from .coordinator import HomeWizardConfigEntry, HWEnergyDeviceUpdateCoordinator from .entity import HomeWizardEntity PARALLEL_UPDATES = 1 @@ -691,7 +690,7 @@ EXTERNAL_SENSORS = { async def async_setup_entry( hass: HomeAssistant, entry: HomeWizardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize sensors.""" diff --git a/homeassistant/components/homewizard/switch.py b/homeassistant/components/homewizard/switch.py index 8ebb56433b1..1930b40583d 100644 --- a/homeassistant/components/homewizard/switch.py +++ b/homeassistant/components/homewizard/switch.py @@ -16,10 +16,9 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import HomeWizardConfigEntry -from .coordinator import HWEnergyDeviceUpdateCoordinator +from .coordinator import HomeWizardConfigEntry, HWEnergyDeviceUpdateCoordinator from .entity import HomeWizardEntity from .helpers import homewizard_exception_handler @@ -70,7 +69,7 @@ SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: HomeWizardConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" async_add_entities( diff --git a/homeassistant/components/homeworks/binary_sensor.py b/homeassistant/components/homeworks/binary_sensor.py index f1ba3c02835..9bdea75479d 100644 --- a/homeassistant/components/homeworks/binary_sensor.py +++ b/homeassistant/components/homeworks/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HomeworksData, HomeworksKeypad from .const import ( @@ -31,7 +31,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homeworks binary sensors.""" data: HomeworksData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/homeworks/button.py b/homeassistant/components/homeworks/button.py index 6a13573ac88..d76c18985e9 100644 --- a/homeassistant/components/homeworks/button.py +++ b/homeassistant/components/homeworks/button.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HomeworksData from .const import ( @@ -27,7 +27,9 @@ from .entity import HomeworksEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homeworks buttons.""" data: HomeworksData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/homeworks/light.py b/homeassistant/components/homeworks/light.py index ac52c1f4974..f07758bbace 100644 --- a/homeassistant/components/homeworks/light.py +++ b/homeassistant/components/homeworks/light.py @@ -13,7 +13,7 @@ from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HomeworksData from .const import CONF_ADDR, CONF_CONTROLLER_ID, CONF_DIMMERS, CONF_RATE, DOMAIN @@ -23,7 +23,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Homeworks lights.""" data: HomeworksData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/honeywell/climate.py b/homeassistant/components/honeywell/climate.py index 1df5eb9601b..5fe84aadd75 100644 --- a/homeassistant/components/honeywell/climate.py +++ b/homeassistant/components/honeywell/climate.py @@ -36,7 +36,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter from . import HoneywellConfigEntry, HoneywellData @@ -98,7 +98,7 @@ SCAN_INTERVAL = datetime.timedelta(seconds=30) async def async_setup_entry( hass: HomeAssistant, entry: HoneywellConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Honeywell thermostat.""" cool_away_temp = entry.options.get(CONF_COOL_AWAY_TEMPERATURE) diff --git a/homeassistant/components/honeywell/humidifier.py b/homeassistant/components/honeywell/humidifier.py index e94ba465c30..77776f84a2e 100644 --- a/homeassistant/components/honeywell/humidifier.py +++ b/homeassistant/components/honeywell/humidifier.py @@ -15,7 +15,7 @@ from homeassistant.components.humidifier import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HoneywellConfigEntry from .const import DOMAIN @@ -73,7 +73,7 @@ HUMIDIFIERS: dict[str, HoneywellHumidifierEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: HoneywellConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Honeywell (de)humidifier dynamically.""" data = config_entry.runtime_data diff --git a/homeassistant/components/honeywell/sensor.py b/homeassistant/components/honeywell/sensor.py index a9109d5d557..75ac6b1b6d3 100644 --- a/homeassistant/components/honeywell/sensor.py +++ b/homeassistant/components/honeywell/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import HoneywellConfigEntry @@ -81,7 +81,7 @@ SENSOR_TYPES: tuple[HoneywellSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: HoneywellConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Honeywell thermostat.""" data = config_entry.runtime_data diff --git a/homeassistant/components/honeywell/switch.py b/homeassistant/components/honeywell/switch.py index 3602dd1ba10..06c79bf4b1d 100644 --- a/homeassistant/components/honeywell/switch.py +++ b/homeassistant/components/honeywell/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import HoneywellConfigEntry, HoneywellData from .const import DOMAIN @@ -34,7 +34,7 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: HoneywellConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Honeywell switches.""" data = config_entry.runtime_data diff --git a/homeassistant/components/huawei_lte/binary_sensor.py b/homeassistant/components/huawei_lte/binary_sensor.py index 06b859cea84..c3434dd0b64 100644 --- a/homeassistant/components/huawei_lte/binary_sensor.py +++ b/homeassistant/components/huawei_lte/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -30,7 +30,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" router = hass.data[DOMAIN].routers[config_entry.entry_id] diff --git a/homeassistant/components/huawei_lte/button.py b/homeassistant/components/huawei_lte/button.py index 55b009d25bf..44b35d51dd4 100644 --- a/homeassistant/components/huawei_lte/button.py +++ b/homeassistant/components/huawei_lte/button.py @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: entity_platform.AddEntitiesCallback, + async_add_entities: entity_platform.AddConfigEntryEntitiesCallback, ) -> None: """Set up Huawei LTE buttons.""" router = hass.data[DOMAIN].routers[config_entry.entry_id] diff --git a/homeassistant/components/huawei_lte/device_tracker.py b/homeassistant/components/huawei_lte/device_tracker.py index df849d4f712..83e82bf17ff 100644 --- a/homeassistant/components/huawei_lte/device_tracker.py +++ b/homeassistant/components/huawei_lte/device_tracker.py @@ -17,7 +17,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Router from .const import ( @@ -53,7 +53,7 @@ def _get_hosts( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" @@ -128,7 +128,7 @@ def _is_us(host: _HostType) -> bool: @callback def async_add_new_entities( router: Router, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: set[str], ) -> None: """Add new entities that are not already being tracked.""" diff --git a/homeassistant/components/huawei_lte/select.py b/homeassistant/components/huawei_lte/select.py index d8a16ae2f79..3df6fa53320 100644 --- a/homeassistant/components/huawei_lte/select.py +++ b/homeassistant/components/huawei_lte/select.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED from . import Router @@ -38,7 +38,7 @@ class HuaweiSelectEntityDescription(SelectEntityDescription): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" router = hass.data[DOMAIN].routers[config_entry.entry_id] diff --git a/homeassistant/components/huawei_lte/sensor.py b/homeassistant/components/huawei_lte/sensor.py index 86965e89dd0..3543433ca45 100644 --- a/homeassistant/components/huawei_lte/sensor.py +++ b/homeassistant/components/huawei_lte/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import Router @@ -754,7 +754,7 @@ SENSOR_META: dict[str, HuaweiSensorGroup] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" router = hass.data[DOMAIN].routers[config_entry.entry_id] diff --git a/homeassistant/components/huawei_lte/switch.py b/homeassistant/components/huawei_lte/switch.py index 07fd89d0b6c..ac8bca4234c 100644 --- a/homeassistant/components/huawei_lte/switch.py +++ b/homeassistant/components/huawei_lte/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" router = hass.data[DOMAIN].routers[config_entry.entry_id] diff --git a/homeassistant/components/hue/binary_sensor.py b/homeassistant/components/hue/binary_sensor.py index 2cb8e8b5d90..ecaa6576775 100644 --- a/homeassistant/components/hue/binary_sensor.py +++ b/homeassistant/components/hue/binary_sensor.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import HueBridge from .const import DOMAIN @@ -15,7 +15,7 @@ from .v2.binary_sensor import async_setup_entry as setup_entry_v2 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor entities.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/event.py b/homeassistant/components/hue/event.py index 64f3ccba9f9..249f81687c0 100644 --- a/homeassistant/components/hue/event.py +++ b/homeassistant/components/hue/event.py @@ -16,7 +16,7 @@ from homeassistant.components.event import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import HueBridge from .const import DEFAULT_BUTTON_EVENT_TYPES, DEVICE_SPECIFIC_EVENT_TYPES, DOMAIN @@ -26,7 +26,7 @@ from .v2.entity import HueBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up event platform from Hue button resources.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/light.py b/homeassistant/components/hue/light.py index c3168b5c8c1..9906c9bffa4 100644 --- a/homeassistant/components/hue/light.py +++ b/homeassistant/components/hue/light.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import HueBridge from .const import DOMAIN @@ -16,7 +16,7 @@ from .v2.light import async_setup_entry as setup_entry_v2 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up light entities.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/scene.py b/homeassistant/components/hue/scene.py index 1d83804820d..0b9eb4efbd6 100644 --- a/homeassistant/components/hue/scene.py +++ b/homeassistant/components/hue/scene.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -34,7 +34,7 @@ ATTR_BRIGHTNESS = "brightness" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up scene platform from Hue group scenes.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/sensor.py b/homeassistant/components/hue/sensor.py index 45cff053aef..227742fdbab 100644 --- a/homeassistant/components/hue/sensor.py +++ b/homeassistant/components/hue/sensor.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import HueBridge from .const import DOMAIN @@ -15,7 +15,7 @@ from .v2.sensor import async_setup_entry as setup_entry_v2 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/switch.py b/homeassistant/components/hue/switch.py index b4bc57acf2d..b6b21686d25 100644 --- a/homeassistant/components/hue/switch.py +++ b/homeassistant/components/hue/switch.py @@ -22,7 +22,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import HueBridge from .const import DOMAIN @@ -32,7 +32,7 @@ from .v2.entity import HueBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hue switch platform from Hue resources.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/v2/binary_sensor.py b/homeassistant/components/hue/v2/binary_sensor.py index 5054ab6e817..6e4c7f98973 100644 --- a/homeassistant/components/hue/v2/binary_sensor.py +++ b/homeassistant/components/hue/v2/binary_sensor.py @@ -30,7 +30,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from ..bridge import HueBridge from ..const import DOMAIN @@ -49,7 +49,7 @@ type ControllerType = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hue Sensors from Config Entry.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/v2/group.py b/homeassistant/components/hue/v2/group.py index 17cd20b55aa..2f9f195df97 100644 --- a/homeassistant/components/hue/v2/group.py +++ b/homeassistant/components/hue/v2/group.py @@ -26,7 +26,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from ..bridge import HueBridge @@ -42,7 +42,7 @@ from .helpers import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hue groups on light platform.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/v2/light.py b/homeassistant/components/hue/v2/light.py index 86d8cc93e54..fc3e000ab75 100644 --- a/homeassistant/components/hue/v2/light.py +++ b/homeassistant/components/hue/v2/light.py @@ -27,7 +27,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from ..bridge import HueBridge @@ -48,7 +48,7 @@ FALLBACK_KELVIN = 5800 # halfway async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hue Light from Config Entry.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hue/v2/sensor.py b/homeassistant/components/hue/v2/sensor.py index bdf1db6df2e..ae6e456a8b4 100644 --- a/homeassistant/components/hue/v2/sensor.py +++ b/homeassistant/components/hue/v2/sensor.py @@ -28,7 +28,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import LIGHT_LUX, PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from ..bridge import HueBridge from ..const import DOMAIN @@ -46,7 +46,7 @@ type ControllerType = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Hue Sensors from Config Entry.""" bridge: HueBridge = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/huisbaasje/sensor.py b/homeassistant/components/huisbaasje/sensor.py index c024e3030fa..91c953b2182 100644 --- a/homeassistant/components/huisbaasje/sensor.py +++ b/homeassistant/components/huisbaasje/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -219,7 +219,7 @@ SENSORS_INFO = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]] = hass.data[DOMAIN][ diff --git a/homeassistant/components/hunterdouglas_powerview/__init__.py b/homeassistant/components/hunterdouglas_powerview/__init__.py index b4bbc37b1e8..3e9ff8727ce 100644 --- a/homeassistant/components/hunterdouglas_powerview/__init__.py +++ b/homeassistant/components/hunterdouglas_powerview/__init__.py @@ -91,7 +91,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PowerviewConfigEntry) -> entry, unique_id=device_info.serial_number ) - coordinator = PowerviewShadeUpdateCoordinator(hass, shades, hub) + coordinator = PowerviewShadeUpdateCoordinator(hass, entry, shades, hub) coordinator.async_set_updated_data(PowerviewShadeData()) # populate raw shade data into the coordinator for diagnostics coordinator.data.store_group_data(shade_data) diff --git a/homeassistant/components/hunterdouglas_powerview/button.py b/homeassistant/components/hunterdouglas_powerview/button.py index adb3e177a8e..c0bcac3a7df 100644 --- a/homeassistant/components/hunterdouglas_powerview/button.py +++ b/homeassistant/components/hunterdouglas_powerview/button.py @@ -22,7 +22,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PowerviewShadeUpdateCoordinator from .entity import ShadeEntity @@ -74,7 +74,7 @@ BUTTONS_SHADE: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the hunter douglas advanced feature buttons.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/hunterdouglas_powerview/coordinator.py b/homeassistant/components/hunterdouglas_powerview/coordinator.py index f074b06b2bc..2ff1914079a 100644 --- a/homeassistant/components/hunterdouglas_powerview/coordinator.py +++ b/homeassistant/components/hunterdouglas_powerview/coordinator.py @@ -10,6 +10,7 @@ from aiopvapi.helpers.aiorequest import PvApiMaintenance from aiopvapi.hub import Hub from aiopvapi.shades import Shades +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -22,7 +23,11 @@ _LOGGER = logging.getLogger(__name__) class PowerviewShadeUpdateCoordinator(DataUpdateCoordinator[PowerviewShadeData]): """DataUpdateCoordinator to gather data from a powerview hub.""" - def __init__(self, hass: HomeAssistant, shades: Shades, hub: Hub) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, shades: Shades, hub: Hub + ) -> None: """Initialize DataUpdateCoordinator to gather data for specific Powerview Hub.""" self.shades = shades self.hub = hub @@ -33,6 +38,7 @@ class PowerviewShadeUpdateCoordinator(DataUpdateCoordinator[PowerviewShadeData]) super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"powerview hub {hub.hub_address}", update_interval=timedelta(seconds=60), ) diff --git a/homeassistant/components/hunterdouglas_powerview/cover.py b/homeassistant/components/hunterdouglas_powerview/cover.py index 197fb4e6223..3f36a57891c 100644 --- a/homeassistant/components/hunterdouglas_powerview/cover.py +++ b/homeassistant/components/hunterdouglas_powerview/cover.py @@ -26,7 +26,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from .const import STATE_ATTRIBUTE_ROOM_NAME @@ -50,7 +50,7 @@ SCAN_INTERVAL = timedelta(minutes=10) async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the hunter douglas shades.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/hunterdouglas_powerview/number.py b/homeassistant/components/hunterdouglas_powerview/number.py index fb8c9f76d79..216cdb2642a 100644 --- a/homeassistant/components/hunterdouglas_powerview/number.py +++ b/homeassistant/components/hunterdouglas_powerview/number.py @@ -14,7 +14,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PowerviewShadeUpdateCoordinator from .entity import ShadeEntity @@ -54,7 +54,7 @@ NUMBERS: Final = ( async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the hunter douglas number entities.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/hunterdouglas_powerview/scene.py b/homeassistant/components/hunterdouglas_powerview/scene.py index 2aaa255c5ab..5016b590f91 100644 --- a/homeassistant/components/hunterdouglas_powerview/scene.py +++ b/homeassistant/components/hunterdouglas_powerview/scene.py @@ -10,7 +10,7 @@ from aiopvapi.resources.scene import Scene as PvScene from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import STATE_ATTRIBUTE_ROOM_NAME from .coordinator import PowerviewShadeUpdateCoordinator @@ -25,7 +25,7 @@ RESYNC_DELAY = 60 async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up powerview scene entries.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/hunterdouglas_powerview/select.py b/homeassistant/components/hunterdouglas_powerview/select.py index db850a0ddbf..932ff3ce3bd 100644 --- a/homeassistant/components/hunterdouglas_powerview/select.py +++ b/homeassistant/components/hunterdouglas_powerview/select.py @@ -12,7 +12,7 @@ from aiopvapi.resources.shade import BaseShade from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PowerviewShadeUpdateCoordinator from .entity import ShadeEntity @@ -54,7 +54,7 @@ DROPDOWNS: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the hunter douglas select entities.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/hunterdouglas_powerview/sensor.py b/homeassistant/components/hunterdouglas_powerview/sensor.py index f5e3ddd5e12..6ebf8e2b278 100644 --- a/homeassistant/components/hunterdouglas_powerview/sensor.py +++ b/homeassistant/components/hunterdouglas_powerview/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PowerviewShadeUpdateCoordinator from .entity import ShadeEntity @@ -79,7 +79,7 @@ SENSORS: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: PowerviewConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the hunter douglas sensor entities.""" pv_entry = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/__init__.py b/homeassistant/components/husqvarna_automower/__init__.py index a08256fb0b5..1945647a706 100644 --- a/homeassistant/components/husqvarna_automower/__init__.py +++ b/homeassistant/components/husqvarna_automower/__init__.py @@ -5,7 +5,6 @@ import logging from aioautomower.session import AutomowerSession from aiohttp import ClientResponseError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -13,7 +12,7 @@ from homeassistant.helpers import aiohttp_client, config_entry_oauth2_flow from homeassistant.util import dt as dt_util from . import api -from .coordinator import AutomowerDataUpdateCoordinator +from .coordinator import AutomowerConfigEntry, AutomowerDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -29,8 +28,6 @@ PLATFORMS: list[Platform] = [ Platform.SWITCH, ] -type AutomowerConfigEntry = ConfigEntry[AutomowerDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: AutomowerConfigEntry) -> bool: """Set up this integration using UI.""" @@ -61,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AutomowerConfigEntry) -> # without the scope. So only polling would be possible. raise ConfigEntryAuthFailed - coordinator = AutomowerDataUpdateCoordinator(hass, automower_api) + coordinator = AutomowerDataUpdateCoordinator(hass, entry, automower_api) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/husqvarna_automower/binary_sensor.py b/homeassistant/components/husqvarna_automower/binary_sensor.py index 907d34e812a..1e5b9fac990 100644 --- a/homeassistant/components/husqvarna_automower/binary_sensor.py +++ b/homeassistant/components/husqvarna_automower/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.binary_sensor import ( 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 AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -71,7 +71,7 @@ MOWER_BINARY_SENSOR_TYPES: tuple[AutomowerBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/button.py b/homeassistant/components/husqvarna_automower/button.py index 7e6e581cdf1..1f7ed7127e0 100644 --- a/homeassistant/components/husqvarna_automower/button.py +++ b/homeassistant/components/husqvarna_automower/button.py @@ -10,7 +10,7 @@ from aioautomower.session import AutomowerSession from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -54,7 +54,7 @@ MOWER_BUTTON_TYPES: tuple[AutomowerButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/calendar.py b/homeassistant/components/husqvarna_automower/calendar.py index 9e2ea037afb..26e939ec7d9 100644 --- a/homeassistant/components/husqvarna_automower/calendar.py +++ b/homeassistant/components/husqvarna_automower/calendar.py @@ -7,7 +7,7 @@ from aioautomower.model import make_name_string from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import AutomowerConfigEntry @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lawn mower platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/coordinator.py b/homeassistant/components/husqvarna_automower/coordinator.py index a587b4f3821..819ee41a43d 100644 --- a/homeassistant/components/husqvarna_automower/coordinator.py +++ b/homeassistant/components/husqvarna_automower/coordinator.py @@ -6,7 +6,6 @@ import asyncio from collections.abc import Callable from datetime import timedelta import logging -from typing import TYPE_CHECKING from aioautomower.exceptions import ( ApiError, @@ -17,6 +16,7 @@ from aioautomower.exceptions import ( from aioautomower.model import MowerAttributes from aioautomower.session import AutomowerSession +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers import device_registry as dr, entity_registry as er @@ -24,25 +24,30 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN -if TYPE_CHECKING: - from . import AutomowerConfigEntry - _LOGGER = logging.getLogger(__name__) MAX_WS_RECONNECT_TIME = 600 SCAN_INTERVAL = timedelta(minutes=8) DEFAULT_RECONNECT_TIME = 2 # Define a default reconnect time +type AutomowerConfigEntry = ConfigEntry[AutomowerDataUpdateCoordinator] + class AutomowerDataUpdateCoordinator(DataUpdateCoordinator[dict[str, MowerAttributes]]): """Class to manage fetching Husqvarna data.""" config_entry: AutomowerConfigEntry - def __init__(self, hass: HomeAssistant, api: AutomowerSession) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: AutomowerConfigEntry, + api: AutomowerSession, + ) -> None: """Initialize data updater.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/husqvarna_automower/device_tracker.py b/homeassistant/components/husqvarna_automower/device_tracker.py index 2fd59b63014..78fad7c3610 100644 --- a/homeassistant/components/husqvarna_automower/device_tracker.py +++ b/homeassistant/components/husqvarna_automower/device_tracker.py @@ -2,7 +2,7 @@ from homeassistant.components.device_tracker import TrackerEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -15,7 +15,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/lawn_mower.py b/homeassistant/components/husqvarna_automower/lawn_mower.py index dd75a8b9bc4..ee6007f089b 100644 --- a/homeassistant/components/husqvarna_automower/lawn_mower.py +++ b/homeassistant/components/husqvarna_automower/lawn_mower.py @@ -15,7 +15,7 @@ from homeassistant.components.lawn_mower import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .const import DOMAIN @@ -49,7 +49,7 @@ OVERRIDE_MODES = [MOW, PARK] async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lawn mower platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/number.py b/homeassistant/components/husqvarna_automower/number.py index d3666494646..cdcf4b45a2d 100644 --- a/homeassistant/components/husqvarna_automower/number.py +++ b/homeassistant/components/husqvarna_automower/number.py @@ -11,7 +11,7 @@ from aioautomower.session import AutomowerSession from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -107,7 +107,7 @@ WORK_AREA_NUMBER_TYPES: tuple[WorkAreaNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/select.py b/homeassistant/components/husqvarna_automower/select.py index 03b1ac02587..9124a0705e1 100644 --- a/homeassistant/components/husqvarna_automower/select.py +++ b/homeassistant/components/husqvarna_automower/select.py @@ -8,7 +8,7 @@ from aioautomower.model import HeadlightModes from homeassistant.components.select import SelectEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -29,7 +29,7 @@ HEADLIGHT_MODES: list = [ async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/sensor.py b/homeassistant/components/husqvarna_automower/sensor.py index a2f4b5f4bab..2e1d4041e5a 100644 --- a/homeassistant/components/husqvarna_automower/sensor.py +++ b/homeassistant/components/husqvarna_automower/sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import AutomowerConfigEntry @@ -430,7 +430,7 @@ WORK_AREA_SENSOR_TYPES: tuple[WorkAreaSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower/switch.py b/homeassistant/components/husqvarna_automower/switch.py index d55d51b42fe..69a3e670eda 100644 --- a/homeassistant/components/husqvarna_automower/switch.py +++ b/homeassistant/components/husqvarna_automower/switch.py @@ -7,7 +7,7 @@ from aioautomower.model import MowerModes, StayOutZones, Zone from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: AutomowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/husqvarna_automower_ble/__init__.py b/homeassistant/components/husqvarna_automower_ble/__init__.py index 2025ba64cf1..ca07d1ab8d2 100644 --- a/homeassistant/components/husqvarna_automower_ble/__init__.py +++ b/homeassistant/components/husqvarna_automower_ble/__init__.py @@ -45,7 +45,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: model = await mower.get_model() LOGGER.debug("Connected to Automower: %s", model) - coordinator = HusqvarnaCoordinator(hass, mower, address, channel_id, model) + coordinator = HusqvarnaCoordinator(hass, entry, mower, address, channel_id, model) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/husqvarna_automower_ble/coordinator.py b/homeassistant/components/husqvarna_automower_ble/coordinator.py index c577ccd9196..dde3462c081 100644 --- a/homeassistant/components/husqvarna_automower_ble/coordinator.py +++ b/homeassistant/components/husqvarna_automower_ble/coordinator.py @@ -9,6 +9,7 @@ from bleak import BleakError from bleak_retry_connector import close_stale_connections_by_address from homeassistant.components import bluetooth +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -20,9 +21,12 @@ SCAN_INTERVAL = timedelta(seconds=60) class HusqvarnaCoordinator(DataUpdateCoordinator[dict[str, bytes]]): """Class to manage fetching data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, mower: Mower, address: str, channel_id: str, @@ -32,6 +36,7 @@ class HusqvarnaCoordinator(DataUpdateCoordinator[dict[str, bytes]]): super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/husqvarna_automower_ble/lawn_mower.py b/homeassistant/components/husqvarna_automower_ble/lawn_mower.py index 980efc6f069..4b239394c2d 100644 --- a/homeassistant/components/husqvarna_automower_ble/lawn_mower.py +++ b/homeassistant/components/husqvarna_automower_ble/lawn_mower.py @@ -12,7 +12,7 @@ from homeassistant.components.lawn_mower import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER from .coordinator import HusqvarnaCoordinator @@ -22,7 +22,7 @@ from .entity import HusqvarnaAutomowerBleEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up AutomowerLawnMower integration from a config entry.""" coordinator: HusqvarnaCoordinator = config_entry.runtime_data diff --git a/homeassistant/components/huum/climate.py b/homeassistant/components/huum/climate.py index 7e0e4ce5ef1..84173260d04 100644 --- a/homeassistant/components/huum/climate.py +++ b/homeassistant/components/huum/climate.py @@ -20,7 +20,7 @@ from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTempera from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -30,7 +30,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Huum sauna with config flow.""" huum_handler = hass.data.setdefault(DOMAIN, {})[entry.entry_id] diff --git a/homeassistant/components/hvv_departures/binary_sensor.py b/homeassistant/components/hvv_departures/binary_sensor.py index 913c61f91b4..622a8436e04 100644 --- a/homeassistant/components/hvv_departures/binary_sensor.py +++ b/homeassistant/components/hvv_departures/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -30,7 +30,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary_sensor platform.""" hub = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/hvv_departures/sensor.py b/homeassistant/components/hvv_departures/sensor.py index 6ad61295d04..667893db8f2 100644 --- a/homeassistant/components/hvv_departures/sensor.py +++ b/homeassistant/components/hvv_departures/sensor.py @@ -13,7 +13,7 @@ from homeassistant.const import ATTR_ID, CONF_OFFSET from homeassistant.core import HomeAssistant from homeassistant.helpers import aiohttp_client from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from homeassistant.util.dt import get_time_zone, utcnow @@ -42,7 +42,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" hub = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hydrawise/__init__.py b/homeassistant/components/hydrawise/__init__.py index ee5a8a66610..ce4d7a8f8c2 100644 --- a/homeassistant/components/hydrawise/__init__.py +++ b/homeassistant/components/hydrawise/__init__.py @@ -39,10 +39,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b app_id=APP_ID, ) - main_coordinator = HydrawiseMainDataUpdateCoordinator(hass, hydrawise) + main_coordinator = HydrawiseMainDataUpdateCoordinator(hass, config_entry, hydrawise) await main_coordinator.async_config_entry_first_refresh() water_use_coordinator = HydrawiseWaterUseDataUpdateCoordinator( - hass, hydrawise, main_coordinator + hass, config_entry, hydrawise, main_coordinator ) await water_use_coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = ( diff --git a/homeassistant/components/hydrawise/binary_sensor.py b/homeassistant/components/hydrawise/binary_sensor.py index 83e8a8325f9..b2862930933 100644 --- a/homeassistant/components/hydrawise/binary_sensor.py +++ b/homeassistant/components/hydrawise/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from .const import DOMAIN, SERVICE_RESUME, SERVICE_START_WATERING, SERVICE_SUSPEND @@ -78,7 +78,7 @@ SCHEMA_SUSPEND: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Hydrawise binary_sensor platform.""" coordinators: HydrawiseUpdateCoordinators = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hydrawise/coordinator.py b/homeassistant/components/hydrawise/coordinator.py index 4721a9fb154..35d816b341b 100644 --- a/homeassistant/components/hydrawise/coordinator.py +++ b/homeassistant/components/hydrawise/coordinator.py @@ -7,6 +7,7 @@ from dataclasses import dataclass, field from pydrawise import HydrawiseBase from pydrawise.schema import Controller, ControllerWaterUseSummary, Sensor, User, Zone +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util.dt import now @@ -39,6 +40,7 @@ class HydrawiseDataUpdateCoordinator(DataUpdateCoordinator[HydrawiseData]): """Base class for Hydrawise Data Update Coordinators.""" api: HydrawiseBase + config_entry: ConfigEntry class HydrawiseMainDataUpdateCoordinator(HydrawiseDataUpdateCoordinator): @@ -49,9 +51,17 @@ class HydrawiseMainDataUpdateCoordinator(HydrawiseDataUpdateCoordinator): integration are updated in a timely manner. """ - def __init__(self, hass: HomeAssistant, api: HydrawiseBase) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: HydrawiseBase + ) -> None: """Initialize HydrawiseDataUpdateCoordinator.""" - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=MAIN_SCAN_INTERVAL) + super().__init__( + hass, + LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=MAIN_SCAN_INTERVAL, + ) self.api = api async def _async_update_data(self) -> HydrawiseData: @@ -82,6 +92,7 @@ class HydrawiseWaterUseDataUpdateCoordinator(HydrawiseDataUpdateCoordinator): def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, api: HydrawiseBase, main_coordinator: HydrawiseMainDataUpdateCoordinator, ) -> None: @@ -89,6 +100,7 @@ class HydrawiseWaterUseDataUpdateCoordinator(HydrawiseDataUpdateCoordinator): super().__init__( hass, LOGGER, + config_entry=config_entry, name=f"{DOMAIN} water use", update_interval=WATER_USE_SCAN_INTERVAL, ) diff --git a/homeassistant/components/hydrawise/sensor.py b/homeassistant/components/hydrawise/sensor.py index 96cc16832da..60bc1d7dc63 100644 --- a/homeassistant/components/hydrawise/sensor.py +++ b/homeassistant/components/hydrawise/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTime, UnitOfVolume from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -131,7 +131,7 @@ FLOW_MEASUREMENT_KEYS = [x.key for x in FLOW_CONTROLLER_SENSORS] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Hydrawise sensor platform.""" coordinators: HydrawiseUpdateCoordinators = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hydrawise/switch.py b/homeassistant/components/hydrawise/switch.py index 62cd81a0481..bc6b31e6d2e 100644 --- a/homeassistant/components/hydrawise/switch.py +++ b/homeassistant/components/hydrawise/switch.py @@ -16,7 +16,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DEFAULT_WATERING_TIME, DOMAIN @@ -63,7 +63,7 @@ SWITCH_KEYS: list[str] = [desc.key for desc in SWITCH_TYPES] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Hydrawise switch platform.""" coordinators: HydrawiseUpdateCoordinators = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hydrawise/valve.py b/homeassistant/components/hydrawise/valve.py index 37f196bc054..13aff22ccbf 100644 --- a/homeassistant/components/hydrawise/valve.py +++ b/homeassistant/components/hydrawise/valve.py @@ -14,7 +14,7 @@ from homeassistant.components.valve import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import HydrawiseUpdateCoordinators @@ -31,7 +31,7 @@ VALVE_TYPES: tuple[ValveEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Hydrawise valve platform.""" coordinators: HydrawiseUpdateCoordinators = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hyperion/camera.py b/homeassistant/components/hyperion/camera.py index 23ce2715140..1260be20eb2 100644 --- a/homeassistant/components/hyperion/camera.py +++ b/homeassistant/components/hyperion/camera.py @@ -32,7 +32,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ( get_hyperion_device_id, @@ -54,7 +54,7 @@ IMAGE_STREAM_JPG_SENTINEL = "data:image/jpg;base64," async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Hyperion platform from config entry.""" entry_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hyperion/light.py b/homeassistant/components/hyperion/light.py index 40d093430a5..f8932a682ab 100644 --- a/homeassistant/components/hyperion/light.py +++ b/homeassistant/components/hyperion/light.py @@ -25,7 +25,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import ( @@ -76,7 +76,7 @@ ICON_EFFECT = "mdi:lava-lamp" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Hyperion platform from config entry.""" diff --git a/homeassistant/components/hyperion/sensor.py b/homeassistant/components/hyperion/sensor.py index ad972806ae5..42b41acea96 100644 --- a/homeassistant/components/hyperion/sensor.py +++ b/homeassistant/components/hyperion/sensor.py @@ -26,7 +26,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ( get_hyperion_device_id, @@ -63,7 +63,7 @@ def _sensor_unique_id(server_id: str, instance_num: int, suffix: str) -> str: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Hyperion platform from config entry.""" entry_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/hyperion/switch.py b/homeassistant/components/hyperion/switch.py index 94cbf2aba29..8b66783e889 100644 --- a/homeassistant/components/hyperion/switch.py +++ b/homeassistant/components/hyperion/switch.py @@ -34,7 +34,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from . import ( @@ -90,7 +90,7 @@ def _component_to_translation_key(component: str) -> str: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Hyperion platform from config entry.""" entry_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/ialarm/__init__.py b/homeassistant/components/ialarm/__init__.py index 95c62b87a19..2484a46f906 100644 --- a/homeassistant/components/ialarm/__init__.py +++ b/homeassistant/components/ialarm/__init__.py @@ -29,7 +29,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except (TimeoutError, ConnectionError) as ex: raise ConfigEntryNotReady from ex - coordinator = IAlarmDataUpdateCoordinator(hass, ialarm, mac) + coordinator = IAlarmDataUpdateCoordinator(hass, entry, ialarm, mac) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {}) diff --git a/homeassistant/components/ialarm/alarm_control_panel.py b/homeassistant/components/ialarm/alarm_control_panel.py index 4ae3787dc1d..e203f892c35 100644 --- a/homeassistant/components/ialarm/alarm_control_panel.py +++ b/homeassistant/components/ialarm/alarm_control_panel.py @@ -10,7 +10,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DATA_COORDINATOR, DOMAIN @@ -18,7 +18,9 @@ from .coordinator import IAlarmDataUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a iAlarm alarm control panel based on a config entry.""" coordinator: IAlarmDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/ialarm/coordinator.py b/homeassistant/components/ialarm/coordinator.py index ad0f2298a3b..61e87c36796 100644 --- a/homeassistant/components/ialarm/coordinator.py +++ b/homeassistant/components/ialarm/coordinator.py @@ -11,6 +11,7 @@ from homeassistant.components.alarm_control_panel import ( SCAN_INTERVAL, AlarmControlPanelState, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -22,7 +23,11 @@ _LOGGER = logging.getLogger(__name__) class IAlarmDataUpdateCoordinator(DataUpdateCoordinator[None]): """Class to manage fetching iAlarm data.""" - def __init__(self, hass: HomeAssistant, ialarm: IAlarm, mac: str) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, ialarm: IAlarm, mac: str + ) -> None: """Initialize global iAlarm data updater.""" self.ialarm = ialarm self.state: AlarmControlPanelState | None = None @@ -32,6 +37,7 @@ class IAlarmDataUpdateCoordinator(DataUpdateCoordinator[None]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/iaqualink/binary_sensor.py b/homeassistant/components/iaqualink/binary_sensor.py index 9e173dc36e0..8fe9d77fbe8 100644 --- a/homeassistant/components/iaqualink/binary_sensor.py +++ b/homeassistant/components/iaqualink/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as AQUALINK_DOMAIN from .entity import AqualinkEntity @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up discovered binary sensors.""" async_add_entities( diff --git a/homeassistant/components/iaqualink/climate.py b/homeassistant/components/iaqualink/climate.py index 53d1bce80de..d30700898c8 100644 --- a/homeassistant/components/iaqualink/climate.py +++ b/homeassistant/components/iaqualink/climate.py @@ -18,7 +18,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import DOMAIN as AQUALINK_DOMAIN @@ -33,7 +33,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up discovered switches.""" async_add_entities( diff --git a/homeassistant/components/iaqualink/light.py b/homeassistant/components/iaqualink/light.py index 59172c13576..e515c482158 100644 --- a/homeassistant/components/iaqualink/light.py +++ b/homeassistant/components/iaqualink/light.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import DOMAIN as AQUALINK_DOMAIN @@ -29,7 +29,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up discovered lights.""" async_add_entities( diff --git a/homeassistant/components/iaqualink/sensor.py b/homeassistant/components/iaqualink/sensor.py index 881adb420bf..1b453f28d8f 100644 --- a/homeassistant/components/iaqualink/sensor.py +++ b/homeassistant/components/iaqualink/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as AQUALINK_DOMAIN from .entity import AqualinkEntity @@ -23,7 +23,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up discovered sensors.""" async_add_entities( diff --git a/homeassistant/components/iaqualink/switch.py b/homeassistant/components/iaqualink/switch.py index 601c5701a4a..e746cbb4f4b 100644 --- a/homeassistant/components/iaqualink/switch.py +++ b/homeassistant/components/iaqualink/switch.py @@ -9,7 +9,7 @@ from iaqualink.device import AqualinkSwitch from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import refresh_system from .const import DOMAIN as AQUALINK_DOMAIN @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up discovered switches.""" async_add_entities( diff --git a/homeassistant/components/ibeacon/device_tracker.py b/homeassistant/components/ibeacon/device_tracker.py index d002cb10f44..0d2ee0137cc 100644 --- a/homeassistant/components/ibeacon/device_tracker.py +++ b/homeassistant/components/ibeacon/device_tracker.py @@ -9,7 +9,7 @@ from homeassistant.components.device_tracker.config_entry import BaseTrackerEnti from homeassistant.const import STATE_HOME, STATE_NOT_HOME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IBeaconConfigEntry from .const import SIGNAL_IBEACON_DEVICE_NEW @@ -20,7 +20,7 @@ from .entity import IBeaconEntity async def async_setup_entry( hass: HomeAssistant, entry: IBeaconConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for iBeacon Tracker component.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ibeacon/sensor.py b/homeassistant/components/ibeacon/sensor.py index f73aef4b803..7e1fd371128 100644 --- a/homeassistant/components/ibeacon/sensor.py +++ b/homeassistant/components/ibeacon/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IBeaconConfigEntry from .const import SIGNAL_IBEACON_DEVICE_NEW @@ -69,7 +69,7 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: IBeaconConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for iBeacon Tracker component.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/icloud/device_tracker.py b/homeassistant/components/icloud/device_tracker.py index 11a18a10020..ca194143852 100644 --- a/homeassistant/components/icloud/device_tracker.py +++ b/homeassistant/components/icloud/device_tracker.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .account import IcloudAccount, IcloudDevice from .const import ( @@ -21,7 +21,9 @@ from .const import ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for iCloud component.""" account: IcloudAccount = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/icloud/sensor.py b/homeassistant/components/icloud/sensor.py index 53c9765f6cc..533605b8c7b 100644 --- a/homeassistant/components/icloud/sensor.py +++ b/homeassistant/components/icloud/sensor.py @@ -10,7 +10,7 @@ from homeassistant.const import PERCENTAGE from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from .account import IcloudAccount, IcloudDevice @@ -18,7 +18,9 @@ from .const import DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for iCloud component.""" account: IcloudAccount = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/idasen_desk/__init__.py b/homeassistant/components/idasen_desk/__init__.py index 671319e46eb..1ea0efeef72 100644 --- a/homeassistant/components/idasen_desk/__init__.py +++ b/homeassistant/components/idasen_desk/__init__.py @@ -9,25 +9,22 @@ from idasen_ha.errors import AuthFailedError from homeassistant.components import bluetooth from homeassistant.components.bluetooth.match import ADDRESS, BluetoothCallbackMatcher -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ADDRESS, EVENT_HOMEASSISTANT_STOP, Platform from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady -from .coordinator import IdasenDeskCoordinator +from .coordinator import IdasenDeskConfigEntry, IdasenDeskCoordinator PLATFORMS: list[Platform] = [Platform.BUTTON, Platform.COVER, Platform.SENSOR] _LOGGER = logging.getLogger(__name__) -type IdasenDeskConfigEntry = ConfigEntry[IdasenDeskCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: IdasenDeskConfigEntry) -> bool: """Set up IKEA Idasen from a config entry.""" address: str = entry.data[CONF_ADDRESS].upper() - coordinator = IdasenDeskCoordinator(hass, entry.title, address) + coordinator = IdasenDeskCoordinator(hass, entry, address) entry.runtime_data = coordinator try: diff --git a/homeassistant/components/idasen_desk/button.py b/homeassistant/components/idasen_desk/button.py index cd7553da1ac..2e63e5e7cb8 100644 --- a/homeassistant/components/idasen_desk/button.py +++ b/homeassistant/components/idasen_desk/button.py @@ -8,9 +8,9 @@ from typing import Any, Final from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IdasenDeskConfigEntry, IdasenDeskCoordinator +from .coordinator import IdasenDeskConfigEntry, IdasenDeskCoordinator from .entity import IdasenDeskEntity _LOGGER = logging.getLogger(__name__) @@ -44,7 +44,7 @@ BUTTONS: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: IdasenDeskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set buttons for device.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/idasen_desk/coordinator.py b/homeassistant/components/idasen_desk/coordinator.py index d9e90cfe5ea..5da3d57cf9a 100644 --- a/homeassistant/components/idasen_desk/coordinator.py +++ b/homeassistant/components/idasen_desk/coordinator.py @@ -7,24 +7,31 @@ import logging from idasen_ha import Desk from homeassistant.components import bluetooth +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator _LOGGER = logging.getLogger(__name__) +type IdasenDeskConfigEntry = ConfigEntry[IdasenDeskCoordinator] + class IdasenDeskCoordinator(DataUpdateCoordinator[int | None]): """Class to manage updates for the Idasen Desk.""" + config_entry: IdasenDeskConfigEntry + def __init__( self, hass: HomeAssistant, - name: str, + config_entry: IdasenDeskConfigEntry, address: str, ) -> None: """Init IdasenDeskCoordinator.""" - super().__init__(hass, _LOGGER, name=name) + super().__init__( + hass, _LOGGER, config_entry=config_entry, name=config_entry.title + ) self.address = address self._expected_connected = False diff --git a/homeassistant/components/idasen_desk/cover.py b/homeassistant/components/idasen_desk/cover.py index a8ba0983e99..b451f4d0156 100644 --- a/homeassistant/components/idasen_desk/cover.py +++ b/homeassistant/components/idasen_desk/cover.py @@ -14,16 +14,16 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IdasenDeskConfigEntry, IdasenDeskCoordinator +from .coordinator import IdasenDeskConfigEntry, IdasenDeskCoordinator from .entity import IdasenDeskEntity async def async_setup_entry( hass: HomeAssistant, entry: IdasenDeskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the cover platform for Idasen Desk.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/idasen_desk/entity.py b/homeassistant/components/idasen_desk/entity.py index bda7afd528c..46730ee13fe 100644 --- a/homeassistant/components/idasen_desk/entity.py +++ b/homeassistant/components/idasen_desk/entity.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import IdasenDeskCoordinator +from .coordinator import IdasenDeskCoordinator class IdasenDeskEntity(CoordinatorEntity[IdasenDeskCoordinator]): diff --git a/homeassistant/components/idasen_desk/sensor.py b/homeassistant/components/idasen_desk/sensor.py index 4613d316a52..22680b4fa7f 100644 --- a/homeassistant/components/idasen_desk/sensor.py +++ b/homeassistant/components/idasen_desk/sensor.py @@ -13,9 +13,9 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IdasenDeskConfigEntry, IdasenDeskCoordinator +from .coordinator import IdasenDeskConfigEntry, IdasenDeskCoordinator from .entity import IdasenDeskEntity @@ -43,7 +43,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: IdasenDeskConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Idasen Desk sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/igloohome/sensor.py b/homeassistant/components/igloohome/sensor.py index 7f25798e454..10a9ece6771 100644 --- a/homeassistant/components/igloohome/sensor.py +++ b/homeassistant/components/igloohome/sensor.py @@ -8,7 +8,7 @@ from igloohome_api import Api as IgloohomeApi, ApiException, GetDeviceInfoRespon from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IgloohomeConfigEntry from .entity import IgloohomeBaseEntity @@ -22,7 +22,7 @@ SCAN_INTERVAL = timedelta(hours=1) async def async_setup_entry( hass: HomeAssistant, entry: IgloohomeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities.""" diff --git a/homeassistant/components/imap/coordinator.py b/homeassistant/components/imap/coordinator.py index 1df107196ff..74f7a86c0d6 100644 --- a/homeassistant/components/imap/coordinator.py +++ b/homeassistant/components/imap/coordinator.py @@ -241,6 +241,7 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]): super().__init__( hass, _LOGGER, + config_entry=entry, name=DOMAIN, update_interval=update_interval, ) diff --git a/homeassistant/components/imap/sensor.py b/homeassistant/components/imap/sensor.py index 60892388252..01009e3d17b 100644 --- a/homeassistant/components/imap/sensor.py +++ b/homeassistant/components/imap/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import CONF_USERNAME, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import ImapConfigEntry @@ -30,7 +30,9 @@ IMAP_MAIL_COUNT_DESCRIPTION = SensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ImapConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ImapConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Imap sensor.""" diff --git a/homeassistant/components/imgw_pib/__init__.py b/homeassistant/components/imgw_pib/__init__.py index eb12e1a2bb4..f9524316570 100644 --- a/homeassistant/components/imgw_pib/__init__.py +++ b/homeassistant/components/imgw_pib/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations -from dataclasses import dataclass import logging from aiohttp import ClientError @@ -10,7 +9,6 @@ from imgw_pib import ImgwPib from imgw_pib.exceptions import ApiError from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_PLATFORM -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -18,21 +16,12 @@ from homeassistant.helpers import entity_registry as er from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import CONF_STATION_ID, DOMAIN -from .coordinator import ImgwPibDataUpdateCoordinator +from .coordinator import ImgwPibConfigEntry, ImgwPibData, ImgwPibDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] _LOGGER = logging.getLogger(__name__) -type ImgwPibConfigEntry = ConfigEntry[ImgwPibData] - - -@dataclass -class ImgwPibData: - """Data for the IMGW-PIB integration.""" - - coordinator: ImgwPibDataUpdateCoordinator - async def async_setup_entry(hass: HomeAssistant, entry: ImgwPibConfigEntry) -> bool: """Set up IMGW-PIB from a config entry.""" @@ -51,7 +40,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ImgwPibConfigEntry) -> b except (ClientError, TimeoutError, ApiError) as err: raise ConfigEntryNotReady from err - coordinator = ImgwPibDataUpdateCoordinator(hass, imgwpib, station_id) + coordinator = ImgwPibDataUpdateCoordinator(hass, entry, imgwpib, station_id) await coordinator.async_config_entry_first_refresh() # Remove binary_sensor entities for which the endpoint has been blocked by IMGW-PIB API diff --git a/homeassistant/components/imgw_pib/coordinator.py b/homeassistant/components/imgw_pib/coordinator.py index 77a58001a6f..fbe470ca953 100644 --- a/homeassistant/components/imgw_pib/coordinator.py +++ b/homeassistant/components/imgw_pib/coordinator.py @@ -1,9 +1,13 @@ """Data Update Coordinator for IMGW-PIB integration.""" +from __future__ import annotations + +from dataclasses import dataclass import logging from imgw_pib import ApiError, HydrologicalData, ImgwPib +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -13,12 +17,25 @@ from .const import DOMAIN, UPDATE_INTERVAL _LOGGER = logging.getLogger(__name__) +@dataclass +class ImgwPibData: + """Data for the IMGW-PIB integration.""" + + coordinator: ImgwPibDataUpdateCoordinator + + +type ImgwPibConfigEntry = ConfigEntry[ImgwPibData] + + class ImgwPibDataUpdateCoordinator(DataUpdateCoordinator[HydrologicalData]): """Class to manage fetching IMGW-PIB data API.""" + config_entry: ImgwPibConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ImgwPibConfigEntry, imgwpib: ImgwPib, station_id: str, ) -> None: @@ -33,7 +50,13 @@ class ImgwPibDataUpdateCoordinator(DataUpdateCoordinator[HydrologicalData]): configuration_url=f"https://hydro.imgw.pl/#/station/hydro/{station_id}", ) - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=UPDATE_INTERVAL, + ) async def _async_update_data(self) -> HydrologicalData: """Update data via internal method.""" diff --git a/homeassistant/components/imgw_pib/diagnostics.py b/homeassistant/components/imgw_pib/diagnostics.py index d135208115f..ce9cb3f9e95 100644 --- a/homeassistant/components/imgw_pib/diagnostics.py +++ b/homeassistant/components/imgw_pib/diagnostics.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import ImgwPibConfigEntry +from .coordinator import ImgwPibConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/imgw_pib/sensor.py b/homeassistant/components/imgw_pib/sensor.py index 15043af2015..33b82bbb43b 100644 --- a/homeassistant/components/imgw_pib/sensor.py +++ b/homeassistant/components/imgw_pib/sensor.py @@ -17,12 +17,11 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfLength, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import ImgwPibConfigEntry from .const import DOMAIN -from .coordinator import ImgwPibDataUpdateCoordinator +from .coordinator import ImgwPibConfigEntry, ImgwPibDataUpdateCoordinator from .entity import ImgwPibEntity PARALLEL_UPDATES = 1 @@ -60,7 +59,7 @@ SENSOR_TYPES: tuple[ImgwPibSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ImgwPibConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a IMGW-PIB sensor entity from a config_entry.""" coordinator = entry.runtime_data.coordinator diff --git a/homeassistant/components/incomfort/__init__.py b/homeassistant/components/incomfort/__init__.py index 4d05a57bcfa..307ff09206f 100644 --- a/homeassistant/components/incomfort/__init__.py +++ b/homeassistant/components/incomfort/__init__.py @@ -5,14 +5,18 @@ from __future__ import annotations from aiohttp import ClientResponseError from incomfortclient import InvalidGateway, InvalidHeaterList -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers import device_registry as dr from .const import DOMAIN -from .coordinator import InComfortData, InComfortDataCoordinator, async_connect_gateway +from .coordinator import ( + InComfortConfigEntry, + InComfortData, + InComfortDataCoordinator, + async_connect_gateway, +) from .errors import InComfortTimeout, InComfortUnknownError, NoHeaters, NotFound PLATFORMS = ( @@ -24,8 +28,6 @@ PLATFORMS = ( INTEGRATION_TITLE = "Intergas InComfort/Intouch Lan2RF gateway" -type InComfortConfigEntry = ConfigEntry[InComfortDataCoordinator] - @callback def async_cleanup_stale_devices( @@ -93,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: InComfortConfigEntry) -> name="RFGateway", ) async_cleanup_stale_devices(hass, entry, data, gateway_device) - coordinator = InComfortDataCoordinator(hass, data, entry.entry_id) + coordinator = InComfortDataCoordinator(hass, entry, data) entry.runtime_data = coordinator await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/incomfort/binary_sensor.py b/homeassistant/components/incomfort/binary_sensor.py index e4353e457a5..356cee82e57 100644 --- a/homeassistant/components/incomfort/binary_sensor.py +++ b/homeassistant/components/incomfort/binary_sensor.py @@ -15,10 +15,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import InComfortConfigEntry -from .coordinator import InComfortDataCoordinator +from .coordinator import InComfortConfigEntry, InComfortDataCoordinator from .entity import IncomfortBoilerEntity PARALLEL_UPDATES = 0 @@ -71,7 +70,7 @@ SENSOR_TYPES: tuple[IncomfortBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: InComfortConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an InComfort/InTouch binary_sensor entity.""" incomfort_coordinator = entry.runtime_data diff --git a/homeassistant/components/incomfort/climate.py b/homeassistant/components/incomfort/climate.py index f814b1fb1f5..d44ba15507e 100644 --- a/homeassistant/components/incomfort/climate.py +++ b/homeassistant/components/incomfort/climate.py @@ -15,11 +15,10 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import InComfortConfigEntry from .const import CONF_LEGACY_SETPOINT_STATUS, DOMAIN -from .coordinator import InComfortDataCoordinator +from .coordinator import InComfortConfigEntry, InComfortDataCoordinator from .entity import IncomfortEntity PARALLEL_UPDATES = 1 @@ -28,7 +27,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: InComfortConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up InComfort/InTouch climate devices.""" incomfort_coordinator = entry.runtime_data @@ -74,7 +73,10 @@ class InComfortClimate(IncomfortEntity, ClimateEntity): name=f"Thermostat {room.room_no}", ) if coordinator.unique_id: - self._attr_device_info["via_device"] = (DOMAIN, coordinator.unique_id) + self._attr_device_info["via_device"] = ( + DOMAIN, + coordinator.config_entry.entry_id, + ) @property def extra_state_attributes(self) -> dict[str, Any]: diff --git a/homeassistant/components/incomfort/config_flow.py b/homeassistant/components/incomfort/config_flow.py index 8e4a5f72619..875bc25bd2f 100644 --- a/homeassistant/components/incomfort/config_flow.py +++ b/homeassistant/components/incomfort/config_flow.py @@ -28,9 +28,8 @@ from homeassistant.helpers.selector import ( ) from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo -from . import InComfortConfigEntry from .const import CONF_LEGACY_SETPOINT_STATUS, DOMAIN -from .coordinator import async_connect_gateway +from .coordinator import InComfortConfigEntry, async_connect_gateway TITLE = "Intergas InComfort/Intouch Lan2RF gateway" diff --git a/homeassistant/components/incomfort/coordinator.py b/homeassistant/components/incomfort/coordinator.py index 3436d40298a..5c72b9daa06 100644 --- a/homeassistant/components/incomfort/coordinator.py +++ b/homeassistant/components/incomfort/coordinator.py @@ -12,12 +12,15 @@ from incomfortclient import ( InvalidHeaterList, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryError from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +type InComfortConfigEntry = ConfigEntry[InComfortDataCoordinator] + _LOGGER = logging.getLogger(__name__) UPDATE_INTERVAL = 30 @@ -50,14 +53,20 @@ async def async_connect_gateway( class InComfortDataCoordinator(DataUpdateCoordinator[InComfortData]): """Data coordinator for InComfort entities.""" + config_entry: InComfortConfigEntry + def __init__( - self, hass: HomeAssistant, incomfort_data: InComfortData, unique_id: str | None + self, + hass: HomeAssistant, + config_entry: InComfortConfigEntry, + incomfort_data: InComfortData, ) -> None: """Initialize coordinator.""" - self.unique_id = unique_id + self.unique_id = config_entry.unique_id super().__init__( hass, _LOGGER, + config_entry=config_entry, name="InComfort datacoordinator", update_interval=timedelta(seconds=UPDATE_INTERVAL), ) diff --git a/homeassistant/components/incomfort/diagnostics.py b/homeassistant/components/incomfort/diagnostics.py index a2f89a94f58..4d7af14eac7 100644 --- a/homeassistant/components/incomfort/diagnostics.py +++ b/homeassistant/components/incomfort/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_PASSWORD from homeassistant.core import HomeAssistant, callback -from . import InComfortConfigEntry +from .coordinator import InComfortConfigEntry REDACT_CONFIG = {CONF_PASSWORD} diff --git a/homeassistant/components/incomfort/entity.py b/homeassistant/components/incomfort/entity.py index 1924c91376b..1e0d357e8e0 100644 --- a/homeassistant/components/incomfort/entity.py +++ b/homeassistant/components/incomfort/entity.py @@ -29,4 +29,7 @@ class IncomfortBoilerEntity(IncomfortEntity): serial_number=heater.serial_no, ) if coordinator.unique_id: - self._attr_device_info["via_device"] = (DOMAIN, coordinator.unique_id) + self._attr_device_info["via_device"] = ( + DOMAIN, + coordinator.config_entry.entry_id, + ) diff --git a/homeassistant/components/incomfort/sensor.py b/homeassistant/components/incomfort/sensor.py index e3f3fc785b2..e344fb01aae 100644 --- a/homeassistant/components/incomfort/sensor.py +++ b/homeassistant/components/incomfort/sensor.py @@ -15,11 +15,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory, UnitOfPressure, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import InComfortConfigEntry -from .coordinator import InComfortDataCoordinator +from .coordinator import InComfortConfigEntry, InComfortDataCoordinator from .entity import IncomfortBoilerEntity PARALLEL_UPDATES = 0 @@ -68,7 +67,7 @@ SENSOR_TYPES: tuple[IncomfortSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: InComfortConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up InComfort/InTouch sensor entities.""" incomfort_coordinator = entry.runtime_data diff --git a/homeassistant/components/incomfort/strings.json b/homeassistant/components/incomfort/strings.json index 15e28b6e0b9..73ba88078a8 100644 --- a/homeassistant/components/incomfort/strings.json +++ b/homeassistant/components/incomfort/strings.json @@ -2,7 +2,7 @@ "config": { "step": { "user": { - "description": "Set up new Intergas gateway, some older systems might not need credentials to be set up. For newer devices authentication is required.", + "description": "Set up new Intergas gateway. Note that some older systems might not accept credentials to be set up. For newer devices authentication is required.", "data": { "host": "[%key:common::config_flow::data::host%]", "username": "[%key:common::config_flow::data::username%]", diff --git a/homeassistant/components/incomfort/water_heater.py b/homeassistant/components/incomfort/water_heater.py index 0ab4a6a06b8..2a2c7cc47da 100644 --- a/homeassistant/components/incomfort/water_heater.py +++ b/homeassistant/components/incomfort/water_heater.py @@ -10,10 +10,9 @@ from incomfortclient import Heater as InComfortHeater from homeassistant.components.water_heater import WaterHeaterEntity from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import InComfortConfigEntry -from .coordinator import InComfortDataCoordinator +from .coordinator import InComfortConfigEntry, InComfortDataCoordinator from .entity import IncomfortBoilerEntity _LOGGER = logging.getLogger(__name__) @@ -26,7 +25,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: InComfortConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an InComfort/InTouch water_heater device.""" incomfort_coordinator = entry.runtime_data diff --git a/homeassistant/components/inkbird/sensor.py b/homeassistant/components/inkbird/sensor.py index 05b2ebbafa0..efda28b110d 100644 --- a/homeassistant/components/inkbird/sensor.py +++ b/homeassistant/components/inkbird/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -98,7 +98,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the INKBIRD BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/insteon/binary_sensor.py b/homeassistant/components/insteon/binary_sensor.py index abb26b7f8e8..887c8fb64a3 100644 --- a/homeassistant/components/insteon/binary_sensor.py +++ b/homeassistant/components/insteon/binary_sensor.py @@ -22,7 +22,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -46,7 +46,7 @@ SENSOR_TYPES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon binary sensors from a config entry.""" diff --git a/homeassistant/components/insteon/climate.py b/homeassistant/components/insteon/climate.py index 506841e7efb..eb33e3ab88c 100644 --- a/homeassistant/components/insteon/climate.py +++ b/homeassistant/components/insteon/climate.py @@ -20,7 +20,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -55,7 +55,7 @@ FAN_MODES = {4: FAN_AUTO, 8: FAN_ONLY} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon climate entities from a config entry.""" diff --git a/homeassistant/components/insteon/cover.py b/homeassistant/components/insteon/cover.py index fe4f484798d..679ee67a1de 100644 --- a/homeassistant/components/insteon/cover.py +++ b/homeassistant/components/insteon/cover.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -22,7 +22,7 @@ from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon covers from a config entry.""" diff --git a/homeassistant/components/insteon/fan.py b/homeassistant/components/insteon/fan.py index 0f1c70b9ea8..f4e0abf3d54 100644 --- a/homeassistant/components/insteon/fan.py +++ b/homeassistant/components/insteon/fan.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -26,7 +26,7 @@ SPEED_RANGE = (1, 255) # off is not included async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon fans from a config entry.""" diff --git a/homeassistant/components/insteon/light.py b/homeassistant/components/insteon/light.py index d19f3cca34a..e4f09fe5689 100644 --- a/homeassistant/components/insteon/light.py +++ b/homeassistant/components/insteon/light.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -22,7 +22,7 @@ MAX_BRIGHTNESS = 255 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon lights from a config entry.""" diff --git a/homeassistant/components/insteon/lock.py b/homeassistant/components/insteon/lock.py index d5f30eacbac..787b0c583cc 100644 --- a/homeassistant/components/insteon/lock.py +++ b/homeassistant/components/insteon/lock.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -17,7 +17,7 @@ from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon locks from a config entry.""" diff --git a/homeassistant/components/insteon/strings.json b/homeassistant/components/insteon/strings.json index 4a8aadb70db..538107dd816 100644 --- a/homeassistant/components/insteon/strings.json +++ b/homeassistant/components/insteon/strings.json @@ -144,7 +144,7 @@ }, "reload": { "name": "[%key:common::action::reload%]", - "description": "Reloads all records. If true the current records are cleared from memory (does not effect the device) and the records are reloaded. If false the existing records are left in place and only missing records are added. Default is false." + "description": "If enabled, all current records are cleared from memory (does not effect the device) and reloaded. Otherwise the existing records are left in place and only missing records are added." } } }, diff --git a/homeassistant/components/insteon/switch.py b/homeassistant/components/insteon/switch.py index 67ce5fa8c0d..e3f7cf3d7a9 100644 --- a/homeassistant/components/insteon/switch.py +++ b/homeassistant/components/insteon/switch.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .entity import InsteonEntity @@ -17,7 +17,7 @@ from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Insteon switches from a config entry.""" diff --git a/homeassistant/components/insteon/utils.py b/homeassistant/components/insteon/utils.py index 5b1d6379328..4ee859934d2 100644 --- a/homeassistant/components/insteon/utils.py +++ b/homeassistant/components/insteon/utils.py @@ -43,7 +43,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_send, dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_CAT, @@ -415,7 +415,7 @@ def async_add_insteon_entities( hass: HomeAssistant, platform: Platform, entity_type: type[InsteonEntity], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, discovery_info: dict[str, Any], ) -> None: """Add an Insteon group to a platform.""" @@ -432,7 +432,7 @@ def async_add_insteon_devices( hass: HomeAssistant, platform: Platform, entity_type: type[InsteonEntity], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add all entities to a platform.""" for address in devices: diff --git a/homeassistant/components/integration/sensor.py b/homeassistant/components/integration/sensor.py index 27aa74d0785..df5342111a7 100644 --- a/homeassistant/components/integration/sensor.py +++ b/homeassistant/components/integration/sensor.py @@ -42,7 +42,10 @@ from homeassistant.core import ( from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import ( async_call_later, async_track_state_change_event, @@ -234,7 +237,7 @@ class IntegrationSensorExtraStoredData(SensorExtraStoredData): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Integration - Riemann sum integral config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/intellifire/__init__.py b/homeassistant/components/intellifire/__init__.py index ce78f1a6fa3..cda30820a2f 100644 --- a/homeassistant/components/intellifire/__init__.py +++ b/homeassistant/components/intellifire/__init__.py @@ -128,9 +128,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) from err # Construct coordinator - data_update_coordinator = IntellifireDataUpdateCoordinator( - hass=hass, fireplace=fireplace - ) + data_update_coordinator = IntellifireDataUpdateCoordinator(hass, entry, fireplace) LOGGER.debug("Fireplace to Initialized - Awaiting first refresh") await data_update_coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/intellifire/binary_sensor.py b/homeassistant/components/intellifire/binary_sensor.py index 7d00bdfc26d..3da1d2e3dc0 100644 --- a/homeassistant/components/intellifire/binary_sensor.py +++ b/homeassistant/components/intellifire/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IntellifireDataUpdateCoordinator from .const import DOMAIN @@ -152,7 +152,7 @@ INTELLIFIRE_BINARY_SENSORS: tuple[IntellifireBinarySensorEntityDescription, ...] async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a IntelliFire On/Off Sensor.""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/intellifire/climate.py b/homeassistant/components/intellifire/climate.py index f72df254424..f067f2a849d 100644 --- a/homeassistant/components/intellifire/climate.py +++ b/homeassistant/components/intellifire/climate.py @@ -13,7 +13,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IntellifireDataUpdateCoordinator from .const import DEFAULT_THERMOSTAT_TEMP, DOMAIN, LOGGER @@ -27,7 +27,7 @@ INTELLIFIRE_CLIMATES: tuple[ClimateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure the fan entry..""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/intellifire/coordinator.py b/homeassistant/components/intellifire/coordinator.py index b4f03f4b5c8..6a23e7438db 100644 --- a/homeassistant/components/intellifire/coordinator.py +++ b/homeassistant/components/intellifire/coordinator.py @@ -9,6 +9,7 @@ from intellifire4py.control import IntelliFireController from intellifire4py.model import IntelliFirePollData from intellifire4py.read import IntelliFireDataProvider +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -19,15 +20,19 @@ from .const import DOMAIN, LOGGER class IntellifireDataUpdateCoordinator(DataUpdateCoordinator[IntelliFirePollData]): """Class to manage the polling of the fireplace API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, fireplace: UnifiedFireplace, ) -> None: """Initialize the Coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=15), ) diff --git a/homeassistant/components/intellifire/fan.py b/homeassistant/components/intellifire/fan.py index c5bec07faaa..174d964d357 100644 --- a/homeassistant/components/intellifire/fan.py +++ b/homeassistant/components/intellifire/fan.py @@ -17,7 +17,7 @@ from homeassistant.components.fan import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -58,7 +58,7 @@ INTELLIFIRE_FANS: tuple[IntellifireFanEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fans.""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/intellifire/light.py b/homeassistant/components/intellifire/light.py index 5f25b5de823..0cf5c7774ed 100644 --- a/homeassistant/components/intellifire/light.py +++ b/homeassistant/components/intellifire/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LOGGER from .coordinator import IntellifireDataUpdateCoordinator @@ -85,7 +85,7 @@ class IntellifireLight(IntellifireEntity, LightEntity): async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fans.""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/intellifire/number.py b/homeassistant/components/intellifire/number.py index 17ed3b7bd27..0776835833e 100644 --- a/homeassistant/components/intellifire/number.py +++ b/homeassistant/components/intellifire/number.py @@ -11,7 +11,7 @@ from homeassistant.components.number import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LOGGER from .coordinator import IntellifireDataUpdateCoordinator @@ -21,7 +21,7 @@ from .entity import IntellifireEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fans.""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/intellifire/sensor.py b/homeassistant/components/intellifire/sensor.py index eaff89d08e7..7763fb1b9b2 100644 --- a/homeassistant/components/intellifire/sensor.py +++ b/homeassistant/components/intellifire/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .const import DOMAIN @@ -141,7 +141,9 @@ INTELLIFIRE_SENSORS: tuple[IntellifireSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Define setup entry call.""" diff --git a/homeassistant/components/intellifire/switch.py b/homeassistant/components/intellifire/switch.py index ac6096497b6..2185ad47cae 100644 --- a/homeassistant/components/intellifire/switch.py +++ b/homeassistant/components/intellifire/switch.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IntellifireDataUpdateCoordinator from .const import DOMAIN @@ -53,7 +53,7 @@ INTELLIFIRE_SWITCHES: tuple[IntellifireSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure switch entities.""" coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/iometer/__init__.py b/homeassistant/components/iometer/__init__.py index 5106d449fed..bbf046e70e9 100644 --- a/homeassistant/components/iometer/__init__.py +++ b/homeassistant/components/iometer/__init__.py @@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IOmeterConfigEntry) -> b except IOmeterConnectionError as err: raise ConfigEntryNotReady from err - coordinator = IOMeterCoordinator(hass, client) + coordinator = IOMeterCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/iometer/coordinator.py b/homeassistant/components/iometer/coordinator.py index 3321b032e4b..708983fb28e 100644 --- a/homeassistant/components/iometer/coordinator.py +++ b/homeassistant/components/iometer/coordinator.py @@ -32,17 +32,23 @@ class IOMeterCoordinator(DataUpdateCoordinator[IOmeterData]): config_entry: IOmeterConfigEntry client: IOmeterClient - def __init__(self, hass: HomeAssistant, client: IOmeterClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: IOmeterConfigEntry, + client: IOmeterClient, + ) -> None: """Initialize coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=DEFAULT_SCAN_INTERVAL, ) self.client = client - self.identifier = self.config_entry.entry_id + self.identifier = config_entry.entry_id async def _async_update_data(self) -> IOmeterData: """Update data async.""" diff --git a/homeassistant/components/iometer/sensor.py b/homeassistant/components/iometer/sensor.py index 7d4c1155e8b..3dff3cc6ea9 100644 --- a/homeassistant/components/iometer/sensor.py +++ b/homeassistant/components/iometer/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import IOMeterCoordinator, IOmeterData @@ -111,7 +111,7 @@ SENSOR_TYPES: list[IOmeterEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sensors.""" coordinator: IOMeterCoordinator = config_entry.runtime_data diff --git a/homeassistant/components/ios/sensor.py b/homeassistant/components/ios/sensor.py index a97c2145919..a3c9876a884 100644 --- a/homeassistant/components/ios/sensor.py +++ b/homeassistant/components/ios/sensor.py @@ -14,7 +14,10 @@ from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.icon import icon_for_battery_level from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -64,7 +67,7 @@ def setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up iOS from a config entry.""" async_add_entities( diff --git a/homeassistant/components/iotawatt/coordinator.py b/homeassistant/components/iotawatt/coordinator.py index 4f9ac1f94b7..13802ebdd76 100644 --- a/homeassistant/components/iotawatt/coordinator.py +++ b/homeassistant/components/iotawatt/coordinator.py @@ -26,13 +26,14 @@ class IotawattUpdater(DataUpdateCoordinator): """Class to manage fetching update data from the IoTaWatt Energy Device.""" api: Iotawatt | None = None + config_entry: ConfigEntry def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize IotaWattUpdater object.""" - self.entry = entry super().__init__( hass=hass, logger=_LOGGER, + config_entry=entry, name=entry.title, update_interval=timedelta(seconds=30), request_refresh_debouncer=Debouncer( @@ -57,11 +58,11 @@ class IotawattUpdater(DataUpdateCoordinator): """Fetch sensors from IoTaWatt device.""" if self.api is None: api = Iotawatt( - self.entry.title, - self.entry.data[CONF_HOST], + self.config_entry.title, + self.config_entry.data[CONF_HOST], httpx_client.get_async_client(self.hass), - self.entry.data.get(CONF_USERNAME), - self.entry.data.get(CONF_PASSWORD), + self.config_entry.data.get(CONF_USERNAME), + self.config_entry.data.get(CONF_PASSWORD), integratedInterval="d", includeNonTotalSensors=False, ) diff --git a/homeassistant/components/iotawatt/sensor.py b/homeassistant/components/iotawatt/sensor.py index c9af588c160..f5210f7fbba 100644 --- a/homeassistant/components/iotawatt/sensor.py +++ b/homeassistant/components/iotawatt/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -114,7 +114,7 @@ ENTITY_DESCRIPTION_KEY_MAP: dict[str, IotaWattSensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add sensors for passed config_entry in HA.""" coordinator: IotawattUpdater = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/iotty/__init__.py b/homeassistant/components/iotty/__init__.py index 804f3f40196..c9eb2639348 100644 --- a/homeassistant/components/iotty/__init__.py +++ b/homeassistant/components/iotty/__init__.py @@ -2,12 +2,8 @@ from __future__ import annotations -from dataclasses import dataclass import logging -from iottycloud.device import Device - -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.config_entry_oauth2_flow import ( @@ -15,22 +11,16 @@ from homeassistant.helpers.config_entry_oauth2_flow import ( async_get_config_entry_implementation, ) -from . import coordinator +from .coordinator import ( + IottyConfigEntry, + IottyConfigEntryData, + IottyDataUpdateCoordinator, +) _LOGGER = logging.getLogger(__name__) PLATFORMS: list[Platform] = [Platform.COVER, Platform.SWITCH] -type IottyConfigEntry = ConfigEntry[IottyConfigEntryData] - - -@dataclass -class IottyConfigEntryData: - """Contains config entry data for iotty.""" - - known_devices: set[Device] - coordinator: coordinator.IottyDataUpdateCoordinator - async def async_setup_entry(hass: HomeAssistant, entry: IottyConfigEntry) -> bool: """Set up iotty from a config entry.""" @@ -39,9 +29,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IottyConfigEntry) -> boo implementation = await async_get_config_entry_implementation(hass, entry) session = OAuth2Session(hass, entry, implementation) - data_update_coordinator = coordinator.IottyDataUpdateCoordinator( - hass, entry, session - ) + data_update_coordinator = IottyDataUpdateCoordinator(hass, entry, session) entry.runtime_data = IottyConfigEntryData(set(), data_update_coordinator) @@ -51,6 +39,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: IottyConfigEntry) -> boo return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: IottyConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/iotty/coordinator.py b/homeassistant/components/iotty/coordinator.py index 420248f7724..af870c347bd 100644 --- a/homeassistant/components/iotty/coordinator.py +++ b/homeassistant/components/iotty/coordinator.py @@ -32,16 +32,27 @@ class IottyData: devices: list[Device] +@dataclass +class IottyConfigEntryData: + """Contains config entry data for iotty.""" + + known_devices: set[Device] + coordinator: IottyDataUpdateCoordinator + + +type IottyConfigEntry = ConfigEntry[IottyConfigEntryData] + + class IottyDataUpdateCoordinator(DataUpdateCoordinator[IottyData]): """Class to manage fetching Iotty data.""" - config_entry: ConfigEntry + config_entry: IottyConfigEntry _entities: dict[str, Entity] _devices: list[Device] _device_registry: dr.DeviceRegistry def __init__( - self, hass: HomeAssistant, entry: ConfigEntry, session: OAuth2Session + self, hass: HomeAssistant, entry: IottyConfigEntry, session: OAuth2Session ) -> None: """Initialize the coordinator.""" _LOGGER.debug("Initializing iotty data update coordinator") @@ -49,11 +60,11 @@ class IottyDataUpdateCoordinator(DataUpdateCoordinator[IottyData]): super().__init__( hass, _LOGGER, + config_entry=entry, name=f"{DOMAIN}_coordinator", update_interval=UPDATE_INTERVAL, ) - self.config_entry = entry self._entities = {} self._devices = [] self.iotty = api.IottyProxy( diff --git a/homeassistant/components/iotty/cover.py b/homeassistant/components/iotty/cover.py index 50a4a1deeba..d8b11131f4f 100644 --- a/homeassistant/components/iotty/cover.py +++ b/homeassistant/components/iotty/cover.py @@ -16,11 +16,10 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IottyConfigEntry from .api import IottyProxy -from .coordinator import IottyDataUpdateCoordinator +from .coordinator import IottyConfigEntry, IottyDataUpdateCoordinator from .entity import IottyEntity _LOGGER = logging.getLogger(__name__) @@ -29,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: IottyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Activate the iotty Shutter component.""" _LOGGER.debug("Setup COVER entry id is %s", config_entry.entry_id) diff --git a/homeassistant/components/iotty/switch.py b/homeassistant/components/iotty/switch.py index b06e3ea308d..113a4439e85 100644 --- a/homeassistant/components/iotty/switch.py +++ b/homeassistant/components/iotty/switch.py @@ -20,11 +20,10 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IottyConfigEntry from .api import IottyProxy -from .coordinator import IottyDataUpdateCoordinator +from .coordinator import IottyConfigEntry, IottyDataUpdateCoordinator from .entity import IottyEntity _LOGGER = logging.getLogger(__name__) @@ -46,7 +45,7 @@ ENTITIES: dict[str, SwitchEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: IottyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Activate the iotty Switch component.""" _LOGGER.debug("Setup SWITCH entry id is %s", config_entry.entry_id) diff --git a/homeassistant/components/ipma/manifest.json b/homeassistant/components/ipma/manifest.json index 1abd7807213..971525e013f 100644 --- a/homeassistant/components/ipma/manifest.json +++ b/homeassistant/components/ipma/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/ipma", "iot_class": "cloud_polling", "loggers": ["geopy", "pyipma"], - "requirements": ["pyipma==3.0.8"] + "requirements": ["pyipma==3.0.9"] } diff --git a/homeassistant/components/ipma/sensor.py b/homeassistant/components/ipma/sensor.py index 2a921cdbb04..78fd018cf9a 100644 --- a/homeassistant/components/ipma/sensor.py +++ b/homeassistant/components/ipma/sensor.py @@ -16,7 +16,7 @@ from pyipma.uv import UV from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from .const import DATA_API, DATA_LOCATION, DOMAIN, MIN_TIME_BETWEEN_UPDATES @@ -86,7 +86,9 @@ SENSOR_TYPES: tuple[IPMASensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the IPMA sensor platform.""" api = hass.data[DOMAIN][entry.entry_id][DATA_API] diff --git a/homeassistant/components/ipma/weather.py b/homeassistant/components/ipma/weather.py index 855587eee2e..d285f9e1ad3 100644 --- a/homeassistant/components/ipma/weather.py +++ b/homeassistant/components/ipma/weather.py @@ -31,7 +31,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sun import is_up from homeassistant.util import Throttle @@ -51,7 +51,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" api = hass.data[DOMAIN][config_entry.entry_id][DATA_API] diff --git a/homeassistant/components/ipp/__init__.py b/homeassistant/components/ipp/__init__.py index 0a94795613b..99332dca0e2 100644 --- a/homeassistant/components/ipp/__init__.py +++ b/homeassistant/components/ipp/__init__.py @@ -2,39 +2,17 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_HOST, - CONF_PORT, - CONF_SSL, - CONF_VERIFY_SSL, - Platform, -) +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from .const import CONF_BASE_PATH -from .coordinator import IPPDataUpdateCoordinator +from .coordinator import IPPConfigEntry, IPPDataUpdateCoordinator PLATFORMS = [Platform.SENSOR] -type IPPConfigEntry = ConfigEntry[IPPDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: IPPConfigEntry) -> bool: """Set up IPP from a config entry.""" - # config flow sets this to either UUID, serial number or None - if (device_id := entry.unique_id) is None: - device_id = entry.entry_id - - coordinator = IPPDataUpdateCoordinator( - hass, - host=entry.data[CONF_HOST], - port=entry.data[CONF_PORT], - base_path=entry.data[CONF_BASE_PATH], - tls=entry.data[CONF_SSL], - verify_ssl=entry.data[CONF_VERIFY_SSL], - device_id=device_id, - ) + coordinator = IPPDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator @@ -44,6 +22,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: IPPConfigEntry) -> bool: return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: IPPConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/ipp/coordinator.py b/homeassistant/components/ipp/coordinator.py index 535b18bcaf0..1c3dc4d0a03 100644 --- a/homeassistant/components/ipp/coordinator.py +++ b/homeassistant/components/ipp/coordinator.py @@ -7,45 +7,42 @@ import logging from pyipp import IPP, IPPError, Printer as IPPPrinter +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL, CONF_VERIFY_SSL from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import DOMAIN +from .const import CONF_BASE_PATH, DOMAIN SCAN_INTERVAL = timedelta(seconds=60) _LOGGER = logging.getLogger(__name__) +type IPPConfigEntry = ConfigEntry[IPPDataUpdateCoordinator] + class IPPDataUpdateCoordinator(DataUpdateCoordinator[IPPPrinter]): """Class to manage fetching IPP data from single endpoint.""" - def __init__( - self, - hass: HomeAssistant, - *, - host: str, - port: int, - base_path: str, - tls: bool, - verify_ssl: bool, - device_id: str, - ) -> None: + config_entry: IPPConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: IPPConfigEntry) -> None: """Initialize global IPP data updater.""" - self.device_id = device_id + self.device_id = config_entry.unique_id or config_entry.entry_id self.ipp = IPP( - host=host, - port=port, - base_path=base_path, - tls=tls, - verify_ssl=verify_ssl, - session=async_get_clientsession(hass, verify_ssl), + host=config_entry.data[CONF_HOST], + port=config_entry.data[CONF_PORT], + base_path=config_entry.data[CONF_BASE_PATH], + tls=config_entry.data[CONF_SSL], + verify_ssl=config_entry.data[CONF_VERIFY_SSL], + session=async_get_clientsession(hass, config_entry.data[CONF_VERIFY_SSL]), ) super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/ipp/diagnostics.py b/homeassistant/components/ipp/diagnostics.py index 9b10dc68966..cd136e78373 100644 --- a/homeassistant/components/ipp/diagnostics.py +++ b/homeassistant/components/ipp/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import IPPConfigEntry +from .coordinator import IPPConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/ipp/sensor.py b/homeassistant/components/ipp/sensor.py index a2792c7749b..e16819a54ff 100644 --- a/homeassistant/components/ipp/sensor.py +++ b/homeassistant/components/ipp/sensor.py @@ -17,10 +17,9 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import ATTR_LOCATION, PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import IPPConfigEntry from .const import ( ATTR_COMMAND_SET, ATTR_INFO, @@ -32,6 +31,7 @@ from .const import ( ATTR_STATE_REASON, ATTR_URI_SUPPORTED, ) +from .coordinator import IPPConfigEntry from .entity import IPPEntity @@ -87,7 +87,7 @@ PRINTER_SENSORS: tuple[IPPSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IPPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up IPP sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/iqvia/sensor.py b/homeassistant/components/iqvia/sensor.py index d04e0885454..64492c634e9 100644 --- a/homeassistant/components/iqvia/sensor.py +++ b/homeassistant/components/iqvia/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_STATE from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -127,7 +127,9 @@ INDEX_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up IQVIA sensors based on a config entry.""" sensors: list[ForecastSensor | IndexSensor] = [ diff --git a/homeassistant/components/iron_os/__init__.py b/homeassistant/components/iron_os/__init__.py index 6af6abb1436..77099e48b41 100644 --- a/homeassistant/components/iron_os/__init__.py +++ b/homeassistant/components/iron_os/__init__.py @@ -8,7 +8,6 @@ from typing import TYPE_CHECKING from pynecil import IronOSUpdate, Pynecil from homeassistant.components import bluetooth -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -19,6 +18,7 @@ from homeassistant.util.hass_dict import HassKey from .const import DOMAIN from .coordinator import ( + IronOSConfigEntry, IronOSCoordinators, IronOSFirmwareUpdateCoordinator, IronOSLiveDataCoordinator, @@ -39,7 +39,6 @@ PLATFORMS: list[Platform] = [ CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) -type IronOSConfigEntry = ConfigEntry[IronOSCoordinators] IRON_OS_KEY: HassKey[IronOSFirmwareUpdateCoordinator] = HassKey(DOMAIN) @@ -73,10 +72,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: IronOSConfigEntry) -> bo device = Pynecil(ble_device) - live_data = IronOSLiveDataCoordinator(hass, device) + live_data = IronOSLiveDataCoordinator(hass, entry, device) await live_data.async_config_entry_first_refresh() - settings = IronOSSettingsCoordinator(hass, device) + settings = IronOSSettingsCoordinator(hass, entry, device) await settings.async_config_entry_first_refresh() entry.runtime_data = IronOSCoordinators( diff --git a/homeassistant/components/iron_os/binary_sensor.py b/homeassistant/components/iron_os/binary_sensor.py index 81ba0e08c95..66e642c7aaa 100644 --- a/homeassistant/components/iron_os/binary_sensor.py +++ b/homeassistant/components/iron_os/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IronOSConfigEntry from .coordinator import IronOSLiveDataCoordinator @@ -29,7 +29,7 @@ class PinecilBinarySensor(StrEnum): async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors from a config entry.""" coordinator = entry.runtime_data.live_data diff --git a/homeassistant/components/iron_os/button.py b/homeassistant/components/iron_os/button.py index be16148a656..e069ddb1d9f 100644 --- a/homeassistant/components/iron_os/button.py +++ b/homeassistant/components/iron_os/button.py @@ -10,7 +10,7 @@ from pynecil import CharSetting from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IronOSConfigEntry from .coordinator import IronOSCoordinators @@ -53,7 +53,7 @@ BUTTON_DESCRIPTIONS: tuple[IronOSButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button entities from a config entry.""" coordinators = entry.runtime_data diff --git a/homeassistant/components/iron_os/config_flow.py b/homeassistant/components/iron_os/config_flow.py index 444db79c926..8509577114f 100644 --- a/homeassistant/components/iron_os/config_flow.py +++ b/homeassistant/components/iron_os/config_flow.py @@ -61,7 +61,7 @@ class IronOSConfigFlow(ConfigFlow, domain=DOMAIN): self._abort_if_unique_id_configured() return self.async_create_entry(title=title, data={}) - current_addresses = self._async_current_ids() + current_addresses = self._async_current_ids(include_ignore=False) for discovery_info in async_discovered_service_info(self.hass, True): address = discovery_info.address if ( diff --git a/homeassistant/components/iron_os/coordinator.py b/homeassistant/components/iron_os/coordinator.py index 080fee20762..fc89ecea43c 100644 --- a/homeassistant/components/iron_os/coordinator.py +++ b/homeassistant/components/iron_os/coordinator.py @@ -43,15 +43,19 @@ class IronOSCoordinators: settings: IronOSSettingsCoordinator +type IronOSConfigEntry = ConfigEntry[IronOSCoordinators] + + class IronOSBaseCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """IronOS base coordinator.""" device_info: DeviceInfoResponse - config_entry: ConfigEntry + config_entry: IronOSConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: IronOSConfigEntry, device: Pynecil, update_interval: timedelta, ) -> None: @@ -60,6 +64,7 @@ class IronOSBaseCoordinator[_DataT](DataUpdateCoordinator[_DataT]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=update_interval, request_refresh_debouncer=Debouncer( @@ -80,9 +85,11 @@ class IronOSBaseCoordinator[_DataT](DataUpdateCoordinator[_DataT]): class IronOSLiveDataCoordinator(IronOSBaseCoordinator[LiveDataResponse]): """IronOS coordinator.""" - def __init__(self, hass: HomeAssistant, device: Pynecil) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: IronOSConfigEntry, device: Pynecil + ) -> None: """Initialize IronOS coordinator.""" - super().__init__(hass, device=device, update_interval=SCAN_INTERVAL) + super().__init__(hass, config_entry, device, SCAN_INTERVAL) async def _async_update_data(self) -> LiveDataResponse: """Fetch data from Device.""" @@ -109,35 +116,14 @@ class IronOSLiveDataCoordinator(IronOSBaseCoordinator[LiveDataResponse]): return False -class IronOSFirmwareUpdateCoordinator(DataUpdateCoordinator[LatestRelease]): - """IronOS coordinator for retrieving update information from github.""" - - def __init__(self, hass: HomeAssistant, github: IronOSUpdate) -> None: - """Initialize IronOS coordinator.""" - super().__init__( - hass, - _LOGGER, - config_entry=None, - name=DOMAIN, - update_interval=SCAN_INTERVAL_GITHUB, - ) - self.github = github - - async def _async_update_data(self) -> LatestRelease: - """Fetch data from Github.""" - - try: - return await self.github.latest_release() - except UpdateException as e: - raise UpdateFailed("Failed to check for latest IronOS update") from e - - class IronOSSettingsCoordinator(IronOSBaseCoordinator[SettingsDataResponse]): """IronOS coordinator.""" - def __init__(self, hass: HomeAssistant, device: Pynecil) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: IronOSConfigEntry, device: Pynecil + ) -> None: """Initialize IronOS coordinator.""" - super().__init__(hass, device=device, update_interval=SCAN_INTERVAL_SETTINGS) + super().__init__(hass, config_entry, device, SCAN_INTERVAL_SETTINGS) async def _async_update_data(self) -> SettingsDataResponse: """Fetch data from Device.""" @@ -173,3 +159,26 @@ class IronOSSettingsCoordinator(IronOSBaseCoordinator[SettingsDataResponse]): ) self.async_update_listeners() await self.async_request_refresh() + + +class IronOSFirmwareUpdateCoordinator(DataUpdateCoordinator[LatestRelease]): + """IronOS coordinator for retrieving update information from github.""" + + def __init__(self, hass: HomeAssistant, github: IronOSUpdate) -> None: + """Initialize IronOS coordinator.""" + super().__init__( + hass, + _LOGGER, + config_entry=None, + name=DOMAIN, + update_interval=SCAN_INTERVAL_GITHUB, + ) + self.github = github + + async def _async_update_data(self) -> LatestRelease: + """Fetch data from Github.""" + + try: + return await self.github.latest_release() + except UpdateException as e: + raise UpdateFailed("Failed to check for latest IronOS update") from e diff --git a/homeassistant/components/iron_os/number.py b/homeassistant/components/iron_os/number.py index 518c11372c4..b8bb3c7d999 100644 --- a/homeassistant/components/iron_os/number.py +++ b/homeassistant/components/iron_os/number.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IronOSConfigEntry from .const import MAX_TEMP, MIN_TEMP @@ -327,7 +327,7 @@ PINECIL_NUMBER_DESCRIPTIONS: tuple[IronOSNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities from a config entry.""" coordinators = entry.runtime_data diff --git a/homeassistant/components/iron_os/select.py b/homeassistant/components/iron_os/select.py index e9c7f81c208..a005bf29af2 100644 --- a/homeassistant/components/iron_os/select.py +++ b/homeassistant/components/iron_os/select.py @@ -23,7 +23,7 @@ from pynecil import ( from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IronOSConfigEntry from .coordinator import IronOSCoordinators @@ -154,7 +154,7 @@ PINECIL_SELECT_DESCRIPTIONS: tuple[IronOSSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select entities from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/iron_os/sensor.py b/homeassistant/components/iron_os/sensor.py index d178b46723f..79f1e54a6f4 100644 --- a/homeassistant/components/iron_os/sensor.py +++ b/homeassistant/components/iron_os/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import IronOSConfigEntry @@ -184,7 +184,7 @@ PINECIL_SENSOR_DESCRIPTIONS: tuple[IronOSSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors from a config entry.""" coordinator = entry.runtime_data.live_data diff --git a/homeassistant/components/iron_os/switch.py b/homeassistant/components/iron_os/switch.py index d88e8cfdcb5..124b670048a 100644 --- a/homeassistant/components/iron_os/switch.py +++ b/homeassistant/components/iron_os/switch.py @@ -12,7 +12,7 @@ from pynecil import CharSetting, SettingsDataResponse from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IronOSConfigEntry from .coordinator import IronOSCoordinators @@ -100,7 +100,7 @@ SWITCH_DESCRIPTIONS: tuple[IronOSSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches from a config entry.""" diff --git a/homeassistant/components/iron_os/update.py b/homeassistant/components/iron_os/update.py index b431d321f24..4ec626ffc2a 100644 --- a/homeassistant/components/iron_os/update.py +++ b/homeassistant/components/iron_os/update.py @@ -9,7 +9,7 @@ from homeassistant.components.update import ( UpdateEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IRON_OS_KEY, IronOSConfigEntry, IronOSLiveDataCoordinator from .coordinator import IronOSFirmwareUpdateCoordinator @@ -26,7 +26,7 @@ UPDATE_DESCRIPTION = UpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: IronOSConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up IronOS update platform.""" diff --git a/homeassistant/components/iskra/__init__.py b/homeassistant/components/iskra/__init__.py index b841da9df26..21c60db20fe 100644 --- a/homeassistant/components/iskra/__init__.py +++ b/homeassistant/components/iskra/__init__.py @@ -6,7 +6,6 @@ from pyiskra.adapters import Modbus, RestAPI from pyiskra.devices import Device from pyiskra.exceptions import DeviceConnectionError, DeviceNotSupported, NotAuthorised -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_ADDRESS, CONF_HOST, @@ -21,14 +20,11 @@ from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from .const import DOMAIN, MANUFACTURER -from .coordinator import IskraDataUpdateCoordinator +from .coordinator import IskraConfigEntry, IskraDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -type IskraConfigEntry = ConfigEntry[list[IskraDataUpdateCoordinator]] - - async def async_setup_entry(hass: HomeAssistant, entry: IskraConfigEntry) -> bool: """Set up iskra device from a config entry.""" conf = entry.data @@ -79,11 +75,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: IskraConfigEntry) -> boo ) coordinators = [ - IskraDataUpdateCoordinator(hass, child_device) + IskraDataUpdateCoordinator(hass, entry, child_device) for child_device in base_device.get_child_devices() ] else: - coordinators = [IskraDataUpdateCoordinator(hass, base_device)] + coordinators = [IskraDataUpdateCoordinator(hass, entry, base_device)] for coordinator in coordinators: await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/iskra/coordinator.py b/homeassistant/components/iskra/coordinator.py index 175d8ed4c86..d476556e96d 100644 --- a/homeassistant/components/iskra/coordinator.py +++ b/homeassistant/components/iskra/coordinator.py @@ -11,6 +11,7 @@ from pyiskra.exceptions import ( NotAuthorised, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -18,21 +19,26 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) +type IskraConfigEntry = ConfigEntry[list[IskraDataUpdateCoordinator]] + class IskraDataUpdateCoordinator(DataUpdateCoordinator[None]): """Class to manage fetching Iskra data.""" - def __init__(self, hass: HomeAssistant, device: Device) -> None: + config_entry: IskraConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: IskraConfigEntry, device: Device + ) -> None: """Initialize.""" self.device = device - update_interval = timedelta(seconds=60) - super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, - update_interval=update_interval, + update_interval=timedelta(seconds=60), ) async def _async_update_data(self) -> None: diff --git a/homeassistant/components/iskra/sensor.py b/homeassistant/components/iskra/sensor.py index df9e3ec53f9..10aa5555249 100644 --- a/homeassistant/components/iskra/sensor.py +++ b/homeassistant/components/iskra/sensor.py @@ -24,9 +24,8 @@ from homeassistant.const import ( UnitOfReactivePower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import IskraConfigEntry from .const import ( ATTR_FREQUENCY, ATTR_NON_RESETTABLE_COUNTER, @@ -44,7 +43,7 @@ from .const import ( ATTR_TOTAL_APPARENT_POWER, ATTR_TOTAL_REACTIVE_POWER, ) -from .coordinator import IskraDataUpdateCoordinator +from .coordinator import IskraConfigEntry, IskraDataUpdateCoordinator from .entity import IskraEntity @@ -208,7 +207,7 @@ def get_counter_entity_description( async def async_setup_entry( hass: HomeAssistant, entry: IskraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Iskra sensors based on config_entry.""" diff --git a/homeassistant/components/islamic_prayer_times/__init__.py b/homeassistant/components/islamic_prayer_times/__init__.py index d61eba343ac..731d1324c71 100644 --- a/homeassistant/components/islamic_prayer_times/__init__.py +++ b/homeassistant/components/islamic_prayer_times/__init__.py @@ -4,20 +4,20 @@ from __future__ import annotations import logging -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from .coordinator import IslamicPrayerDataUpdateCoordinator +from .coordinator import ( + IslamicPrayerDataUpdateCoordinator, + IslamicPrayerTimesConfigEntry, +) PLATFORMS = [Platform.SENSOR] _LOGGER = logging.getLogger(__name__) -type IslamicPrayerTimesConfigEntry = ConfigEntry[IslamicPrayerDataUpdateCoordinator] - async def async_setup_entry( hass: HomeAssistant, config_entry: IslamicPrayerTimesConfigEntry @@ -36,7 +36,7 @@ async def async_setup_entry( await er.async_migrate_entries(hass, config_entry.entry_id, update_unique_id) - coordinator = IslamicPrayerDataUpdateCoordinator(hass) + coordinator = IslamicPrayerDataUpdateCoordinator(hass, config_entry) await coordinator.async_config_entry_first_refresh() config_entry.runtime_data = coordinator @@ -48,7 +48,9 @@ async def async_setup_entry( return True -async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_migrate_entry( + hass: HomeAssistant, config_entry: IslamicPrayerTimesConfigEntry +) -> bool: """Migrate old entry.""" _LOGGER.debug("Migrating from version %s", config_entry.version) diff --git a/homeassistant/components/islamic_prayer_times/coordinator.py b/homeassistant/components/islamic_prayer_times/coordinator.py index 35903afa393..a6cd3fb151e 100644 --- a/homeassistant/components/islamic_prayer_times/coordinator.py +++ b/homeassistant/components/islamic_prayer_times/coordinator.py @@ -29,21 +29,26 @@ from .const import ( _LOGGER = logging.getLogger(__name__) +type IslamicPrayerTimesConfigEntry = ConfigEntry[IslamicPrayerDataUpdateCoordinator] + class IslamicPrayerDataUpdateCoordinator(DataUpdateCoordinator[dict[str, datetime]]): """Islamic Prayer Client Object.""" - config_entry: ConfigEntry + config_entry: IslamicPrayerTimesConfigEntry - def __init__(self, hass: HomeAssistant) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: IslamicPrayerTimesConfigEntry + ) -> None: """Initialize the Islamic Prayer client.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, ) - self.latitude = self.config_entry.data[CONF_LATITUDE] - self.longitude = self.config_entry.data[CONF_LONGITUDE] + self.latitude = config_entry.data[CONF_LATITUDE] + self.longitude = config_entry.data[CONF_LONGITUDE] self.event_unsub: CALLBACK_TYPE | None = None @property diff --git a/homeassistant/components/islamic_prayer_times/sensor.py b/homeassistant/components/islamic_prayer_times/sensor.py index c46b629d2d8..3d35786186e 100644 --- a/homeassistant/components/islamic_prayer_times/sensor.py +++ b/homeassistant/components/islamic_prayer_times/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import IslamicPrayerTimesConfigEntry @@ -51,7 +51,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: IslamicPrayerTimesConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Islamic prayer times sensor platform.""" diff --git a/homeassistant/components/israel_rail/__init__.py b/homeassistant/components/israel_rail/__init__.py index 3c33a159a63..ed800f559d4 100644 --- a/homeassistant/components/israel_rail/__init__.py +++ b/homeassistant/components/israel_rail/__init__.py @@ -4,13 +4,12 @@ import logging from israelrailapi import TrainSchedule -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from .const import CONF_DESTINATION, CONF_START, DOMAIN -from .coordinator import IsraelRailDataUpdateCoordinator +from .coordinator import IsraelRailConfigEntry, IsraelRailDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -18,9 +17,6 @@ _LOGGER = logging.getLogger(__name__) PLATFORMS: list[Platform] = [Platform.SENSOR] -type IsraelRailConfigEntry = ConfigEntry[IsraelRailDataUpdateCoordinator] - - async def async_setup_entry(hass: HomeAssistant, entry: IsraelRailConfigEntry) -> bool: """Set up Israel rail from a config entry.""" config = entry.data @@ -43,7 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IsraelRailConfigEntry) - ) from e israel_rail_coordinator = IsraelRailDataUpdateCoordinator( - hass, train_schedule, start, destination + hass, entry, train_schedule, start, destination ) await israel_rail_coordinator.async_config_entry_first_refresh() entry.runtime_data = israel_rail_coordinator diff --git a/homeassistant/components/israel_rail/coordinator.py b/homeassistant/components/israel_rail/coordinator.py index b022e3fd790..190ed938790 100644 --- a/homeassistant/components/israel_rail/coordinator.py +++ b/homeassistant/components/israel_rail/coordinator.py @@ -38,14 +38,18 @@ def departure_time(train_route: TrainRoute) -> datetime | None: return start_datetime.astimezone() if start_datetime else None +type IsraelRailConfigEntry = ConfigEntry[IsraelRailDataUpdateCoordinator] + + class IsraelRailDataUpdateCoordinator(DataUpdateCoordinator[list[DataConnection]]): """A IsraelRail Data Update Coordinator.""" - config_entry: ConfigEntry + config_entry: IsraelRailConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: IsraelRailConfigEntry, train_schedule: TrainSchedule, start: str, destination: str, @@ -54,6 +58,7 @@ class IsraelRailDataUpdateCoordinator(DataUpdateCoordinator[list[DataConnection] super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=DEFAULT_SCAN_INTERVAL, ) diff --git a/homeassistant/components/israel_rail/sensor.py b/homeassistant/components/israel_rail/sensor.py index 132a9a74826..86b2e135cfb 100644 --- a/homeassistant/components/israel_rail/sensor.py +++ b/homeassistant/components/israel_rail/sensor.py @@ -15,13 +15,16 @@ from homeassistant.components.sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import IsraelRailConfigEntry from .const import ATTRIBUTION, DEPARTURES_COUNT, DOMAIN -from .coordinator import DataConnection, IsraelRailDataUpdateCoordinator +from .coordinator import ( + DataConnection, + IsraelRailConfigEntry, + IsraelRailDataUpdateCoordinator, +) _LOGGER = logging.getLogger(__name__) @@ -70,7 +73,7 @@ SENSORS: tuple[IsraelRailSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: IsraelRailConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor from a config entry created in the integrations UI.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/iss/sensor.py b/homeassistant/components/iss/sensor.py index f4f91f0099e..b6e98e07f8a 100644 --- a/homeassistant/components/iss/sensor.py +++ b/homeassistant/components/iss/sensor.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE, CONF_SHOW_ON_MAP from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" coordinator: DataUpdateCoordinator[IssData] = hass.data[DOMAIN] diff --git a/homeassistant/components/ista_ecotrend/__init__.py b/homeassistant/components/ista_ecotrend/__init__.py index 76ef8d13fd4..4262b354acb 100644 --- a/homeassistant/components/ista_ecotrend/__init__.py +++ b/homeassistant/components/ista_ecotrend/__init__.py @@ -6,20 +6,17 @@ import logging from pyecotrend_ista import KeycloakError, LoginError, PyEcotrendIsta, ServerError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from .const import DOMAIN -from .coordinator import IstaCoordinator +from .coordinator import IstaConfigEntry, IstaCoordinator _LOGGER = logging.getLogger(__name__) PLATFORMS: list[Platform] = [Platform.SENSOR] -type IstaConfigEntry = ConfigEntry[IstaCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: IstaConfigEntry) -> bool: """Set up ista EcoTrend from a config entry.""" @@ -42,7 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IstaConfigEntry) -> bool translation_placeholders={CONF_EMAIL: entry.data[CONF_EMAIL]}, ) from e - coordinator = IstaCoordinator(hass, ista) + coordinator = IstaCoordinator(hass, entry, ista) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/ista_ecotrend/coordinator.py b/homeassistant/components/ista_ecotrend/coordinator.py index 0f14cd06fe3..53ef4a46d20 100644 --- a/homeassistant/components/ista_ecotrend/coordinator.py +++ b/homeassistant/components/ista_ecotrend/coordinator.py @@ -18,17 +18,22 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) +type IstaConfigEntry = ConfigEntry[IstaCoordinator] + class IstaCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Ista EcoTrend data update coordinator.""" - config_entry: ConfigEntry + config_entry: IstaConfigEntry - def __init__(self, hass: HomeAssistant, ista: PyEcotrendIsta) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: IstaConfigEntry, ista: PyEcotrendIsta + ) -> None: """Initialize ista EcoTrend data update coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(days=1), ) diff --git a/homeassistant/components/ista_ecotrend/sensor.py b/homeassistant/components/ista_ecotrend/sensor.py index e96ac103741..ee54e502c26 100644 --- a/homeassistant/components/ista_ecotrend/sensor.py +++ b/homeassistant/components/ista_ecotrend/sensor.py @@ -30,13 +30,12 @@ from homeassistant.helpers.device_registry import ( DeviceEntryType, DeviceInfo, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import IstaConfigEntry from .const import DOMAIN -from .coordinator import IstaCoordinator +from .coordinator import IstaConfigEntry, IstaCoordinator from .util import IstaConsumptionType, IstaValueType, get_native_value, get_statistics _LOGGER = logging.getLogger(__name__) @@ -153,7 +152,7 @@ SENSOR_DESCRIPTIONS: tuple[IstaSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: IstaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ista EcoTrend sensors.""" diff --git a/homeassistant/components/isy994/binary_sensor.py b/homeassistant/components/isy994/binary_sensor.py index 179944ad35f..8c9ce7dcc12 100644 --- a/homeassistant/components/isy994/binary_sensor.py +++ b/homeassistant/components/isy994/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON, Platform from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import RestoreEntity @@ -54,7 +54,9 @@ DEVICE_PARENT_REQUIRED = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY binary sensor platform.""" entities: list[ diff --git a/homeassistant/components/isy994/button.py b/homeassistant/components/isy994/button.py index b3b6aa40503..a895312c45a 100644 --- a/homeassistant/components/isy994/button.py +++ b/homeassistant/components/isy994/button.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_NETWORK, DOMAIN from .models import IsyData @@ -28,7 +28,7 @@ from .models import IsyData async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ISY/IoX button from config entry.""" isy_data: IsyData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/isy994/climate.py b/homeassistant/components/isy994/climate.py index d5deba56284..57c1b6aa79d 100644 --- a/homeassistant/components/isy994/climate.py +++ b/homeassistant/components/isy994/climate.py @@ -37,7 +37,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.enum import try_parse_enum from .const import ( @@ -61,7 +61,9 @@ from .models import IsyData async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY thermostat platform.""" diff --git a/homeassistant/components/isy994/cover.py b/homeassistant/components/isy994/cover.py index b9d7ec44d27..6a660aaaf6f 100644 --- a/homeassistant/components/isy994/cover.py +++ b/homeassistant/components/isy994/cover.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import _LOGGER, DOMAIN, UOM_8_BIT_RANGE from .entity import ISYNodeEntity, ISYProgramEntity @@ -23,7 +23,9 @@ from .models import IsyData async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY cover platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/isy994/fan.py b/homeassistant/components/isy994/fan.py index fc0406e2d5f..aa6059abf49 100644 --- a/homeassistant/components/isy994/fan.py +++ b/homeassistant/components/isy994/fan.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -27,7 +27,9 @@ SPEED_RANGE = (1, 255) # off is not included async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY fan platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/isy994/light.py b/homeassistant/components/isy994/light.py index b9b269d9ca3..29df8398f97 100644 --- a/homeassistant/components/isy994/light.py +++ b/homeassistant/components/isy994/light.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import _LOGGER, CONF_RESTORE_LIGHT_STATE, DOMAIN, UOM_PERCENTAGE @@ -24,7 +24,9 @@ ATTR_LAST_BRIGHTNESS = "last_brightness" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY light platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/isy994/lock.py b/homeassistant/components/isy994/lock.py index dc2da2a6ee2..d6866a8e00c 100644 --- a/homeassistant/components/isy994/lock.py +++ b/homeassistant/components/isy994/lock.py @@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -48,7 +48,9 @@ def async_setup_lock_services(hass: HomeAssistant) -> None: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY lock platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/isy994/number.py b/homeassistant/components/isy994/number.py index c8feba1bf8d..fc30e6296d4 100644 --- a/homeassistant/components/isy994/number.py +++ b/homeassistant/components/isy994/number.py @@ -38,7 +38,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -80,7 +80,7 @@ BACKLIGHT_MEMORY_FILTER = {"memory": DEV_BL_ADDR, "cmd1": DEV_CMD_MEMORY_WRITE} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ISY/IoX number entities from config entry.""" isy_data: IsyData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/isy994/select.py b/homeassistant/components/isy994/select.py index 8befcf024d1..868c96375bb 100644 --- a/homeassistant/components/isy994/select.py +++ b/homeassistant/components/isy994/select.py @@ -34,7 +34,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import _LOGGER, DOMAIN, UOM_INDEX @@ -56,7 +56,7 @@ BACKLIGHT_MEMORY_FILTER = {"memory": DEV_BL_ADDR, "cmd1": DEV_CMD_MEMORY_WRITE} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ISY/IoX select entities from config entry.""" isy_data: IsyData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/isy994/sensor.py b/homeassistant/components/isy994/sensor.py index 58ba3171bc8..2655f4d3c4e 100644 --- a/homeassistant/components/isy994/sensor.py +++ b/homeassistant/components/isy994/sensor.py @@ -33,7 +33,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( _LOGGER, @@ -108,7 +108,9 @@ ISY_CONTROL_TO_ENTITY_CATEGORY = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY sensor platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/isy994/switch.py b/homeassistant/components/isy994/switch.py index c05bd2ddbbb..946feddcd10 100644 --- a/homeassistant/components/isy994/switch.py +++ b/homeassistant/components/isy994/switch.py @@ -25,7 +25,7 @@ from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import ISYAuxControlEntity, ISYNodeEntity, ISYProgramEntity @@ -42,7 +42,9 @@ class ISYSwitchEntityDescription(SwitchEntityDescription): async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ISY switch platform.""" isy_data: IsyData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/ituran/device_tracker.py b/homeassistant/components/ituran/device_tracker.py index 37796570c61..5f816709864 100644 --- a/homeassistant/components/ituran/device_tracker.py +++ b/homeassistant/components/ituran/device_tracker.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.device_tracker import TrackerEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import IturanConfigEntry from .coordinator import IturanDataUpdateCoordinator @@ -14,7 +14,7 @@ from .entity import IturanBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: IturanConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ituran tracker from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/ituran/sensor.py b/homeassistant/components/ituran/sensor.py index e962f5bd561..a115b2be89c 100644 --- a/homeassistant/components/ituran/sensor.py +++ b/homeassistant/components/ituran/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfSpeed, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import IturanConfigEntry @@ -87,7 +87,7 @@ SENSOR_TYPES: list[IturanSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: IturanConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ituran sensors from config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/izone/climate.py b/homeassistant/components/izone/climate.py index e61917c825b..80c3a0384c1 100644 --- a/homeassistant/components/izone/climate.py +++ b/homeassistant/components/izone/climate.py @@ -33,7 +33,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_platform from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.temperature import display_temp as show_temp from homeassistant.helpers.typing import ConfigType, VolDictType @@ -73,7 +73,9 @@ IZONE_SERVICE_AIRFLOW_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize an IZone Controller.""" disco = hass.data[DATA_DISCOVERY_SERVICE] diff --git a/homeassistant/components/jellyfin/__init__.py b/homeassistant/components/jellyfin/__init__.py index 4f0886dfa22..1cb6219ada0 100644 --- a/homeassistant/components/jellyfin/__init__.py +++ b/homeassistant/components/jellyfin/__init__.py @@ -2,16 +2,13 @@ from typing import Any -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from .client_wrapper import CannotConnect, InvalidAuth, create_client, validate_input from .const import CONF_CLIENT_DEVICE_ID, DOMAIN, PLATFORMS -from .coordinator import JellyfinDataUpdateCoordinator - -type JellyfinConfigEntry = ConfigEntry[JellyfinDataUpdateCoordinator] +from .coordinator import JellyfinConfigEntry, JellyfinDataUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: JellyfinConfigEntry) -> bool: @@ -35,7 +32,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: JellyfinConfigEntry) -> server_info: dict[str, Any] = connect_result["Servers"][0] - coordinator = JellyfinDataUpdateCoordinator(hass, client, server_info, user_id) + coordinator = JellyfinDataUpdateCoordinator( + hass, entry, client, server_info, user_id + ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/jellyfin/config_flow.py b/homeassistant/components/jellyfin/config_flow.py index 0c170d2485f..03c637a989f 100644 --- a/homeassistant/components/jellyfin/config_flow.py +++ b/homeassistant/components/jellyfin/config_flow.py @@ -13,9 +13,9 @@ from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME from homeassistant.core import callback from homeassistant.util.uuid import random_uuid_hex -from . import JellyfinConfigEntry from .client_wrapper import CannotConnect, InvalidAuth, create_client, validate_input from .const import CONF_CLIENT_DEVICE_ID, DOMAIN, SUPPORTED_AUDIO_CODECS +from .coordinator import JellyfinConfigEntry _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/jellyfin/coordinator.py b/homeassistant/components/jellyfin/coordinator.py index 20428250254..cd22ad4ab39 100644 --- a/homeassistant/components/jellyfin/coordinator.py +++ b/homeassistant/components/jellyfin/coordinator.py @@ -13,15 +13,18 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import CONF_CLIENT_DEVICE_ID, DOMAIN, LOGGER, USER_APP_NAME +type JellyfinConfigEntry = ConfigEntry[JellyfinDataUpdateCoordinator] + class JellyfinDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]): """Data update coordinator for the Jellyfin integration.""" - config_entry: ConfigEntry + config_entry: JellyfinConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: JellyfinConfigEntry, api_client: JellyfinClient, system_info: dict[str, Any], user_id: str, @@ -30,6 +33,7 @@ class JellyfinDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict[str, An super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=10), ) @@ -37,7 +41,7 @@ class JellyfinDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict[str, An self.server_id: str = system_info["Id"] self.server_name: str = system_info["Name"] self.server_version: str | None = system_info.get("Version") - self.client_device_id: str = self.config_entry.data[CONF_CLIENT_DEVICE_ID] + self.client_device_id: str = config_entry.data[CONF_CLIENT_DEVICE_ID] self.user_id: str = user_id self.session_ids: set[str] = set() diff --git a/homeassistant/components/jellyfin/diagnostics.py b/homeassistant/components/jellyfin/diagnostics.py index 8042d588d1b..721e0ae654e 100644 --- a/homeassistant/components/jellyfin/diagnostics.py +++ b/homeassistant/components/jellyfin/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_PASSWORD from homeassistant.core import HomeAssistant -from . import JellyfinConfigEntry +from .coordinator import JellyfinConfigEntry TO_REDACT = {CONF_PASSWORD} diff --git a/homeassistant/components/jellyfin/media_player.py b/homeassistant/components/jellyfin/media_player.py index bf6e95c0c96..a8744b3e725 100644 --- a/homeassistant/components/jellyfin/media_player.py +++ b/homeassistant/components/jellyfin/media_player.py @@ -12,21 +12,20 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import parse_datetime -from . import JellyfinConfigEntry from .browse_media import build_item_response, build_root_response from .client_wrapper import get_artwork_url from .const import CONTENT_TYPE_MAP, LOGGER -from .coordinator import JellyfinDataUpdateCoordinator +from .coordinator import JellyfinConfigEntry, JellyfinDataUpdateCoordinator from .entity import JellyfinClientEntity async def async_setup_entry( hass: HomeAssistant, entry: JellyfinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Jellyfin media_player from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jellyfin/media_source.py b/homeassistant/components/jellyfin/media_source.py index a061118dd0a..a4d08d8d024 100644 --- a/homeassistant/components/jellyfin/media_source.py +++ b/homeassistant/components/jellyfin/media_source.py @@ -19,7 +19,6 @@ from homeassistant.components.media_source import ( ) from homeassistant.core import HomeAssistant -from . import JellyfinConfigEntry from .const import ( COLLECTION_TYPE_MOVIES, COLLECTION_TYPE_MUSIC, @@ -48,6 +47,7 @@ from .const import ( PLAYABLE_ITEM_TYPES, SUPPORTED_COLLECTION_TYPES, ) +from .coordinator import JellyfinConfigEntry _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/jellyfin/remote.py b/homeassistant/components/jellyfin/remote.py index ae33d58cc0c..27a0b131ca0 100644 --- a/homeassistant/components/jellyfin/remote.py +++ b/homeassistant/components/jellyfin/remote.py @@ -14,18 +14,17 @@ from homeassistant.components.remote import ( RemoteEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import JellyfinConfigEntry from .const import LOGGER -from .coordinator import JellyfinDataUpdateCoordinator +from .coordinator import JellyfinConfigEntry, JellyfinDataUpdateCoordinator from .entity import JellyfinClientEntity async def async_setup_entry( hass: HomeAssistant, entry: JellyfinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Jellyfin remote from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jellyfin/sensor.py b/homeassistant/components/jellyfin/sensor.py index 5c519f661ee..e1100a9f43b 100644 --- a/homeassistant/components/jellyfin/sensor.py +++ b/homeassistant/components/jellyfin/sensor.py @@ -8,10 +8,10 @@ from typing import Any from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import JellyfinConfigEntry, JellyfinDataUpdateCoordinator +from .coordinator import JellyfinConfigEntry, JellyfinDataUpdateCoordinator from .entity import JellyfinServerEntity @@ -43,7 +43,7 @@ SENSOR_TYPES: tuple[JellyfinSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: JellyfinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Jellyfin sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jewish_calendar/binary_sensor.py b/homeassistant/components/jewish_calendar/binary_sensor.py index 85519bf37b0..5ff3171b7de 100644 --- a/homeassistant/components/jewish_calendar/binary_sensor.py +++ b/homeassistant/components/jewish_calendar/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers import event -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .entity import JewishCalendarConfigEntry, JewishCalendarEntity @@ -62,7 +62,7 @@ BINARY_SENSORS: tuple[JewishCalendarBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: JewishCalendarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Jewish Calendar binary sensors.""" async_add_entities( diff --git a/homeassistant/components/jewish_calendar/sensor.py b/homeassistant/components/jewish_calendar/sensor.py index 5e02435ed06..eee1d966ae6 100644 --- a/homeassistant/components/jewish_calendar/sensor.py +++ b/homeassistant/components/jewish_calendar/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import SUN_EVENT_SUNSET, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sun import get_astral_event_date from homeassistant.util import dt as dt_util @@ -168,7 +168,7 @@ TIME_SENSORS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: JewishCalendarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Jewish calendar sensors .""" sensors = [ diff --git a/homeassistant/components/juicenet/number.py b/homeassistant/components/juicenet/number.py index 383d0d590c4..69323884f61 100644 --- a/homeassistant/components/juicenet/number.py +++ b/homeassistant/components/juicenet/number.py @@ -13,7 +13,7 @@ from homeassistant.components.number import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, JUICENET_API, JUICENET_COORDINATOR @@ -43,7 +43,7 @@ NUMBER_TYPES: tuple[JuiceNetNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JuiceNet Numbers.""" juicenet_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/juicenet/sensor.py b/homeassistant/components/juicenet/sensor.py index 1f0b815cd97..7bf0639f5d0 100644 --- a/homeassistant/components/juicenet/sensor.py +++ b/homeassistant/components/juicenet/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, JUICENET_API, JUICENET_COORDINATOR from .entity import JuiceNetDevice @@ -70,7 +70,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JuiceNet Sensors.""" juicenet_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/juicenet/switch.py b/homeassistant/components/juicenet/switch.py index d800ac58c2c..9f34b7afdb3 100644 --- a/homeassistant/components/juicenet/switch.py +++ b/homeassistant/components/juicenet/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, JUICENET_API, JUICENET_COORDINATOR from .entity import JuiceNetDevice @@ -14,7 +14,7 @@ from .entity import JuiceNetDevice async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JuiceNet switches.""" juicenet_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/justnimbus/__init__.py b/homeassistant/components/justnimbus/__init__.py index 101a2086962..123807d887c 100644 --- a/homeassistant/components/justnimbus/__init__.py +++ b/homeassistant/components/justnimbus/__init__.py @@ -13,7 +13,7 @@ from .coordinator import JustNimbusCoordinator async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up JustNimbus from a config entry.""" if "zip_code" in entry.data: - coordinator = JustNimbusCoordinator(hass=hass, entry=entry) + coordinator = JustNimbusCoordinator(hass, entry) else: raise ConfigEntryAuthFailed await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/justnimbus/coordinator.py b/homeassistant/components/justnimbus/coordinator.py index 4031ad86fdf..a6945c45417 100644 --- a/homeassistant/components/justnimbus/coordinator.py +++ b/homeassistant/components/justnimbus/coordinator.py @@ -20,16 +20,20 @@ _LOGGER = logging.getLogger(__name__) class JustNimbusCoordinator(DataUpdateCoordinator[justnimbus.JustNimbusModel]): """Data update coordinator.""" - def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: + config_entry: ConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize the coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(minutes=1), ) self._client = justnimbus.JustNimbusClient( - client_id=entry.data[CONF_CLIENT_ID], zip_code=entry.data[CONF_ZIP_CODE] + client_id=config_entry.data[CONF_CLIENT_ID], + zip_code=config_entry.data[CONF_ZIP_CODE], ) async def _async_update_data(self) -> justnimbus.JustNimbusModel: diff --git a/homeassistant/components/justnimbus/sensor.py b/homeassistant/components/justnimbus/sensor.py index c2c22307371..1e288e272cd 100644 --- a/homeassistant/components/justnimbus/sensor.py +++ b/homeassistant/components/justnimbus/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import JustNimbusCoordinator @@ -101,7 +101,9 @@ SENSOR_TYPES = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JustNimbus sensor.""" coordinator: JustNimbusCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/jvc_projector/__init__.py b/homeassistant/components/jvc_projector/__init__.py index 09e93127e40..ad7e333ca13 100644 --- a/homeassistant/components/jvc_projector/__init__.py +++ b/homeassistant/components/jvc_projector/__init__.py @@ -4,7 +4,6 @@ from __future__ import annotations from jvcprojector import JvcProjector, JvcProjectorAuthError, JvcProjectorConnectError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, @@ -15,9 +14,7 @@ from homeassistant.const import ( from homeassistant.core import Event, HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady -from .coordinator import JvcProjectorDataUpdateCoordinator - -type JVCConfigEntry = ConfigEntry[JvcProjectorDataUpdateCoordinator] +from .coordinator import JVCConfigEntry, JvcProjectorDataUpdateCoordinator PLATFORMS = [Platform.BINARY_SENSOR, Platform.REMOTE, Platform.SELECT, Platform.SENSOR] @@ -41,7 +38,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: JVCConfigEntry) -> bool: await device.disconnect() raise ConfigEntryAuthFailed("Password authentication failed") from err - coordinator = JvcProjectorDataUpdateCoordinator(hass, device) + coordinator = JvcProjectorDataUpdateCoordinator(hass, entry, device) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/jvc_projector/binary_sensor.py b/homeassistant/components/jvc_projector/binary_sensor.py index 6dfac63892b..7ae76298839 100644 --- a/homeassistant/components/jvc_projector/binary_sensor.py +++ b/homeassistant/components/jvc_projector/binary_sensor.py @@ -6,16 +6,18 @@ from jvcprojector import const from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import JVCConfigEntry, JvcProjectorDataUpdateCoordinator +from .coordinator import JVCConfigEntry, JvcProjectorDataUpdateCoordinator from .entity import JvcProjectorEntity ON_STATUS = (const.ON, const.WARMING) async def async_setup_entry( - hass: HomeAssistant, entry: JVCConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: JVCConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JVC Projector platform from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jvc_projector/coordinator.py b/homeassistant/components/jvc_projector/coordinator.py index a2ecfa8eb52..db97b05f980 100644 --- a/homeassistant/components/jvc_projector/coordinator.py +++ b/homeassistant/components/jvc_projector/coordinator.py @@ -13,6 +13,7 @@ from jvcprojector import ( const, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.device_registry import format_mac @@ -25,15 +26,22 @@ _LOGGER = logging.getLogger(__name__) INTERVAL_SLOW = timedelta(seconds=10) INTERVAL_FAST = timedelta(seconds=5) +type JVCConfigEntry = ConfigEntry[JvcProjectorDataUpdateCoordinator] + class JvcProjectorDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str]]): """Data update coordinator for the JVC Projector integration.""" - def __init__(self, hass: HomeAssistant, device: JvcProjector) -> None: + config_entry: JVCConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: JVCConfigEntry, device: JvcProjector + ) -> None: """Initialize the coordinator.""" super().__init__( hass=hass, logger=_LOGGER, + config_entry=config_entry, name=NAME, update_interval=INTERVAL_SLOW, ) diff --git a/homeassistant/components/jvc_projector/remote.py b/homeassistant/components/jvc_projector/remote.py index f90a2816363..e1aff2fbb4c 100644 --- a/homeassistant/components/jvc_projector/remote.py +++ b/homeassistant/components/jvc_projector/remote.py @@ -12,9 +12,9 @@ from jvcprojector import const from homeassistant.components.remote import RemoteEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import JVCConfigEntry +from .coordinator import JVCConfigEntry from .entity import JvcProjectorEntity COMMANDS = { @@ -54,7 +54,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: JVCConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: JVCConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JVC Projector platform from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jvc_projector/select.py b/homeassistant/components/jvc_projector/select.py index 60c80f98fc0..b83695609cb 100644 --- a/homeassistant/components/jvc_projector/select.py +++ b/homeassistant/components/jvc_projector/select.py @@ -10,9 +10,9 @@ from jvcprojector import JvcProjector, const from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import JVCConfigEntry, JvcProjectorDataUpdateCoordinator +from .coordinator import JVCConfigEntry, JvcProjectorDataUpdateCoordinator from .entity import JvcProjectorEntity @@ -40,7 +40,7 @@ SELECTS: Final[list[JvcProjectorSelectDescription]] = [ async def async_setup_entry( hass: HomeAssistant, entry: JVCConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JVC Projector platform from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/jvc_projector/sensor.py b/homeassistant/components/jvc_projector/sensor.py index 3edf51e4316..7a7799bc4ee 100644 --- a/homeassistant/components/jvc_projector/sensor.py +++ b/homeassistant/components/jvc_projector/sensor.py @@ -11,9 +11,9 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import JVCConfigEntry, JvcProjectorDataUpdateCoordinator +from .coordinator import JVCConfigEntry, JvcProjectorDataUpdateCoordinator from .entity import JvcProjectorEntity JVC_SENSORS = ( @@ -34,7 +34,9 @@ JVC_SENSORS = ( async def async_setup_entry( - hass: HomeAssistant, entry: JVCConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: JVCConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the JVC Projector platform from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/kaleidescape/media_player.py b/homeassistant/components/kaleidescape/media_player.py index 33acb899728..88e2e16bef2 100644 --- a/homeassistant/components/kaleidescape/media_player.py +++ b/homeassistant/components/kaleidescape/media_player.py @@ -22,7 +22,7 @@ if TYPE_CHECKING: from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant - from homeassistant.helpers.entity_platform import AddEntitiesCallback + from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback KALEIDESCAPE_PLAYING_STATES = [ @@ -38,7 +38,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from a config entry.""" entities = [KaleidescapeMediaPlayer(hass.data[KALEIDESCAPE_DOMAIN][entry.entry_id])] diff --git a/homeassistant/components/kaleidescape/remote.py b/homeassistant/components/kaleidescape/remote.py index 2d35ad2787f..ddafd52f220 100644 --- a/homeassistant/components/kaleidescape/remote.py +++ b/homeassistant/components/kaleidescape/remote.py @@ -18,11 +18,13 @@ if TYPE_CHECKING: from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant - from homeassistant.helpers.entity_platform import AddEntitiesCallback + from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from a config entry.""" entities = [KaleidescapeRemote(hass.data[KALEIDESCAPE_DOMAIN][entry.entry_id])] diff --git a/homeassistant/components/kaleidescape/sensor.py b/homeassistant/components/kaleidescape/sensor.py index 5520943e683..8bff5df2e70 100644 --- a/homeassistant/components/kaleidescape/sensor.py +++ b/homeassistant/components/kaleidescape/sensor.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant - from homeassistant.helpers.entity_platform import AddEntitiesCallback + from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType @@ -131,7 +131,9 @@ SENSOR_TYPES: tuple[KaleidescapeSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from a config entry.""" device: KaleidescapeDevice = hass.data[KALEIDESCAPE_DOMAIN][entry.entry_id] diff --git a/homeassistant/components/keenetic_ndms2/binary_sensor.py b/homeassistant/components/keenetic_ndms2/binary_sensor.py index cb7d83b9238..4d1b5da3552 100644 --- a/homeassistant/components/keenetic_ndms2/binary_sensor.py +++ b/homeassistant/components/keenetic_ndms2/binary_sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KeeneticRouter from .const import DOMAIN, ROUTER @@ -16,7 +16,7 @@ from .const import DOMAIN, ROUTER async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Keenetic NDMS2 component.""" router: KeeneticRouter = hass.data[DOMAIN][config_entry.entry_id][ROUTER] diff --git a/homeassistant/components/keenetic_ndms2/device_tracker.py b/homeassistant/components/keenetic_ndms2/device_tracker.py index 0f5166e16dd..4143611d6af 100644 --- a/homeassistant/components/keenetic_ndms2/device_tracker.py +++ b/homeassistant/components/keenetic_ndms2/device_tracker.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN, ROUTER @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Keenetic NDMS2 component.""" router: KeeneticRouter = hass.data[DOMAIN][config_entry.entry_id][ROUTER] diff --git a/homeassistant/components/kegtron/sensor.py b/homeassistant/components/kegtron/sensor.py index e0638fccea0..602c61f96ff 100644 --- a/homeassistant/components/kegtron/sensor.py +++ b/homeassistant/components/kegtron/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -110,7 +110,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Kegtron BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/keymitt_ble/switch.py b/homeassistant/components/keymitt_ble/switch.py index ca458c5020f..57d3af98062 100644 --- a/homeassistant/components/keymitt_ble/switch.py +++ b/homeassistant/components/keymitt_ble/switch.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.typing import VolDictType @@ -29,7 +29,9 @@ CALIBRATE_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MicroBot based on a config entry.""" coordinator: MicroBotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/kitchen_sink/__init__.py b/homeassistant/components/kitchen_sink/__init__.py index 09a72fc529c..eff1a1ba8b2 100644 --- a/homeassistant/components/kitchen_sink/__init__.py +++ b/homeassistant/components/kitchen_sink/__init__.py @@ -70,11 +70,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return True -async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set the config entry up.""" # Set up demo platforms with config entry await hass.config_entries.async_forward_entry_setups( - config_entry, COMPONENTS_WITH_DEMO_PLATFORM + entry, COMPONENTS_WITH_DEMO_PLATFORM ) # Create issues @@ -85,7 +85,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b await _insert_statistics(hass) # Start a reauth flow - config_entry.async_start_reauth(hass) + entry.async_start_reauth(hass) + + entry.async_on_unload(entry.add_update_listener(_async_update_listener)) # Notify backup listeners hass.async_create_task(_notify_backup_listeners(hass), eager_start=False) @@ -93,6 +95,11 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b return True +async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Handle update.""" + await hass.config_entries.async_reload(entry.entry_id) + + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload config entry.""" # Notify backup listeners diff --git a/homeassistant/components/kitchen_sink/button.py b/homeassistant/components/kitchen_sink/button.py index 5c62c4b32d1..1ee9bd78095 100644 --- a/homeassistant/components/kitchen_sink/button.py +++ b/homeassistant/components/kitchen_sink/button.py @@ -7,7 +7,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -15,7 +15,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo button platform.""" async_add_entities( diff --git a/homeassistant/components/kitchen_sink/config_flow.py b/homeassistant/components/kitchen_sink/config_flow.py index 019d1dddcad..e1ffe334038 100644 --- a/homeassistant/components/kitchen_sink/config_flow.py +++ b/homeassistant/components/kitchen_sink/config_flow.py @@ -12,7 +12,9 @@ from homeassistant.config_entries import ( ConfigEntry, ConfigFlow, ConfigFlowResult, + ConfigSubentryFlow, OptionsFlow, + SubentryFlowResult, ) from homeassistant.core import callback @@ -35,6 +37,14 @@ class KitchenSinkConfigFlow(ConfigFlow, domain=DOMAIN): """Get the options flow for this handler.""" return OptionsFlowHandler() + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[ConfigSubentryFlow]]: + """Return subentries supported by this handler.""" + return {"entity": SubentryFlowHandler} + async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult: """Set the config entry up from yaml.""" return self.async_create_entry(title="Kitchen Sink", data=import_data) @@ -94,3 +104,60 @@ class OptionsFlowHandler(OptionsFlow): } ), ) + + +class SubentryFlowHandler(ConfigSubentryFlow): + """Handle subentry flow.""" + + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> SubentryFlowResult: + """User flow to create a sensor subentry.""" + return await self.async_step_add_sensor() + + async def async_step_add_sensor( + self, user_input: dict[str, Any] | None = None + ) -> SubentryFlowResult: + """Add a new sensor.""" + if user_input is not None: + title = user_input.pop("name") + return self.async_create_entry(data=user_input, title=title) + + return self.async_show_form( + step_id="add_sensor", + data_schema=vol.Schema( + { + vol.Required("name"): str, + vol.Required("state"): int, + } + ), + ) + + async def async_step_reconfigure( + self, user_input: dict[str, Any] | None = None + ) -> SubentryFlowResult: + """Reconfigure a sensor subentry.""" + return await self.async_step_reconfigure_sensor() + + async def async_step_reconfigure_sensor( + self, user_input: dict[str, Any] | None = None + ) -> SubentryFlowResult: + """Reconfigure a sensor.""" + if user_input is not None: + title = user_input.pop("name") + return self.async_update_and_abort( + self._get_reconfigure_entry(), + self._get_reconfigure_subentry(), + data=user_input, + title=title, + ) + + return self.async_show_form( + step_id="reconfigure_sensor", + data_schema=vol.Schema( + { + vol.Required("name"): str, + vol.Required("state"): int, + } + ), + ) diff --git a/homeassistant/components/kitchen_sink/image.py b/homeassistant/components/kitchen_sink/image.py index 504b36464f5..130317f4bc5 100644 --- a/homeassistant/components/kitchen_sink/image.py +++ b/homeassistant/components/kitchen_sink/image.py @@ -7,7 +7,10 @@ from pathlib import Path from homeassistant.components.image import ImageEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -35,7 +38,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Everything but the Kitchen Sink config entry.""" await async_setup_platform(hass, {}, async_add_entities) diff --git a/homeassistant/components/kitchen_sink/lawn_mower.py b/homeassistant/components/kitchen_sink/lawn_mower.py index 51814fb262d..18a3f3dee77 100644 --- a/homeassistant/components/kitchen_sink/lawn_mower.py +++ b/homeassistant/components/kitchen_sink/lawn_mower.py @@ -9,7 +9,10 @@ from homeassistant.components.lawn_mower import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -71,7 +74,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Everything but the Kitchen Sink config entry.""" await async_setup_platform(hass, {}, async_add_entities) diff --git a/homeassistant/components/kitchen_sink/lock.py b/homeassistant/components/kitchen_sink/lock.py index 80ecc57d0d9..63566482cdf 100644 --- a/homeassistant/components/kitchen_sink/lock.py +++ b/homeassistant/components/kitchen_sink/lock.py @@ -7,7 +7,10 @@ from typing import Any from homeassistant.components.lock import LockEntity, LockEntityFeature, LockState from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -49,7 +52,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Everything but the Kitchen Sink config entry.""" await async_setup_platform(hass, {}, async_add_entities) diff --git a/homeassistant/components/kitchen_sink/notify.py b/homeassistant/components/kitchen_sink/notify.py index fb34a36f0b7..be5bad58109 100644 --- a/homeassistant/components/kitchen_sink/notify.py +++ b/homeassistant/components/kitchen_sink/notify.py @@ -7,7 +7,7 @@ from homeassistant.components.notify import NotifyEntity, NotifyEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -15,7 +15,7 @@ from . import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo notify entity platform.""" async_add_entities( diff --git a/homeassistant/components/kitchen_sink/sensor.py b/homeassistant/components/kitchen_sink/sensor.py index 95e56c276e4..19d1b31aeab 100644 --- a/homeassistant/components/kitchen_sink/sensor.py +++ b/homeassistant/components/kitchen_sink/sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED, StateType, UndefinedType from . import DOMAIN @@ -21,7 +21,7 @@ from .device import async_create_device async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Everything but the Kitchen Sink config entry.""" async_create_device( @@ -90,6 +90,23 @@ async def async_setup_entry( ] ) + for subentry_id, subentry in config_entry.subentries.items(): + async_add_entities( + [ + DemoSensor( + device_unique_id=subentry_id, + unique_id=subentry_id, + device_name=subentry.title, + entity_name=None, + state=subentry.data["state"], + device_class=None, + state_class=None, + unit_of_measurement=None, + ) + ], + config_subentry_id=subentry_id, + ) + class DemoSensor(SensorEntity): """Representation of a Demo sensor.""" diff --git a/homeassistant/components/kitchen_sink/strings.json b/homeassistant/components/kitchen_sink/strings.json index c03f909e617..e2fbb99c89f 100644 --- a/homeassistant/components/kitchen_sink/strings.json +++ b/homeassistant/components/kitchen_sink/strings.json @@ -9,6 +9,27 @@ } } }, + "config_subentries": { + "entity": { + "title": "Add entity", + "step": { + "add_sensor": { + "description": "Configure the new sensor", + "data": { + "name": "[%key:common::config_flow::data::name%]", + "state": "Initial state" + } + }, + "reconfigure_sensor": { + "description": "Reconfigure the sensor", + "data": { + "name": "[%key:component::kitchen_sink::config_subentries::entity::step::reconfigure_sensor::data::state%]", + "state": "Initial state" + } + } + } + } + }, "options": { "step": { "init": { diff --git a/homeassistant/components/kitchen_sink/switch.py b/homeassistant/components/kitchen_sink/switch.py index 68a8312b496..45d3cb14eca 100644 --- a/homeassistant/components/kitchen_sink/switch.py +++ b/homeassistant/components/kitchen_sink/switch.py @@ -8,7 +8,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .device import async_create_device @@ -17,7 +17,7 @@ from .device import async_create_device async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the demo switch platform.""" async_create_device( diff --git a/homeassistant/components/kitchen_sink/weather.py b/homeassistant/components/kitchen_sink/weather.py index e94e823c692..a6b7cc69d05 100644 --- a/homeassistant/components/kitchen_sink/weather.py +++ b/homeassistant/components/kitchen_sink/weather.py @@ -26,7 +26,7 @@ from homeassistant.components.weather import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPressure, UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from homeassistant.util import dt as dt_util @@ -56,7 +56,7 @@ CONDITION_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Demo config entry.""" async_add_entities( diff --git a/homeassistant/components/kmtronic/switch.py b/homeassistant/components/kmtronic/switch.py index f00ecf8623c..b32f78b0e98 100644 --- a/homeassistant/components/kmtronic/switch.py +++ b/homeassistant/components/kmtronic/switch.py @@ -7,14 +7,16 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_REVERSE, DATA_COORDINATOR, DATA_HUB, DOMAIN, MANUFACTURER async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Config entry example.""" coordinator = hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR] diff --git a/homeassistant/components/knocki/__init__.py b/homeassistant/components/knocki/__init__.py index dfdf060e3b5..966f1dbf309 100644 --- a/homeassistant/components/knocki/__init__.py +++ b/homeassistant/components/knocki/__init__.py @@ -4,17 +4,14 @@ from __future__ import annotations from knocki import Event, EventType, KnockiClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TOKEN, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .coordinator import KnockiCoordinator +from .coordinator import KnockiConfigEntry, KnockiCoordinator PLATFORMS: list[Platform] = [Platform.EVENT] -type KnockiConfigEntry = ConfigEntry[KnockiCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: KnockiConfigEntry) -> bool: """Set up Knocki from a config entry.""" @@ -22,7 +19,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: KnockiConfigEntry) -> bo session=async_get_clientsession(hass), token=entry.data[CONF_TOKEN] ) - coordinator = KnockiCoordinator(hass, client) + coordinator = KnockiCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/knocki/coordinator.py b/homeassistant/components/knocki/coordinator.py index c1e32b817e1..f5cc373f5c1 100644 --- a/homeassistant/components/knocki/coordinator.py +++ b/homeassistant/components/knocki/coordinator.py @@ -3,21 +3,29 @@ from knocki import Event, KnockiClient, KnockiConnectionError, Trigger from homeassistant.components.event import DOMAIN as EVENT_DOMAIN +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, LOGGER +type KnockiConfigEntry = ConfigEntry[KnockiCoordinator] + class KnockiCoordinator(DataUpdateCoordinator[dict[int, Trigger]]): """The Knocki coordinator.""" - def __init__(self, hass: HomeAssistant, client: KnockiClient) -> None: + config_entry: KnockiConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: KnockiConfigEntry, client: KnockiClient + ) -> None: """Initialize the coordinator.""" super().__init__( hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, ) self.client = client diff --git a/homeassistant/components/knocki/event.py b/homeassistant/components/knocki/event.py index 74dc5a0f64c..1b148f03f1c 100644 --- a/homeassistant/components/knocki/event.py +++ b/homeassistant/components/knocki/event.py @@ -5,7 +5,7 @@ from knocki import Event, EventType, KnockiClient, Trigger from homeassistant.components.event import EventEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import KnockiConfigEntry from .const import DOMAIN @@ -14,7 +14,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: KnockiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Knocki from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/knx/binary_sensor.py b/homeassistant/components/knx/binary_sensor.py index c629860351c..c11612f79bf 100644 --- a/homeassistant/components/knx/binary_sensor.py +++ b/homeassistant/components/knx/binary_sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.restore_state import RestoreEntity @@ -45,7 +45,7 @@ from .storage.const import CONF_ENTITY, CONF_GA_PASSIVE, CONF_GA_SENSOR, CONF_GA async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the KNX binary sensor platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/button.py b/homeassistant/components/knx/button.py index 5a2add5dcd7..538299a0556 100644 --- a/homeassistant/components/knx/button.py +++ b/homeassistant/components/knx/button.py @@ -8,7 +8,7 @@ from homeassistant import config_entries from homeassistant.components.button import ButtonEntity from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, CONF_PAYLOAD, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -19,7 +19,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the KNX binary sensor platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/climate.py b/homeassistant/components/knx/climate.py index e3bb63581e7..fdce5e0c470 100644 --- a/homeassistant/components/knx/climate.py +++ b/homeassistant/components/knx/climate.py @@ -34,7 +34,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -49,7 +49,7 @@ CONTROLLER_MODES_INV = {value: key for key, value in CONTROLLER_MODES.items()} async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/cover.py b/homeassistant/components/knx/cover.py index 2d38426a687..3c5752b990c 100644 --- a/homeassistant/components/knx/cover.py +++ b/homeassistant/components/knx/cover.py @@ -22,7 +22,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -34,7 +34,7 @@ from .schema import CoverSchema async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cover(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/date.py b/homeassistant/components/knx/date.py index 8f65ac8a952..7980e6a2bc3 100644 --- a/homeassistant/components/knx/date.py +++ b/homeassistant/components/knx/date.py @@ -18,7 +18,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType @@ -36,7 +36,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/datetime.py b/homeassistant/components/knx/datetime.py index b75e1a14f67..7701597a8ef 100644 --- a/homeassistant/components/knx/datetime.py +++ b/homeassistant/components/knx/datetime.py @@ -18,7 +18,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util @@ -37,7 +37,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/fan.py b/homeassistant/components/knx/fan.py index 75d91e48048..926b6458706 100644 --- a/homeassistant/components/knx/fan.py +++ b/homeassistant/components/knx/fan.py @@ -11,7 +11,7 @@ from homeassistant import config_entries from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from homeassistant.util.percentage import ( percentage_to_ranged_value, @@ -30,7 +30,7 @@ DEFAULT_PERCENTAGE: Final = 50 async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up fan(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/light.py b/homeassistant/components/knx/light.py index 33edc19fb1c..865cfdc6e25 100644 --- a/homeassistant/components/knx/light.py +++ b/homeassistant/components/knx/light.py @@ -22,7 +22,7 @@ from homeassistant.components.light import ( from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.typing import ConfigType @@ -61,7 +61,7 @@ from .storage.entity_store_schema import LightColorMode async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up light(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/notify.py b/homeassistant/components/knx/notify.py index 245de2e937e..97980ab3d36 100644 --- a/homeassistant/components/knx/notify.py +++ b/homeassistant/components/knx/notify.py @@ -9,7 +9,7 @@ from homeassistant import config_entries from homeassistant.components.notify import NotifyEntity from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, CONF_TYPE, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -20,7 +20,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up notify(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/number.py b/homeassistant/components/knx/number.py index 27e4ff743ab..67e8778accc 100644 --- a/homeassistant/components/knx/number.py +++ b/homeassistant/components/knx/number.py @@ -19,7 +19,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -31,7 +31,7 @@ from .schema import NumberSchema async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/scene.py b/homeassistant/components/knx/scene.py index dfd226d72b1..f5361a6e7da 100644 --- a/homeassistant/components/knx/scene.py +++ b/homeassistant/components/knx/scene.py @@ -10,7 +10,7 @@ from homeassistant import config_entries from homeassistant.components.scene import Scene from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -22,7 +22,7 @@ from .schema import SceneSchema async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up scene(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/select.py b/homeassistant/components/knx/select.py index b499e3c601d..e80fa66f9d4 100644 --- a/homeassistant/components/knx/select.py +++ b/homeassistant/components/knx/select.py @@ -16,7 +16,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType @@ -36,7 +36,7 @@ from .schema import SelectSchema async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/sensor.py b/homeassistant/components/knx/sensor.py index fa4911aa4b7..8e537ea234e 100644 --- a/homeassistant/components/knx/sensor.py +++ b/homeassistant/components/knx/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, StateType from homeassistant.util.enum import try_parse_enum @@ -112,7 +112,7 @@ SYSTEM_ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/strings.json b/homeassistant/components/knx/strings.json index dadc8e84796..10730d87ed1 100644 --- a/homeassistant/components/knx/strings.json +++ b/homeassistant/components/knx/strings.json @@ -397,7 +397,7 @@ }, "response": { "name": "Send as Response", - "description": "If set to `True`, the telegram will be sent as a `GroupValueResponse` instead of a `GroupValueWrite`." + "description": "Whether the telegram should be sent as a `GroupValueResponse` instead of a `GroupValueWrite`." } } }, @@ -425,7 +425,7 @@ }, "remove": { "name": "Remove event registration", - "description": "If `True` the group address(es) will be removed." + "description": "Whether the group address(es) will be removed." } } }, @@ -455,7 +455,7 @@ }, "remove": { "name": "Remove exposure", - "description": "If `True` the exposure will be removed. Only `address` is required for removal." + "description": "Whether the exposure should be removed. Only the 'Address' field is required for removal." } } }, diff --git a/homeassistant/components/knx/switch.py b/homeassistant/components/knx/switch.py index 725468cd6a9..730c5b788ff 100644 --- a/homeassistant/components/knx/switch.py +++ b/homeassistant/components/knx/switch.py @@ -19,7 +19,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.restore_state import RestoreEntity @@ -48,7 +48,7 @@ from .storage.const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch(es) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/text.py b/homeassistant/components/knx/text.py index 2256afadbd9..9c2bb88f92b 100644 --- a/homeassistant/components/knx/text.py +++ b/homeassistant/components/knx/text.py @@ -18,7 +18,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType @@ -30,7 +30,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor(s) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/time.py b/homeassistant/components/knx/time.py index 1e82c324502..2c74ab18af3 100644 --- a/homeassistant/components/knx/time.py +++ b/homeassistant/components/knx/time.py @@ -18,7 +18,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType @@ -36,7 +36,7 @@ from .entity import KnxYamlEntity async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/knx/weather.py b/homeassistant/components/knx/weather.py index a1e5c0efe48..342ab445611 100644 --- a/homeassistant/components/knx/weather.py +++ b/homeassistant/components/knx/weather.py @@ -16,7 +16,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import KNXModule @@ -28,7 +28,7 @@ from .schema import WeatherSchema async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch(es) for KNX platform.""" knx_module = hass.data[KNX_MODULE_KEY] diff --git a/homeassistant/components/kodi/media_player.py b/homeassistant/components/kodi/media_player.py index bbddbd9f348..c4a2436548a 100644 --- a/homeassistant/components/kodi/media_player.py +++ b/homeassistant/components/kodi/media_player.py @@ -46,7 +46,10 @@ from homeassistant.helpers import ( entity_platform, ) from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.network import is_internal_request from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, VolDictType @@ -206,7 +209,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Kodi media player platform.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/konnected/binary_sensor.py b/homeassistant/components/konnected/binary_sensor.py index 75c381c53f2..3f1a27302d8 100644 --- a/homeassistant/components/konnected/binary_sensor.py +++ b/homeassistant/components/konnected/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as KONNECTED_DOMAIN @@ -21,7 +21,7 @@ from .const import DOMAIN as KONNECTED_DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors attached to a Konnected device from a config entry.""" data = hass.data[KONNECTED_DOMAIN] diff --git a/homeassistant/components/konnected/sensor.py b/homeassistant/components/konnected/sensor.py index 6191f98f179..cd36c217627 100644 --- a/homeassistant/components/konnected/sensor.py +++ b/homeassistant/components/konnected/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as KONNECTED_DOMAIN, SIGNAL_DS18B20_NEW @@ -43,7 +43,7 @@ SENSOR_TYPES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors attached to a Konnected device from a config entry.""" data = hass.data[KONNECTED_DOMAIN] diff --git a/homeassistant/components/konnected/switch.py b/homeassistant/components/konnected/switch.py index 65b99d623f1..58311502cbe 100644 --- a/homeassistant/components/konnected/switch.py +++ b/homeassistant/components/konnected/switch.py @@ -16,7 +16,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_ACTIVATION, @@ -33,7 +33,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches attached to a Konnected device from a config entry.""" data = hass.data[KONNECTED_DOMAIN] diff --git a/homeassistant/components/kostal_plenticore/coordinator.py b/homeassistant/components/kostal_plenticore/coordinator.py index 5f4393146f0..a404a997663 100644 --- a/homeassistant/components/kostal_plenticore/coordinator.py +++ b/homeassistant/components/kostal_plenticore/coordinator.py @@ -16,6 +16,7 @@ from pykoplenti import ( ExtendedApiClient, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -162,9 +163,12 @@ class DataUpdateCoordinatorMixin: class PlenticoreUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Base implementation of DataUpdateCoordinator for Plenticore data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, logger: logging.Logger, name: str, update_inverval: timedelta, @@ -174,6 +178,7 @@ class PlenticoreUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): super().__init__( hass=hass, logger=logger, + config_entry=config_entry, name=name, update_interval=update_inverval, ) @@ -240,9 +245,12 @@ class SettingDataUpdateCoordinator( class PlenticoreSelectUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Base implementation of DataUpdateCoordinator for Plenticore data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, logger: logging.Logger, name: str, update_inverval: timedelta, @@ -252,6 +260,7 @@ class PlenticoreSelectUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): super().__init__( hass=hass, logger=logger, + config_entry=config_entry, name=name, update_interval=update_inverval, ) diff --git a/homeassistant/components/kostal_plenticore/number.py b/homeassistant/components/kostal_plenticore/number.py index 8afe69a7749..7efb00cf8f4 100644 --- a/homeassistant/components/kostal_plenticore/number.py +++ b/homeassistant/components/kostal_plenticore/number.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -73,7 +73,9 @@ NUMBER_SETTINGS_DATA = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Kostal Plenticore Number entities.""" plenticore = hass.data[DOMAIN][entry.entry_id] @@ -82,11 +84,7 @@ async def async_setup_entry( available_settings_data = await plenticore.client.get_settings() settings_data_update_coordinator = SettingDataUpdateCoordinator( - hass, - _LOGGER, - "Settings Data", - timedelta(seconds=30), - plenticore, + hass, entry, _LOGGER, "Settings Data", timedelta(seconds=30), plenticore ) for description in NUMBER_SETTINGS_DATA: diff --git a/homeassistant/components/kostal_plenticore/select.py b/homeassistant/components/kostal_plenticore/select.py index 73f3f94eda8..61929b9fadc 100644 --- a/homeassistant/components/kostal_plenticore/select.py +++ b/homeassistant/components/kostal_plenticore/select.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -42,18 +42,16 @@ SELECT_SETTINGS_DATA = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add kostal plenticore Select widget.""" plenticore: Plenticore = hass.data[DOMAIN][entry.entry_id] available_settings_data = await plenticore.client.get_settings() select_data_update_coordinator = SelectDataUpdateCoordinator( - hass, - _LOGGER, - "Settings Data", - timedelta(seconds=30), - plenticore, + hass, entry, _LOGGER, "Settings Data", timedelta(seconds=30), plenticore ) entities = [] diff --git a/homeassistant/components/kostal_plenticore/sensor.py b/homeassistant/components/kostal_plenticore/sensor.py index 67de34f2fce..1be7fb06e7b 100644 --- a/homeassistant/components/kostal_plenticore/sensor.py +++ b/homeassistant/components/kostal_plenticore/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -807,7 +807,9 @@ SENSOR_PROCESS_DATA = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add kostal plenticore Sensors.""" plenticore = hass.data[DOMAIN][entry.entry_id] @@ -816,11 +818,7 @@ async def async_setup_entry( available_process_data = await plenticore.client.get_process_data() process_data_update_coordinator = ProcessDataUpdateCoordinator( - hass, - _LOGGER, - "Process Data", - timedelta(seconds=10), - plenticore, + hass, entry, _LOGGER, "Process Data", timedelta(seconds=10), plenticore ) for description in SENSOR_PROCESS_DATA: module_id = description.module_id diff --git a/homeassistant/components/kostal_plenticore/switch.py b/homeassistant/components/kostal_plenticore/switch.py index 7ce2d468c88..e3d5f830c78 100644 --- a/homeassistant/components/kostal_plenticore/switch.py +++ b/homeassistant/components/kostal_plenticore/switch.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -48,7 +48,9 @@ SWITCH_SETTINGS_DATA = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add kostal plenticore Switch.""" plenticore = hass.data[DOMAIN][entry.entry_id] @@ -57,11 +59,7 @@ async def async_setup_entry( available_settings_data = await plenticore.client.get_settings() settings_data_update_coordinator = SettingDataUpdateCoordinator( - hass, - _LOGGER, - "Settings Data", - timedelta(seconds=30), - plenticore, + hass, entry, _LOGGER, "Settings Data", timedelta(seconds=30), plenticore ) for description in SWITCH_SETTINGS_DATA: if ( diff --git a/homeassistant/components/kraken/sensor.py b/homeassistant/components/kraken/sensor.py index 37fee795783..1d3f36d29e4 100644 --- a/homeassistant/components/kraken/sensor.py +++ b/homeassistant/components/kraken/sensor.py @@ -16,7 +16,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -139,7 +139,7 @@ SENSOR_TYPES: tuple[KrakenSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add kraken entities from a config_entry.""" diff --git a/homeassistant/components/kulersky/light.py b/homeassistant/components/kulersky/light.py index 552507ef50b..bcc3f32dceb 100644 --- a/homeassistant/components/kulersky/light.py +++ b/homeassistant/components/kulersky/light.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from .const import DATA_ADDRESSES, DATA_DISCOVERY_SUBSCRIPTION, DOMAIN @@ -31,7 +31,7 @@ DISCOVERY_INTERVAL = timedelta(seconds=60) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Kuler sky light devices.""" diff --git a/homeassistant/components/lacrosse_view/__init__.py b/homeassistant/components/lacrosse_view/__init__.py index d977af418a2..e98d1d421be 100644 --- a/homeassistant/components/lacrosse_view/__init__.py +++ b/homeassistant/components/lacrosse_view/__init__.py @@ -30,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except LoginError as error: raise ConfigEntryAuthFailed from error - coordinator = LaCrosseUpdateCoordinator(hass, api, entry) + coordinator = LaCrosseUpdateCoordinator(hass, entry, api) _LOGGER.debug("First refresh") await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/lacrosse_view/coordinator.py b/homeassistant/components/lacrosse_view/coordinator.py index 8d7e44ecd99..3d741e8f1a8 100644 --- a/homeassistant/components/lacrosse_view/coordinator.py +++ b/homeassistant/components/lacrosse_view/coordinator.py @@ -27,12 +27,13 @@ class LaCrosseUpdateCoordinator(DataUpdateCoordinator[list[Sensor]]): id: str hass: HomeAssistant devices: list[Sensor] | None = None + config_entry: ConfigEntry def __init__( self, hass: HomeAssistant, - api: LaCrosse, entry: ConfigEntry, + api: LaCrosse, ) -> None: """Initialize DataUpdateCoordinator for LaCrosse View.""" self.api = api @@ -45,6 +46,7 @@ class LaCrosseUpdateCoordinator(DataUpdateCoordinator[list[Sensor]]): super().__init__( hass, _LOGGER, + config_entry=entry, name="LaCrosse View", update_interval=timedelta(seconds=SCAN_INTERVAL), ) diff --git a/homeassistant/components/lacrosse_view/sensor.py b/homeassistant/components/lacrosse_view/sensor.py index 5c56a0328a2..df66b7ba96a 100644 --- a/homeassistant/components/lacrosse_view/sensor.py +++ b/homeassistant/components/lacrosse_view/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -149,7 +149,7 @@ UNIT_OF_MEASUREMENT_MAP = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaCrosse View from a config entry.""" coordinator: DataUpdateCoordinator[list[Sensor]] = hass.data[DOMAIN][ @@ -226,7 +226,6 @@ class LaCrosseViewSensor( name=sensor.name, manufacturer="LaCrosse Technology", model=sensor.model, - via_device=(DOMAIN, sensor.location.id), ) self.index = index diff --git a/homeassistant/components/lamarzocco/binary_sensor.py b/homeassistant/components/lamarzocco/binary_sensor.py index e36b53bc993..39bd5d4b954 100644 --- a/homeassistant/components/lamarzocco/binary_sensor.py +++ b/homeassistant/components/lamarzocco/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LaMarzoccoConfigEntry from .entity import LaMarzoccoEntity, LaMarzoccoEntityDescription, LaMarzoccScaleEntity @@ -71,7 +71,7 @@ SCALE_ENTITIES: tuple[LaMarzoccoBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor entities.""" coordinator = entry.runtime_data.config_coordinator diff --git a/homeassistant/components/lamarzocco/button.py b/homeassistant/components/lamarzocco/button.py index 22e92f656ff..db51d610949 100644 --- a/homeassistant/components/lamarzocco/button.py +++ b/homeassistant/components/lamarzocco/button.py @@ -10,7 +10,7 @@ from pylamarzocco.exceptions import RequestNotSuccessful from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator @@ -53,7 +53,7 @@ ENTITIES: tuple[LaMarzoccoButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button entities.""" diff --git a/homeassistant/components/lamarzocco/calendar.py b/homeassistant/components/lamarzocco/calendar.py index 1dcc7c324ac..4365bf56b2d 100644 --- a/homeassistant/components/lamarzocco/calendar.py +++ b/homeassistant/components/lamarzocco/calendar.py @@ -7,7 +7,7 @@ from pylamarzocco.models import LaMarzoccoWakeUpSleepEntry from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator @@ -32,7 +32,7 @@ DAY_OF_WEEK = [ async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch entities and services.""" diff --git a/homeassistant/components/lamarzocco/number.py b/homeassistant/components/lamarzocco/number.py index 44b582fbf1a..3b3d569a6f7 100644 --- a/homeassistant/components/lamarzocco/number.py +++ b/homeassistant/components/lamarzocco/number.py @@ -29,7 +29,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator @@ -230,7 +230,7 @@ SCALE_KEY_ENTITIES: tuple[LaMarzoccoKeyNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities.""" coordinator = entry.runtime_data.config_coordinator diff --git a/homeassistant/components/lamarzocco/select.py b/homeassistant/components/lamarzocco/select.py index 7acb654f0d2..bd6ac1ee04f 100644 --- a/homeassistant/components/lamarzocco/select.py +++ b/homeassistant/components/lamarzocco/select.py @@ -19,7 +19,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMarzoccoConfigEntry @@ -126,7 +126,7 @@ SCALE_ENTITIES: tuple[LaMarzoccoSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select entities.""" coordinator = entry.runtime_data.config_coordinator diff --git a/homeassistant/components/lamarzocco/sensor.py b/homeassistant/components/lamarzocco/sensor.py index a2d6143daa5..6287ea91a40 100644 --- a/homeassistant/components/lamarzocco/sensor.py +++ b/homeassistant/components/lamarzocco/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator from .entity import LaMarzoccoEntity, LaMarzoccoEntityDescription, LaMarzoccScaleEntity @@ -134,7 +134,7 @@ SCALE_ENTITIES: tuple[LaMarzoccoSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities.""" config_coordinator = entry.runtime_data.config_coordinator diff --git a/homeassistant/components/lamarzocco/switch.py b/homeassistant/components/lamarzocco/switch.py index 54bd1ac2aed..ee03ba421d4 100644 --- a/homeassistant/components/lamarzocco/switch.py +++ b/homeassistant/components/lamarzocco/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator @@ -64,7 +64,7 @@ ENTITIES: tuple[LaMarzoccoSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch entities and services.""" diff --git a/homeassistant/components/lamarzocco/update.py b/homeassistant/components/lamarzocco/update.py index 0833ee6e249..37960d26e95 100644 --- a/homeassistant/components/lamarzocco/update.py +++ b/homeassistant/components/lamarzocco/update.py @@ -15,7 +15,7 @@ from homeassistant.components.update import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMarzoccoConfigEntry @@ -55,7 +55,7 @@ ENTITIES: tuple[LaMarzoccoUpdateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LaMarzoccoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create update entities.""" diff --git a/homeassistant/components/lametric/button.py b/homeassistant/components/lametric/button.py index f0a452f2d02..3c7d754fa0b 100644 --- a/homeassistant/components/lametric/button.py +++ b/homeassistant/components/lametric/button.py @@ -12,7 +12,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMetricDataUpdateCoordinator @@ -58,7 +58,7 @@ BUTTONS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaMetric button based on a config entry.""" coordinator: LaMetricDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lametric/coordinator.py b/homeassistant/components/lametric/coordinator.py index 6655b035740..c292b2971b6 100644 --- a/homeassistant/components/lametric/coordinator.py +++ b/homeassistant/components/lametric/coordinator.py @@ -21,14 +21,15 @@ class LaMetricDataUpdateCoordinator(DataUpdateCoordinator[Device]): def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize the LaMatric coordinator.""" - self.config_entry = entry self.lametric = LaMetricDevice( host=entry.data[CONF_HOST], api_key=entry.data[CONF_API_KEY], session=async_get_clientsession(hass), ) - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, LOGGER, config_entry=entry, name=DOMAIN, update_interval=SCAN_INTERVAL + ) async def _async_update_data(self) -> Device: """Fetch device information of the LaMetric device.""" diff --git a/homeassistant/components/lametric/number.py b/homeassistant/components/lametric/number.py index ccfd48a3abf..7f356741d76 100644 --- a/homeassistant/components/lametric/number.py +++ b/homeassistant/components/lametric/number.py @@ -12,7 +12,7 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMetricDataUpdateCoordinator @@ -58,7 +58,7 @@ NUMBERS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaMetric number based on a config entry.""" coordinator: LaMetricDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lametric/select.py b/homeassistant/components/lametric/select.py index bf9872f2791..eab7cd5997c 100644 --- a/homeassistant/components/lametric/select.py +++ b/homeassistant/components/lametric/select.py @@ -12,7 +12,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMetricDataUpdateCoordinator @@ -43,7 +43,7 @@ SELECTS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaMetric select based on a config entry.""" coordinator: LaMetricDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lametric/sensor.py b/homeassistant/components/lametric/sensor.py index f202a77b530..a5d5da3c046 100644 --- a/homeassistant/components/lametric/sensor.py +++ b/homeassistant/components/lametric/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMetricDataUpdateCoordinator @@ -45,7 +45,7 @@ SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaMetric sensor based on a config entry.""" coordinator: LaMetricDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lametric/switch.py b/homeassistant/components/lametric/switch.py index 3aabfaf17e1..85e61164639 100644 --- a/homeassistant/components/lametric/switch.py +++ b/homeassistant/components/lametric/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LaMetricDataUpdateCoordinator @@ -48,7 +48,7 @@ SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LaMetric switch based on a config entry.""" coordinator: LaMetricDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/landisgyr_heat_meter/__init__.py b/homeassistant/components/landisgyr_heat_meter/__init__.py index 5cbdc593100..7e7ebe61eb7 100644 --- a/homeassistant/components/landisgyr_heat_meter/__init__.py +++ b/homeassistant/components/landisgyr_heat_meter/__init__.py @@ -27,7 +27,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: reader = ultraheat_api.UltraheatReader(entry.data[CONF_DEVICE]) api = ultraheat_api.HeatMeterService(reader) - coordinator = UltraheatCoordinator(hass, api) + coordinator = UltraheatCoordinator(hass, entry, api) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/landisgyr_heat_meter/coordinator.py b/homeassistant/components/landisgyr_heat_meter/coordinator.py index db265449f37..4214fa1db3e 100644 --- a/homeassistant/components/landisgyr_heat_meter/coordinator.py +++ b/homeassistant/components/landisgyr_heat_meter/coordinator.py @@ -7,6 +7,7 @@ import serial from ultraheat_api.response import HeatMeterResponse from ultraheat_api.service import HeatMeterService +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -18,11 +19,16 @@ _LOGGER = logging.getLogger(__name__) class UltraheatCoordinator(DataUpdateCoordinator[HeatMeterResponse]): """Coordinator for getting data from the ultraheat api.""" - def __init__(self, hass: HomeAssistant, api: HeatMeterService) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: HeatMeterService + ) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="ultraheat", update_interval=POLLING_INTERVAL, ) diff --git a/homeassistant/components/landisgyr_heat_meter/sensor.py b/homeassistant/components/landisgyr_heat_meter/sensor.py index dd76d3e53cc..9bb4af572fd 100644 --- a/homeassistant/components/landisgyr_heat_meter/sensor.py +++ b/homeassistant/components/landisgyr_heat_meter/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -269,7 +269,9 @@ HEAT_METER_SENSOR_TYPES = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" unique_id = entry.entry_id diff --git a/homeassistant/components/lastfm/__init__.py b/homeassistant/components/lastfm/__init__.py index ebcc929c39c..8611d06eee1 100644 --- a/homeassistant/components/lastfm/__init__.py +++ b/homeassistant/components/lastfm/__init__.py @@ -12,7 +12,7 @@ from .coordinator import LastFMDataUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up lastfm from a config entry.""" - coordinator = LastFMDataUpdateCoordinator(hass) + coordinator = LastFMDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/lastfm/coordinator.py b/homeassistant/components/lastfm/coordinator.py index 18473745450..ae89e103b80 100644 --- a/homeassistant/components/lastfm/coordinator.py +++ b/homeassistant/components/lastfm/coordinator.py @@ -39,15 +39,16 @@ class LastFMDataUpdateCoordinator(DataUpdateCoordinator[dict[str, LastFMUserData config_entry: ConfigEntry _client: LastFMNetwork - def __init__(self, hass: HomeAssistant) -> None: + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize the LastFM data coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) - self._client = LastFMNetwork(api_key=self.config_entry.options[CONF_API_KEY]) + self._client = LastFMNetwork(api_key=config_entry.options[CONF_API_KEY]) async def _async_update_data(self) -> dict[str, LastFMUserData]: res = {} diff --git a/homeassistant/components/lastfm/sensor.py b/homeassistant/components/lastfm/sensor.py index 48770113a80..89025583e92 100644 --- a/homeassistant/components/lastfm/sensor.py +++ b/homeassistant/components/lastfm/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -27,7 +27,7 @@ from .coordinator import LastFMDataUpdateCoordinator, LastFMUserData async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize the entries.""" diff --git a/homeassistant/components/launch_library/sensor.py b/homeassistant/components/launch_library/sensor.py index 7d3b2bd97b6..201b4c8f037 100644 --- a/homeassistant/components/launch_library/sensor.py +++ b/homeassistant/components/launch_library/sensor.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, PERCENTAGE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -122,7 +122,7 @@ SENSOR_DESCRIPTIONS: tuple[LaunchLibrarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" name = entry.data.get(CONF_NAME, DEFAULT_NEXT_LAUNCH_NAME) diff --git a/homeassistant/components/laundrify/__init__.py b/homeassistant/components/laundrify/__init__.py index b08624b6d23..7e3dd848348 100644 --- a/homeassistant/components/laundrify/__init__.py +++ b/homeassistant/components/laundrify/__init__.py @@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .const import DEFAULT_POLL_INTERVAL, DOMAIN +from .const import DOMAIN from .coordinator import LaundrifyUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -34,7 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except ApiConnectionException as err: raise ConfigEntryNotReady("Cannot reach laundrify API") from err - coordinator = LaundrifyUpdateCoordinator(hass, api_client, DEFAULT_POLL_INTERVAL) + coordinator = LaundrifyUpdateCoordinator(hass, entry, api_client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/laundrify/binary_sensor.py b/homeassistant/components/laundrify/binary_sensor.py index cee6aa6c754..82f4f7609dc 100644 --- a/homeassistant/components/laundrify/binary_sensor.py +++ b/homeassistant/components/laundrify/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER, MODELS @@ -23,7 +23,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors from a config entry created in the integrations UI.""" diff --git a/homeassistant/components/laundrify/coordinator.py b/homeassistant/components/laundrify/coordinator.py index 22f68a7c5ae..928e30a9ed5 100644 --- a/homeassistant/components/laundrify/coordinator.py +++ b/homeassistant/components/laundrify/coordinator.py @@ -7,11 +7,12 @@ import logging from laundrify_aio import LaundrifyAPI, LaundrifyDevice from laundrify_aio.exceptions import ApiConnectionException, UnauthorizedException +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import DOMAIN, REQUEST_TIMEOUT +from .const import DEFAULT_POLL_INTERVAL, DOMAIN, REQUEST_TIMEOUT _LOGGER = logging.getLogger(__name__) @@ -19,15 +20,21 @@ _LOGGER = logging.getLogger(__name__) class LaundrifyUpdateCoordinator(DataUpdateCoordinator[dict[str, LaundrifyDevice]]): """Class to manage fetching laundrify API data.""" + config_entry: ConfigEntry + def __init__( - self, hass: HomeAssistant, laundrify_api: LaundrifyAPI, poll_interval: int + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + laundrify_api: LaundrifyAPI, ) -> None: """Initialize laundrify coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, - update_interval=timedelta(seconds=poll_interval), + update_interval=timedelta(seconds=DEFAULT_POLL_INTERVAL), ) self.laundrify_api = laundrify_api diff --git a/homeassistant/components/laundrify/sensor.py b/homeassistant/components/laundrify/sensor.py index 98169f95fce..3c343861b0a 100644 --- a/homeassistant/components/laundrify/sensor.py +++ b/homeassistant/components/laundrify/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -24,7 +24,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add power sensor for passed config_entry in HA.""" diff --git a/homeassistant/components/lcn/binary_sensor.py b/homeassistant/components/lcn/binary_sensor.py index d0ce4815f19..65afae56f22 100644 --- a/homeassistant/components/lcn/binary_sensor.py +++ b/homeassistant/components/lcn/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.script import scripts_with_entity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SOURCE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -35,7 +35,7 @@ from .helpers import InputType def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -54,7 +54,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN switch entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/climate.py b/homeassistant/components/lcn/climate.py index 1dff15c4f22..e91ae723714 100644 --- a/homeassistant/components/lcn/climate.py +++ b/homeassistant/components/lcn/climate.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -43,7 +43,7 @@ PARALLEL_UPDATES = 0 def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -57,7 +57,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN switch entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/cover.py b/homeassistant/components/lcn/cover.py index 042461b6af2..be713871aae 100644 --- a/homeassistant/components/lcn/cover.py +++ b/homeassistant/components/lcn/cover.py @@ -10,7 +10,7 @@ from homeassistant.components.cover import DOMAIN as DOMAIN_COVER, CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -28,7 +28,7 @@ PARALLEL_UPDATES = 0 def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -45,7 +45,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN cover entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/light.py b/homeassistant/components/lcn/light.py index 9ec660325c8..cba7c0888b7 100644 --- a/homeassistant/components/lcn/light.py +++ b/homeassistant/components/lcn/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -37,7 +37,7 @@ PARALLEL_UPDATES = 0 def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -54,7 +54,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN light entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/scene.py b/homeassistant/components/lcn/scene.py index 0f40926cf17..072d0a20757 100644 --- a/homeassistant/components/lcn/scene.py +++ b/homeassistant/components/lcn/scene.py @@ -10,7 +10,7 @@ from homeassistant.components.scene import DOMAIN as DOMAIN_SCENE, Scene from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SCENE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -29,7 +29,7 @@ PARALLEL_UPDATES = 0 def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -43,7 +43,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN switch entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/sensor.py b/homeassistant/components/lcn/sensor.py index ada0857742c..ee87ed2a91b 100644 --- a/homeassistant/components/lcn/sensor.py +++ b/homeassistant/components/lcn/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( CONF_UNIT_OF_MEASUREMENT, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -50,7 +50,7 @@ DEVICE_CLASS_MAPPING = { def add_lcn_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -69,7 +69,7 @@ def add_lcn_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN switch entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/lcn/switch.py b/homeassistant/components/lcn/switch.py index dd940bd38b3..6267a081bc9 100644 --- a/homeassistant/components/lcn/switch.py +++ b/homeassistant/components/lcn/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH, SwitchEntit from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .const import ( @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 def add_lcn_switch_entities( config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, entity_configs: Iterable[ConfigType], ) -> None: """Add entities for this domain.""" @@ -53,7 +53,7 @@ def add_lcn_switch_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LCN switch entities from a config entry.""" add_entities = partial( diff --git a/homeassistant/components/ld2410_ble/__init__.py b/homeassistant/components/ld2410_ble/__init__.py index 57e3dfa4617..db67010823d 100644 --- a/homeassistant/components/ld2410_ble/__init__.py +++ b/homeassistant/components/ld2410_ble/__init__.py @@ -41,7 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ld2410_ble = LD2410BLE(ble_device) - coordinator = LD2410BLECoordinator(hass, ld2410_ble) + coordinator = LD2410BLECoordinator(hass, entry, ld2410_ble) try: await ld2410_ble.initialise() diff --git a/homeassistant/components/ld2410_ble/binary_sensor.py b/homeassistant/components/ld2410_ble/binary_sensor.py index c52bc34b699..3ba43e0d6dc 100644 --- a/homeassistant/components/ld2410_ble/binary_sensor.py +++ b/homeassistant/components/ld2410_ble/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import LD2410BLE, LD2410BLECoordinator @@ -31,7 +31,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform for LD2410BLE.""" data: LD2410BLEData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/ld2410_ble/coordinator.py b/homeassistant/components/ld2410_ble/coordinator.py index 2f0fd079773..b318542e798 100644 --- a/homeassistant/components/ld2410_ble/coordinator.py +++ b/homeassistant/components/ld2410_ble/coordinator.py @@ -6,6 +6,7 @@ import time from ld2410_ble import LD2410BLE, LD2410BLEState +from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HassJob, HomeAssistant, callback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -21,11 +22,16 @@ DEBOUNCE_SECONDS = 1.0 class LD2410BLECoordinator(DataUpdateCoordinator[None]): """Data coordinator for receiving LD2410B updates.""" - def __init__(self, hass: HomeAssistant, ld2410_ble: LD2410BLE) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, ld2410_ble: LD2410BLE + ) -> None: """Initialise the coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, ) self._ld2410_ble = ld2410_ble diff --git a/homeassistant/components/ld2410_ble/sensor.py b/homeassistant/components/ld2410_ble/sensor.py index 6daa1397161..db4e42580c4 100644 --- a/homeassistant/components/ld2410_ble/sensor.py +++ b/homeassistant/components/ld2410_ble/sensor.py @@ -11,7 +11,7 @@ from homeassistant.const import EntityCategory, UnitOfLength from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import LD2410BLE, LD2410BLECoordinator @@ -122,7 +122,7 @@ SENSOR_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform for LD2410BLE.""" data: LD2410BLEData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/leaone/sensor.py b/homeassistant/components/leaone/sensor.py index 62948868870..c815a0964e0 100644 --- a/homeassistant/components/leaone/sensor.py +++ b/homeassistant/components/leaone/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfMass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -107,7 +107,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Leaone BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/led_ble/light.py b/homeassistant/components/led_ble/light.py index 3bca7269eba..14f2f228e13 100644 --- a/homeassistant/components/led_ble/light.py +++ b/homeassistant/components/led_ble/light.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -32,7 +32,7 @@ from .models import LEDBLEData async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the light platform for LEDBLE.""" data: LEDBLEData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lektrico/__init__.py b/homeassistant/components/lektrico/__init__.py index 475b6132541..0a6675237dd 100644 --- a/homeassistant/components/lektrico/__init__.py +++ b/homeassistant/components/lektrico/__init__.py @@ -4,11 +4,10 @@ from __future__ import annotations from lektricowifi import Device -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, Platform +from homeassistant.const import CONF_TYPE, Platform from homeassistant.core import HomeAssistant -from .coordinator import LektricoDeviceDataUpdateCoordinator +from .coordinator import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator # List the platforms that charger supports. CHARGERS_PLATFORMS: list[Platform] = [ @@ -26,15 +25,10 @@ LB_DEVICES_PLATFORMS: list[Platform] = [ Platform.SENSOR, ] -type LektricoConfigEntry = ConfigEntry[LektricoDeviceDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: LektricoConfigEntry) -> bool: """Set up Lektrico Charging Station from a config entry.""" - coordinator = LektricoDeviceDataUpdateCoordinator( - hass, - f"{entry.data[CONF_TYPE]}_{entry.data[ATTR_SERIAL_NUMBER]}", - ) + coordinator = LektricoDeviceDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() @@ -45,7 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: LektricoConfigEntry) -> return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: LektricoConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms( @@ -53,7 +47,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) -def _get_platforms(entry: ConfigEntry) -> list[Platform]: +def _get_platforms(entry: LektricoConfigEntry) -> list[Platform]: """Return the platforms for this type of device.""" _device_type: str = entry.data[CONF_TYPE] if _device_type in (Device.TYPE_1P7K, Device.TYPE_3P22K): diff --git a/homeassistant/components/lektrico/binary_sensor.py b/homeassistant/components/lektrico/binary_sensor.py index d0a3e39690c..37e55ade798 100644 --- a/homeassistant/components/lektrico/binary_sensor.py +++ b/homeassistant/components/lektrico/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator from .entity import LektricoEntity @@ -101,7 +101,7 @@ BINARY_SENSORS: tuple[LektricoBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico binary sensor entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/lektrico/button.py b/homeassistant/components/lektrico/button.py index 62aef12ff53..e598773321d 100644 --- a/homeassistant/components/lektrico/button.py +++ b/homeassistant/components/lektrico/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator from .entity import LektricoEntity @@ -60,7 +60,7 @@ BUTTONS_FOR_LB_DEVICES: tuple[LektricoButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico charger based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/lektrico/coordinator.py b/homeassistant/components/lektrico/coordinator.py index 7c72a00e2d3..aa96cf49e07 100644 --- a/homeassistant/components/lektrico/coordinator.py +++ b/homeassistant/components/lektrico/coordinator.py @@ -22,18 +22,21 @@ from .const import LOGGER SCAN_INTERVAL = timedelta(seconds=10) +type LektricoConfigEntry = ConfigEntry[LektricoDeviceDataUpdateCoordinator] + class LektricoDeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Data update coordinator for Lektrico device.""" - config_entry: ConfigEntry + config_entry: LektricoConfigEntry - def __init__(self, hass: HomeAssistant, device_name: str) -> None: + def __init__(self, hass: HomeAssistant, config_entry: LektricoConfigEntry) -> None: """Initialize a Lektrico Device.""" super().__init__( hass, LOGGER, - name=device_name, + config_entry=config_entry, + name=f"{config_entry.data[CONF_TYPE]}_{config_entry.data[ATTR_SERIAL_NUMBER]}", update_interval=SCAN_INTERVAL, ) self.device = Device( diff --git a/homeassistant/components/lektrico/number.py b/homeassistant/components/lektrico/number.py index 8054ba8afe5..c54ee938607 100644 --- a/homeassistant/components/lektrico/number.py +++ b/homeassistant/components/lektrico/number.py @@ -15,7 +15,7 @@ from homeassistant.const import ( UnitOfElectricCurrent, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator from .entity import LektricoEntity @@ -58,7 +58,7 @@ NUMBERS: tuple[LektricoNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico number entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/lektrico/select.py b/homeassistant/components/lektrico/select.py index ef45d97d697..513a82365af 100644 --- a/homeassistant/components/lektrico/select.py +++ b/homeassistant/components/lektrico/select.py @@ -9,7 +9,7 @@ from lektricowifi import Device from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator from .entity import LektricoEntity @@ -46,7 +46,7 @@ SELECTS: tuple[LektricoSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico select entities based on a config entry.""" diff --git a/homeassistant/components/lektrico/sensor.py b/homeassistant/components/lektrico/sensor.py index d55d91c4cd4..927011459b0 100644 --- a/homeassistant/components/lektrico/sensor.py +++ b/homeassistant/components/lektrico/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import IntegrationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator @@ -283,7 +283,7 @@ SENSORS_FOR_LB_3_PHASE: tuple[LektricoSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico charger based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/lektrico/switch.py b/homeassistant/components/lektrico/switch.py index 0fdfbd2ad41..065e96f84b8 100644 --- a/homeassistant/components/lektrico/switch.py +++ b/homeassistant/components/lektrico/switch.py @@ -9,7 +9,7 @@ from lektricowifi import Device from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import ATTR_SERIAL_NUMBER, CONF_TYPE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator from .entity import LektricoEntity @@ -59,7 +59,7 @@ SWITCHS_FOR_3_PHASE_CHARGERS: tuple[LektricoSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LektricoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lektrico switch entities based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/letpot/switch.py b/homeassistant/components/letpot/switch.py index ab02f2860c6..41150d1b1e9 100644 --- a/homeassistant/components/letpot/switch.py +++ b/homeassistant/components/letpot/switch.py @@ -10,7 +10,7 @@ from letpot.models import DeviceFeature, LetPotDeviceStatus from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator from .entity import LetPotEntity, exception_handler @@ -63,7 +63,7 @@ AUTO_MODE_SWITCH: LetPotSwitchEntityDescription = LetPotSwitchEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: LetPotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LetPot switch entities based on a config entry and device status/features.""" coordinators = entry.runtime_data diff --git a/homeassistant/components/letpot/time.py b/homeassistant/components/letpot/time.py index cca088c8e61..bae61df6a28 100644 --- a/homeassistant/components/letpot/time.py +++ b/homeassistant/components/letpot/time.py @@ -11,7 +11,7 @@ from letpot.models import LetPotDeviceStatus from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator from .entity import LetPotEntity, exception_handler @@ -54,7 +54,7 @@ TIME_SENSORS: tuple[LetPotTimeEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: LetPotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LetPot time entities based on a config entry.""" coordinators = entry.runtime_data diff --git a/homeassistant/components/lg_netcast/media_player.py b/homeassistant/components/lg_netcast/media_player.py index b3f8f8e0437..de652eeef08 100644 --- a/homeassistant/components/lg_netcast/media_player.py +++ b/homeassistant/components/lg_netcast/media_player.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST, CONF_MODEL, CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.trigger import PluggableAction from .const import ATTR_MANUFACTURER, DOMAIN @@ -47,7 +47,7 @@ SUPPORT_LGTV = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a LG Netcast Media Player from a config_entry.""" diff --git a/homeassistant/components/lg_soundbar/media_player.py b/homeassistant/components/lg_soundbar/media_player.py index cebe1d33728..c3ea22ee08f 100644 --- a/homeassistant/components/lg_soundbar/media_player.py +++ b/homeassistant/components/lg_soundbar/media_player.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -23,7 +23,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up media_player from a config entry created in the integrations UI.""" async_add_entities( diff --git a/homeassistant/components/lg_thinq/__init__.py b/homeassistant/components/lg_thinq/__init__.py index 657524f0ef5..72d81af4ff0 100644 --- a/homeassistant/components/lg_thinq/__init__.py +++ b/homeassistant/components/lg_thinq/__init__.py @@ -100,7 +100,7 @@ async def async_setup_coordinators( # Setup coordinator per device. task_list = [ - hass.async_create_task(async_setup_device_coordinator(hass, bridge)) + hass.async_create_task(async_setup_device_coordinator(hass, entry, bridge)) for bridge in bridge_list ] task_result = await asyncio.gather(*task_list) diff --git a/homeassistant/components/lg_thinq/binary_sensor.py b/homeassistant/components/lg_thinq/binary_sensor.py index 845bf8c3079..aeade4d132a 100644 --- a/homeassistant/components/lg_thinq/binary_sensor.py +++ b/homeassistant/components/lg_thinq/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .entity import ThinQEntity @@ -136,7 +136,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for binary sensor platform.""" entities: list[ThinQBinarySensorEntity] = [] diff --git a/homeassistant/components/lg_thinq/climate.py b/homeassistant/components/lg_thinq/climate.py index 5cf9ccbd442..ff57709f9a8 100644 --- a/homeassistant/components/lg_thinq/climate.py +++ b/homeassistant/components/lg_thinq/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.temperature import display_temp from . import ThinqConfigEntry @@ -79,7 +79,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for climate platform.""" entities: list[ThinQClimateEntity] = [] diff --git a/homeassistant/components/lg_thinq/coordinator.py b/homeassistant/components/lg_thinq/coordinator.py index 9f317dc21d9..d6991d15297 100644 --- a/homeassistant/components/lg_thinq/coordinator.py +++ b/homeassistant/components/lg_thinq/coordinator.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from typing import Any +from typing import TYPE_CHECKING, Any from thinqconnect import ThinQAPIException from thinqconnect.integration import HABridge @@ -11,6 +11,9 @@ from thinqconnect.integration import HABridge from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import ThinqConfigEntry + from .const import DOMAIN _LOGGER = logging.getLogger(__name__) @@ -19,11 +22,16 @@ _LOGGER = logging.getLogger(__name__) class DeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """LG Device's Data Update Coordinator.""" - def __init__(self, hass: HomeAssistant, ha_bridge: HABridge) -> None: + config_entry: ThinqConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ThinqConfigEntry, ha_bridge: HABridge + ) -> None: """Initialize data coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"{DOMAIN}_{ha_bridge.device.device_id}", ) @@ -71,10 +79,10 @@ class DeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): async def async_setup_device_coordinator( - hass: HomeAssistant, ha_bridge: HABridge + hass: HomeAssistant, config_entry: ThinqConfigEntry, ha_bridge: HABridge ) -> DeviceDataUpdateCoordinator: """Create DeviceDataUpdateCoordinator and device_api per device.""" - coordinator = DeviceDataUpdateCoordinator(hass, ha_bridge) + coordinator = DeviceDataUpdateCoordinator(hass, config_entry, ha_bridge) await coordinator.async_refresh() _LOGGER.debug( diff --git a/homeassistant/components/lg_thinq/event.py b/homeassistant/components/lg_thinq/event.py index b963cba37cc..f9baadf7a05 100644 --- a/homeassistant/components/lg_thinq/event.py +++ b/homeassistant/components/lg_thinq/event.py @@ -9,7 +9,7 @@ from thinqconnect.integration import ActiveMode, ThinQPropertyEx from homeassistant.components.event import EventEntity, EventEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .coordinator import DeviceDataUpdateCoordinator @@ -57,7 +57,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for event platform.""" entities: list[ThinQEventEntity] = [] diff --git a/homeassistant/components/lg_thinq/fan.py b/homeassistant/components/lg_thinq/fan.py index edcadf2598a..6d07c98744a 100644 --- a/homeassistant/components/lg_thinq/fan.py +++ b/homeassistant/components/lg_thinq/fan.py @@ -14,7 +14,7 @@ from homeassistant.components.fan import ( FanEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -41,7 +41,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for fan platform.""" entities: list[ThinQFanEntity] = [] diff --git a/homeassistant/components/lg_thinq/number.py b/homeassistant/components/lg_thinq/number.py index 634c1a8fe84..0cbfcf9b5c8 100644 --- a/homeassistant/components/lg_thinq/number.py +++ b/homeassistant/components/lg_thinq/number.py @@ -16,7 +16,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import PERCENTAGE, UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .entity import ThinQEntity @@ -140,7 +140,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for number platform.""" entities: list[ThinQNumberEntity] = [] diff --git a/homeassistant/components/lg_thinq/select.py b/homeassistant/components/lg_thinq/select.py index e555d616ca3..929fa0b1d28 100644 --- a/homeassistant/components/lg_thinq/select.py +++ b/homeassistant/components/lg_thinq/select.py @@ -10,7 +10,7 @@ from thinqconnect.integration import ActiveMode from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .coordinator import DeviceDataUpdateCoordinator @@ -142,7 +142,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for select platform.""" entities: list[ThinQSelectEntity] = [] diff --git a/homeassistant/components/lg_thinq/sensor.py b/homeassistant/components/lg_thinq/sensor.py index 7baaab52403..bb190cccde9 100644 --- a/homeassistant/components/lg_thinq/sensor.py +++ b/homeassistant/components/lg_thinq/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import ThinqConfigEntry @@ -492,7 +492,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for sensor platform.""" entities: list[ThinQSensorEntity] = [] diff --git a/homeassistant/components/lg_thinq/switch.py b/homeassistant/components/lg_thinq/switch.py index 6d69ce9a314..06363140193 100644 --- a/homeassistant/components/lg_thinq/switch.py +++ b/homeassistant/components/lg_thinq/switch.py @@ -17,7 +17,7 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .entity import ThinQEntity @@ -172,7 +172,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for switch platform.""" entities: list[ThinQSwitchEntity] = [] diff --git a/homeassistant/components/lg_thinq/vacuum.py b/homeassistant/components/lg_thinq/vacuum.py index 6cbb731869c..6cf2a9086b1 100644 --- a/homeassistant/components/lg_thinq/vacuum.py +++ b/homeassistant/components/lg_thinq/vacuum.py @@ -15,7 +15,7 @@ from homeassistant.components.vacuum import ( VacuumEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ThinqConfigEntry from .entity import ThinQEntity @@ -73,7 +73,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ThinqConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an entry for vacuum platform.""" entities: list[ThinQStateVacuumEntity] = [] diff --git a/homeassistant/components/lidarr/__init__.py b/homeassistant/components/lidarr/__init__.py index a421a881b69..e3a5cf250b2 100644 --- a/homeassistant/components/lidarr/__init__.py +++ b/homeassistant/components/lidarr/__init__.py @@ -2,12 +2,11 @@ from __future__ import annotations -from dataclasses import dataclass, fields +from dataclasses import fields from aiopyarr.lidarr_client import LidarrClient from aiopyarr.models.host_configuration import PyArrHostConfiguration -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_URL, CONF_VERIFY_SSL, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr @@ -18,27 +17,16 @@ from .const import DEFAULT_NAME, DOMAIN from .coordinator import ( AlbumsDataUpdateCoordinator, DiskSpaceDataUpdateCoordinator, + LidarrConfigEntry, + LidarrData, QueueDataUpdateCoordinator, StatusDataUpdateCoordinator, WantedDataUpdateCoordinator, ) -type LidarrConfigEntry = ConfigEntry[LidarrData] - PLATFORMS = [Platform.SENSOR] -@dataclass(kw_only=True, slots=True) -class LidarrData: - """Lidarr data type.""" - - disk_space: DiskSpaceDataUpdateCoordinator - queue: QueueDataUpdateCoordinator - status: StatusDataUpdateCoordinator - wanted: WantedDataUpdateCoordinator - albums: AlbumsDataUpdateCoordinator - - async def async_setup_entry(hass: HomeAssistant, entry: LidarrConfigEntry) -> bool: """Set up Lidarr from a config entry.""" host_configuration = PyArrHostConfiguration( @@ -52,11 +40,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: LidarrConfigEntry) -> bo request_timeout=60, ) data = LidarrData( - disk_space=DiskSpaceDataUpdateCoordinator(hass, host_configuration, lidarr), - queue=QueueDataUpdateCoordinator(hass, host_configuration, lidarr), - status=StatusDataUpdateCoordinator(hass, host_configuration, lidarr), - wanted=WantedDataUpdateCoordinator(hass, host_configuration, lidarr), - albums=AlbumsDataUpdateCoordinator(hass, host_configuration, lidarr), + disk_space=DiskSpaceDataUpdateCoordinator( + hass, entry, host_configuration, lidarr + ), + queue=QueueDataUpdateCoordinator(hass, entry, host_configuration, lidarr), + status=StatusDataUpdateCoordinator(hass, entry, host_configuration, lidarr), + wanted=WantedDataUpdateCoordinator(hass, entry, host_configuration, lidarr), + albums=AlbumsDataUpdateCoordinator(hass, entry, host_configuration, lidarr), ) for field in fields(data): coordinator = getattr(data, field.name) diff --git a/homeassistant/components/lidarr/coordinator.py b/homeassistant/components/lidarr/coordinator.py index 1010f708748..3f9d2be4bec 100644 --- a/homeassistant/components/lidarr/coordinator.py +++ b/homeassistant/components/lidarr/coordinator.py @@ -3,6 +3,7 @@ from __future__ import annotations from abc import ABC, abstractmethod +from dataclasses import dataclass from datetime import timedelta from typing import Generic, TypeVar, cast @@ -17,17 +18,32 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DEFAULT_MAX_RECORDS, DOMAIN, LOGGER + +@dataclass(kw_only=True, slots=True) +class LidarrData: + """Lidarr data type.""" + + disk_space: DiskSpaceDataUpdateCoordinator + queue: QueueDataUpdateCoordinator + status: StatusDataUpdateCoordinator + wanted: WantedDataUpdateCoordinator + albums: AlbumsDataUpdateCoordinator + + T = TypeVar("T", bound=list[LidarrRootFolder] | LidarrQueue | str | LidarrAlbum | int) +type LidarrConfigEntry = ConfigEntry[LidarrData] + class LidarrDataUpdateCoordinator(DataUpdateCoordinator[T], Generic[T], ABC): """Data update coordinator for the Lidarr integration.""" - config_entry: ConfigEntry + config_entry: LidarrConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: LidarrConfigEntry, host_configuration: PyArrHostConfiguration, api_client: LidarrClient, ) -> None: @@ -35,6 +51,7 @@ class LidarrDataUpdateCoordinator(DataUpdateCoordinator[T], Generic[T], ABC): super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/lidarr/sensor.py b/homeassistant/components/lidarr/sensor.py index 805fcce53ad..81b2c570eab 100644 --- a/homeassistant/components/lidarr/sensor.py +++ b/homeassistant/components/lidarr/sensor.py @@ -16,11 +16,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import LidarrConfigEntry from .const import BYTE_SIZES -from .coordinator import LidarrDataUpdateCoordinator, T +from .coordinator import LidarrConfigEntry, LidarrDataUpdateCoordinator, T from .entity import LidarrEntity @@ -115,7 +114,7 @@ SENSOR_TYPES: dict[str, LidarrSensorEntityDescription[Any]] = { async def async_setup_entry( hass: HomeAssistant, entry: LidarrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lidarr sensors based on a config entry.""" entities: list[LidarrSensor[Any]] = [] diff --git a/homeassistant/components/lifx/__init__.py b/homeassistant/components/lifx/__init__.py index 2847862029f..7a6d95549ff 100644 --- a/homeassistant/components/lifx/__init__.py +++ b/homeassistant/components/lifx/__init__.py @@ -211,7 +211,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except socket.gaierror as ex: connection.async_stop() raise ConfigEntryNotReady(f"Could not resolve {host}: {ex}") from ex - coordinator = LIFXUpdateCoordinator(hass, connection, entry.title) + coordinator = LIFXUpdateCoordinator(hass, entry, connection) coordinator.async_setup() try: await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/lifx/binary_sensor.py b/homeassistant/components/lifx/binary_sensor.py index 454561a6f4e..f5a974b4626 100644 --- a/homeassistant/components/lifx/binary_sensor.py +++ b/homeassistant/components/lifx/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, HEV_CYCLE_STATE from .coordinator import LIFXUpdateCoordinator @@ -26,7 +26,9 @@ HEV_CYCLE_STATE_SENSOR = BinarySensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LIFX from a config entry.""" coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lifx/button.py b/homeassistant/components/lifx/button.py index 694c91b4c27..25ab61aebae 100644 --- a/homeassistant/components/lifx/button.py +++ b/homeassistant/components/lifx/button.py @@ -10,7 +10,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, IDENTIFY, RESTART from .coordinator import LIFXUpdateCoordinator @@ -32,7 +32,7 @@ IDENTIFY_BUTTON_DESCRIPTION = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LIFX from a config entry.""" domain_data = hass.data[DOMAIN] diff --git a/homeassistant/components/lifx/coordinator.py b/homeassistant/components/lifx/coordinator.py index eaaff7e6540..b77dbdc015a 100644 --- a/homeassistant/components/lifx/coordinator.py +++ b/homeassistant/components/lifx/coordinator.py @@ -23,6 +23,7 @@ from aiolifx_themes.themes import ThemeLibrary, ThemePainter from awesomeversion import AwesomeVersion from propcache.api import cached_property +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( SIGNAL_STRENGTH_DECIBELS, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, @@ -86,11 +87,13 @@ class SkyType(IntEnum): class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): """DataUpdateCoordinator to gather data for a specific lifx device.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, connection: LIFXConnection, - title: str, ) -> None: """Initialize DataUpdateCoordinator.""" assert connection.device is not None @@ -105,7 +108,8 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): super().__init__( hass, _LOGGER, - name=f"{title} ({self.device.ip_addr})", + config_entry=config_entry, + name=f"{config_entry.title} ({self.device.ip_addr})", update_interval=timedelta(seconds=LIGHT_UPDATE_INTERVAL), # We don't want an immediate refresh since the device # takes a moment to reflect the state change diff --git a/homeassistant/components/lifx/light.py b/homeassistant/components/lifx/light.py index 2a8031b3874..5641786eb61 100644 --- a/homeassistant/components/lifx/light.py +++ b/homeassistant/components/lifx/light.py @@ -22,7 +22,7 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.typing import VolDictType @@ -79,7 +79,7 @@ HSBK_KELVIN = 3 async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LIFX from a config entry.""" domain_data = hass.data[DOMAIN] diff --git a/homeassistant/components/lifx/select.py b/homeassistant/components/lifx/select.py index de3a5b431a9..13b81e2a784 100644 --- a/homeassistant/components/lifx/select.py +++ b/homeassistant/components/lifx/select.py @@ -8,7 +8,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_THEME, @@ -38,7 +38,9 @@ THEME_ENTITY = SelectEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LIFX from a config entry.""" coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lifx/sensor.py b/homeassistant/components/lifx/sensor.py index 68f354024e4..96feba633f4 100644 --- a/homeassistant/components/lifx/sensor.py +++ b/homeassistant/components/lifx/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_RSSI, DOMAIN from .coordinator import LIFXUpdateCoordinator @@ -32,7 +32,9 @@ RSSI_SENSOR = SensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up LIFX sensor from config entry.""" coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/light/strings.json b/homeassistant/components/light/strings.json index b874e48406e..c0f658c3a44 100644 --- a/homeassistant/components/light/strings.json +++ b/homeassistant/components/light/strings.json @@ -285,7 +285,7 @@ "services": { "turn_on": { "name": "[%key:common::action::turn_on%]", - "description": "Turn on one or more lights and adjust properties of the light, even when they are turned on already.", + "description": "Turns on one or more lights and adjusts their properties, even when they are turned on already.", "fields": { "transition": { "name": "[%key:component::light::common::field_transition_name%]", @@ -364,7 +364,7 @@ }, "turn_off": { "name": "[%key:common::action::turn_off%]", - "description": "Turn off one or more lights.", + "description": "Turns off one or more lights.", "fields": { "transition": { "name": "[%key:component::light::common::field_transition_name%]", @@ -383,7 +383,7 @@ }, "toggle": { "name": "[%key:common::action::toggle%]", - "description": "Toggles one or more lights, from on to off, or, off to on, based on their current state.", + "description": "Toggles one or more lights, from on to off, or off to on, based on their current state.", "fields": { "transition": { "name": "[%key:component::light::common::field_transition_name%]", diff --git a/homeassistant/components/linear_garage_door/__init__.py b/homeassistant/components/linear_garage_door/__init__.py index e4aa30c98df..5e524fbb512 100644 --- a/homeassistant/components/linear_garage_door/__init__.py +++ b/homeassistant/components/linear_garage_door/__init__.py @@ -31,7 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: }, ) - coordinator = LinearUpdateCoordinator(hass) + coordinator = LinearUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/linear_garage_door/coordinator.py b/homeassistant/components/linear_garage_door/coordinator.py index 38b1306ec38..b55affe92e7 100644 --- a/homeassistant/components/linear_garage_door/coordinator.py +++ b/homeassistant/components/linear_garage_door/coordinator.py @@ -34,15 +34,16 @@ class LinearUpdateCoordinator(DataUpdateCoordinator[dict[str, LinearDevice]]): _devices: list[dict[str, Any]] | None = None config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant) -> None: + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize DataUpdateCoordinator for Linear.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Linear Garage Door", update_interval=timedelta(seconds=60), ) - self.site_id = self.config_entry.data["site_id"] + self.site_id = config_entry.data["site_id"] async def _async_update_data(self) -> dict[str, LinearDevice]: """Get the data for Linear.""" diff --git a/homeassistant/components/linear_garage_door/cover.py b/homeassistant/components/linear_garage_door/cover.py index 1f7ae7ce114..7b0510f00d1 100644 --- a/homeassistant/components/linear_garage_door/cover.py +++ b/homeassistant/components/linear_garage_door/cover.py @@ -10,7 +10,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LinearUpdateCoordinator @@ -24,7 +24,7 @@ SCAN_INTERVAL = timedelta(seconds=10) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Linear Garage Door cover.""" coordinator: LinearUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/linear_garage_door/light.py b/homeassistant/components/linear_garage_door/light.py index 3679491712f..ac03894d446 100644 --- a/homeassistant/components/linear_garage_door/light.py +++ b/homeassistant/components/linear_garage_door/light.py @@ -7,7 +7,7 @@ from linear_garage_door import Linear from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LinearUpdateCoordinator @@ -19,7 +19,7 @@ SUPPORTED_SUBDEVICES = ["Light"] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Linear Garage Door cover.""" coordinator: LinearUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/linkplay/button.py b/homeassistant/components/linkplay/button.py index 1c93ebcdc3e..8865cf00aa5 100644 --- a/homeassistant/components/linkplay/button.py +++ b/homeassistant/components/linkplay/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LinkPlayConfigEntry from .entity import LinkPlayBaseEntity, exception_wrap @@ -50,7 +50,7 @@ BUTTON_TYPES: tuple[LinkPlayButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: LinkPlayConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the LinkPlay buttons from config entry.""" diff --git a/homeassistant/components/linkplay/media_player.py b/homeassistant/components/linkplay/media_player.py index 456fbf23289..2986db76520 100644 --- a/homeassistant/components/linkplay/media_player.py +++ b/homeassistant/components/linkplay/media_player.py @@ -30,7 +30,7 @@ from homeassistant.helpers import ( entity_platform, entity_registry as er, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from . import LinkPlayConfigEntry, LinkPlayData @@ -129,7 +129,7 @@ SERVICE_PLAY_PRESET_SCHEMA = cv.make_entity_service_schema( async def async_setup_entry( hass: HomeAssistant, entry: LinkPlayConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a media player from a config entry.""" diff --git a/homeassistant/components/litejet/light.py b/homeassistant/components/litejet/light.py index f2b9af9adb4..95870927072 100644 --- a/homeassistant/components/litejet/light.py +++ b/homeassistant/components/litejet/light.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_DEFAULT_TRANSITION, DOMAIN @@ -27,7 +27,7 @@ ATTR_NUMBER = "number" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" diff --git a/homeassistant/components/litejet/scene.py b/homeassistant/components/litejet/scene.py index 712e223aa3e..dd96b5accb6 100644 --- a/homeassistant/components/litejet/scene.py +++ b/homeassistant/components/litejet/scene.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -22,7 +22,7 @@ ATTR_NUMBER = "number" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" diff --git a/homeassistant/components/litejet/switch.py b/homeassistant/components/litejet/switch.py index 28f751f3ec1..1b46ba360c3 100644 --- a/homeassistant/components/litejet/switch.py +++ b/homeassistant/components/litejet/switch.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -19,7 +19,7 @@ ATTR_NUMBER = "number" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" diff --git a/homeassistant/components/litterrobot/binary_sensor.py b/homeassistant/components/litterrobot/binary_sensor.py index 700985d285f..ca9af22f1e9 100644 --- a/homeassistant/components/litterrobot/binary_sensor.py +++ b/homeassistant/components/litterrobot/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry from .entity import LitterRobotEntity, _WhiskerEntityT @@ -63,7 +63,7 @@ BINARY_SENSOR_MAP: dict[type[Robot], tuple[RobotBinarySensorEntityDescription, . async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot binary sensors using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/button.py b/homeassistant/components/litterrobot/button.py index 758548b3a67..da6ac53ccec 100644 --- a/homeassistant/components/litterrobot/button.py +++ b/homeassistant/components/litterrobot/button.py @@ -11,7 +11,7 @@ from pylitterbot import FeederRobot, LitterRobot3, LitterRobot4, Robot from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry from .entity import LitterRobotEntity, _WhiskerEntityT @@ -48,7 +48,7 @@ ROBOT_BUTTON_MAP: dict[type[Robot], RobotButtonEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot cleaner using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/select.py b/homeassistant/components/litterrobot/select.py index f6e3781f3df..be3a9915940 100644 --- a/homeassistant/components/litterrobot/select.py +++ b/homeassistant/components/litterrobot/select.py @@ -12,7 +12,7 @@ from pylitterbot.robot.litterrobot4 import BrightnessLevel from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry, LitterRobotDataUpdateCoordinator from .entity import LitterRobotEntity, _WhiskerEntityT @@ -68,7 +68,7 @@ ROBOT_SELECT_MAP: dict[type[Robot], RobotSelectEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot selects using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/sensor.py b/homeassistant/components/litterrobot/sensor.py index 3e25a0556c6..a638f24cf2a 100644 --- a/homeassistant/components/litterrobot/sensor.py +++ b/homeassistant/components/litterrobot/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfMass from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry from .entity import LitterRobotEntity, _WhiskerEntityT @@ -160,7 +160,7 @@ PET_SENSORS: list[RobotSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot sensors using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/switch.py b/homeassistant/components/litterrobot/switch.py index 4839748c068..5924f8f094a 100644 --- a/homeassistant/components/litterrobot/switch.py +++ b/homeassistant/components/litterrobot/switch.py @@ -11,7 +11,7 @@ from pylitterbot import FeederRobot, LitterRobot from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry from .entity import LitterRobotEntity, _WhiskerEntityT @@ -45,7 +45,7 @@ ROBOT_SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot switches using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/time.py b/homeassistant/components/litterrobot/time.py index 69d81d63eae..3573418613b 100644 --- a/homeassistant/components/litterrobot/time.py +++ b/homeassistant/components/litterrobot/time.py @@ -12,7 +12,7 @@ from pylitterbot import LitterRobot3 from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import LitterRobotConfigEntry @@ -49,7 +49,7 @@ LITTER_ROBOT_3_SLEEP_START = RobotTimeEntityDescription[LitterRobot3]( async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot cleaner using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/update.py b/homeassistant/components/litterrobot/update.py index 53ab23e9db8..4d9dfe5074d 100644 --- a/homeassistant/components/litterrobot/update.py +++ b/homeassistant/components/litterrobot/update.py @@ -15,7 +15,7 @@ from homeassistant.components.update import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import LitterRobotConfigEntry from .entity import LitterRobotEntity @@ -31,7 +31,7 @@ FIRMWARE_UPDATE_ENTITY = UpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot update platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/litterrobot/vacuum.py b/homeassistant/components/litterrobot/vacuum.py index 314fab6a621..9989c306b51 100644 --- a/homeassistant/components/litterrobot/vacuum.py +++ b/homeassistant/components/litterrobot/vacuum.py @@ -17,7 +17,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import LitterRobotConfigEntry @@ -46,7 +46,7 @@ LITTER_BOX_ENTITY = StateVacuumEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: LitterRobotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Litter-Robot cleaner using config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/livisi/binary_sensor.py b/homeassistant/components/livisi/binary_sensor.py index d4edd59f2d7..50eb4cd28b9 100644 --- a/homeassistant/components/livisi/binary_sensor.py +++ b/homeassistant/components/livisi/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LIVISI_STATE_CHANGE, LOGGER, WDS_DEVICE_TYPE from .coordinator import LivisiDataUpdateCoordinator @@ -21,7 +21,7 @@ from .entity import LivisiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary_sensor device.""" coordinator: LivisiDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/livisi/climate.py b/homeassistant/components/livisi/climate.py index 3ecdcb486c0..1f5e3360c7d 100644 --- a/homeassistant/components/livisi/climate.py +++ b/homeassistant/components/livisi/climate.py @@ -16,7 +16,7 @@ from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -33,7 +33,7 @@ from .entity import LivisiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate device.""" coordinator: LivisiDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/livisi/coordinator.py b/homeassistant/components/livisi/coordinator.py index b8b282c2829..6557416ed3a 100644 --- a/homeassistant/components/livisi/coordinator.py +++ b/homeassistant/components/livisi/coordinator.py @@ -39,10 +39,10 @@ class LivisiDataUpdateCoordinator(DataUpdateCoordinator[list[dict[str, Any]]]): super().__init__( hass, LOGGER, + config_entry=config_entry, name="Livisi devices", update_interval=timedelta(seconds=DEVICE_POLLING_DELAY), ) - self.config_entry = config_entry self.hass = hass self.aiolivisi = aiolivisi self.websocket = Websocket(aiolivisi) diff --git a/homeassistant/components/livisi/switch.py b/homeassistant/components/livisi/switch.py index fa604c5fc87..5599a4af0d4 100644 --- a/homeassistant/components/livisi/switch.py +++ b/homeassistant/components/livisi/switch.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LIVISI_STATE_CHANGE, LOGGER, SWITCH_DEVICE_TYPES from .coordinator import LivisiDataUpdateCoordinator @@ -19,7 +19,7 @@ from .entity import LivisiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch device.""" coordinator: LivisiDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/local_calendar/calendar.py b/homeassistant/components/local_calendar/calendar.py index eb7b0c20d91..df6f994a46c 100644 --- a/homeassistant/components/local_calendar/calendar.py +++ b/homeassistant/components/local_calendar/calendar.py @@ -26,7 +26,7 @@ from homeassistant.components.calendar import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import CONF_CALENDAR_NAME, DOMAIN @@ -40,7 +40,7 @@ PRODID = "-//homeassistant.io//local_calendar 1.0//EN" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the local calendar platform.""" store = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/local_file/camera.py b/homeassistant/components/local_file/camera.py index db421bbce1d..8be0389678d 100644 --- a/homeassistant/components/local_file/camera.py +++ b/homeassistant/components/local_file/camera.py @@ -20,7 +20,10 @@ from homeassistant.helpers import ( entity_platform, issue_registry as ir, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import slugify @@ -40,7 +43,7 @@ PLATFORM_SCHEMA = CAMERA_PLATFORM_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Camera for local file from a config entry.""" diff --git a/homeassistant/components/local_ip/sensor.py b/homeassistant/components/local_ip/sensor.py index 7f855220563..a4cb9f2d60e 100644 --- a/homeassistant/components/local_ip/sensor.py +++ b/homeassistant/components/local_ip/sensor.py @@ -5,7 +5,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SENSOR @@ -13,7 +13,7 @@ from .const import SENSOR async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config_entry.""" name = entry.data.get(CONF_NAME) or "Local IP" diff --git a/homeassistant/components/local_todo/todo.py b/homeassistant/components/local_todo/todo.py index c496fd6b6ba..30df24ea854 100644 --- a/homeassistant/components/local_todo/todo.py +++ b/homeassistant/components/local_todo/todo.py @@ -17,7 +17,7 @@ from homeassistant.components.todo import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import SetupPhases, async_pause_setup from homeassistant.util import dt as dt_util @@ -65,7 +65,7 @@ def _migrate_calendar(calendar: Calendar) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: LocalTodoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the local_todo todo platform.""" diff --git a/homeassistant/components/locative/device_tracker.py b/homeassistant/components/locative/device_tracker.py index 47a498331eb..f7ae9039729 100644 --- a/homeassistant/components/locative/device_tracker.py +++ b/homeassistant/components/locative/device_tracker.py @@ -4,13 +4,15 @@ from homeassistant.components.device_tracker import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as LT_DOMAIN, TRACKER_UPDATE async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure a dispatcher connection based on a config entry.""" diff --git a/homeassistant/components/london_air/sensor.py b/homeassistant/components/london_air/sensor.py index 81133433d05..a4d34fcb2d6 100644 --- a/homeassistant/components/london_air/sensor.py +++ b/homeassistant/components/london_air/sensor.py @@ -37,10 +37,12 @@ AUTHORITIES = [ "Enfield", "Greenwich", "Hackney", + "Hammersmith and Fulham", "Haringey", "Harrow", "Havering", "Hillingdon", + "Hounslow", "Islington", "Kensington and Chelsea", "Kingston", diff --git a/homeassistant/components/lookin/__init__.py b/homeassistant/components/lookin/__init__.py index a0e529bc189..2fbabc12747 100644 --- a/homeassistant/components/lookin/__init__.py +++ b/homeassistant/components/lookin/__init__.py @@ -122,6 +122,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: coordinator_class = LookinDataUpdateCoordinator[MeteoSensor] meteo_coordinator = coordinator_class( hass, + entry, push_coordinator, name=entry.title, update_method=lookin_protocol.get_meteo_sensor, @@ -140,6 +141,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: updater = _async_remote_updater(lookin_protocol, uuid) coordinator = LookinDataUpdateCoordinator( hass, + entry, push_coordinator, name=f"{entry.title} {uuid}", update_method=updater, diff --git a/homeassistant/components/lookin/climate.py b/homeassistant/components/lookin/climate.py index 051a18c9a32..9cef56bcf9f 100644 --- a/homeassistant/components/lookin/climate.py +++ b/homeassistant/components/lookin/climate.py @@ -28,7 +28,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TYPE_TO_PLATFORM from .coordinator import LookinDataUpdateCoordinator @@ -65,7 +65,7 @@ LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the climate platform for lookin from a config entry.""" lookin_data: LookinData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/lookin/coordinator.py b/homeassistant/components/lookin/coordinator.py index d9834bd1d94..a74cd0e4861 100644 --- a/homeassistant/components/lookin/coordinator.py +++ b/homeassistant/components/lookin/coordinator.py @@ -7,6 +7,7 @@ from datetime import timedelta import logging import time +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -43,9 +44,12 @@ class LookinPushCoordinator: class LookinDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """DataUpdateCoordinator to gather data for a specific lookin devices.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, push_coordinator: LookinPushCoordinator, name: str, update_interval: timedelta | None = None, @@ -56,6 +60,7 @@ class LookinDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=name, update_interval=update_interval, update_method=update_method, diff --git a/homeassistant/components/lookin/light.py b/homeassistant/components/lookin/light.py index 804d0ebef01..d46cb96d6c0 100644 --- a/homeassistant/components/lookin/light.py +++ b/homeassistant/components/lookin/light.py @@ -9,7 +9,7 @@ from homeassistant.components.light import ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TYPE_TO_PLATFORM from .entity import LookinPowerPushRemoteEntity @@ -21,7 +21,7 @@ LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the light platform for lookin from a config entry.""" lookin_data: LookinData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/lookin/media_player.py b/homeassistant/components/lookin/media_player.py index b3dda9c9e0c..a3568d9f155 100644 --- a/homeassistant/components/lookin/media_player.py +++ b/homeassistant/components/lookin/media_player.py @@ -15,7 +15,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TYPE_TO_PLATFORM from .coordinator import LookinDataUpdateCoordinator @@ -44,7 +44,7 @@ _FUNCTION_NAME_TO_FEATURE = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the media_player platform for lookin from a config entry.""" lookin_data: LookinData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/lookin/sensor.py b/homeassistant/components/lookin/sensor.py index cae4f7782a8..89e1ed6aa69 100644 --- a/homeassistant/components/lookin/sensor.py +++ b/homeassistant/components/lookin/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import LookinDeviceCoordinatorEntity @@ -43,7 +43,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lookin sensors from the config entry.""" lookin_data: LookinData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/loqed/__init__.py b/homeassistant/components/loqed/__init__.py index b6408880c96..b308e2c0f1d 100644 --- a/homeassistant/components/loqed/__init__.py +++ b/homeassistant/components/loqed/__init__.py @@ -44,7 +44,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: aiohttp.ClientError, ) as ex: raise ConfigEntryNotReady(f"Unable to connect to bridge at {host}") from ex - coordinator = LoqedDataCoordinator(hass, api, lock, entry) + coordinator = LoqedDataCoordinator(hass, entry, api, lock) await coordinator.ensure_webhooks() await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/loqed/coordinator.py b/homeassistant/components/loqed/coordinator.py index 1447934103e..7b60385a759 100644 --- a/homeassistant/components/loqed/coordinator.py +++ b/homeassistant/components/loqed/coordinator.py @@ -71,19 +71,20 @@ class StatusMessage(TypedDict): class LoqedDataCoordinator(DataUpdateCoordinator[StatusMessage]): """Data update coordinator for the loqed platform.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, api: loqed.LoqedAPI, lock: loqed.Lock, - entry: ConfigEntry, ) -> None: """Initialize the Loqed Data Update coordinator.""" - super().__init__(hass, _LOGGER, name="Loqed sensors") + super().__init__(hass, _LOGGER, config_entry=config_entry, name="Loqed sensors") self._api = api - self._entry = entry self.lock = lock - self.device_name = self._entry.data[CONF_NAME] + self.device_name = config_entry.data[CONF_NAME] async def _async_update_data(self) -> StatusMessage: """Fetch data from API endpoint.""" @@ -110,17 +111,19 @@ class LoqedDataCoordinator(DataUpdateCoordinator[StatusMessage]): async def ensure_webhooks(self) -> None: """Register webhook on LOQED bridge.""" - webhook_id = self._entry.data[CONF_WEBHOOK_ID] + webhook_id = self.config_entry.data[CONF_WEBHOOK_ID] webhook.async_register( self.hass, DOMAIN, "Loqed", webhook_id, self._handle_webhook ) if cloud.async_active_subscription(self.hass): - webhook_url = await async_cloudhook_generate_url(self.hass, self._entry) + webhook_url = await async_cloudhook_generate_url( + self.hass, self.config_entry + ) else: webhook_url = webhook.async_generate_url( - self.hass, self._entry.data[CONF_WEBHOOK_ID] + self.hass, self.config_entry.data[CONF_WEBHOOK_ID] ) _LOGGER.debug("Webhook URL: %s", webhook_url) @@ -140,10 +143,10 @@ class LoqedDataCoordinator(DataUpdateCoordinator[StatusMessage]): async def remove_webhooks(self) -> None: """Remove webhook from LOQED bridge.""" - webhook_id = self._entry.data[CONF_WEBHOOK_ID] + webhook_id = self.config_entry.data[CONF_WEBHOOK_ID] - if CONF_CLOUDHOOK_URL in self._entry.data: - webhook_url = self._entry.data[CONF_CLOUDHOOK_URL] + if CONF_CLOUDHOOK_URL in self.config_entry.data: + webhook_url = self.config_entry.data[CONF_CLOUDHOOK_URL] else: webhook_url = webhook.async_generate_url(self.hass, webhook_id) diff --git a/homeassistant/components/loqed/lock.py b/homeassistant/components/loqed/lock.py index be6b39176d6..2064537df52 100644 --- a/homeassistant/components/loqed/lock.py +++ b/homeassistant/components/loqed/lock.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.lock import LockEntity, LockEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LoqedDataCoordinator from .const import DOMAIN @@ -20,7 +20,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Loqed lock platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/loqed/sensor.py b/homeassistant/components/loqed/sensor.py index 1d4595db8e9..c28b55b4f98 100644 --- a/homeassistant/components/loqed/sensor.py +++ b/homeassistant/components/loqed/sensor.py @@ -15,7 +15,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import LoqedDataCoordinator, StatusMessage @@ -42,7 +42,9 @@ SENSORS: Final[tuple[SensorEntityDescription, ...]] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Loqed lock platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/luftdaten/sensor.py b/homeassistant/components/luftdaten/sensor.py index 8b9def63fda..2189386a4bb 100644 --- a/homeassistant/components/luftdaten/sensor.py +++ b/homeassistant/components/luftdaten/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -72,7 +72,9 @@ SENSORS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Sensor.Community sensor based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lupusec/alarm_control_panel.py b/homeassistant/components/lupusec/alarm_control_panel.py index 4b3d12ad743..03feabae0dc 100644 --- a/homeassistant/components/lupusec/alarm_control_panel.py +++ b/homeassistant/components/lupusec/alarm_control_panel.py @@ -14,7 +14,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .entity import LupusecDevice @@ -25,7 +25,7 @@ SCAN_INTERVAL = timedelta(seconds=2) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an alarm control panel for a Lupusec device.""" data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/lupusec/binary_sensor.py b/homeassistant/components/lupusec/binary_sensor.py index b2413e2b462..bcd21adc1aa 100644 --- a/homeassistant/components/lupusec/binary_sensor.py +++ b/homeassistant/components/lupusec/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .entity import LupusecBaseSensor @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a binary sensors for a Lupusec device.""" diff --git a/homeassistant/components/lupusec/switch.py b/homeassistant/components/lupusec/switch.py index 23f3c927880..a70df90f8e7 100644 --- a/homeassistant/components/lupusec/switch.py +++ b/homeassistant/components/lupusec/switch.py @@ -11,7 +11,7 @@ import lupupy.constants as CONST from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .entity import LupusecBaseSensor @@ -22,7 +22,7 @@ SCAN_INTERVAL = timedelta(seconds=2) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lupusec switch devices.""" diff --git a/homeassistant/components/lutron/binary_sensor.py b/homeassistant/components/lutron/binary_sensor.py index c33b545413d..5bed760e1ac 100644 --- a/homeassistant/components/lutron/binary_sensor.py +++ b/homeassistant/components/lutron/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronDevice @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron binary_sensor platform. diff --git a/homeassistant/components/lutron/cover.py b/homeassistant/components/lutron/cover.py index 2f80798aee4..e8f3ad09879 100644 --- a/homeassistant/components/lutron/cover.py +++ b/homeassistant/components/lutron/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronDevice @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron cover platform. diff --git a/homeassistant/components/lutron/event.py b/homeassistant/components/lutron/event.py index 7b1b9e65137..942e165b97f 100644 --- a/homeassistant/components/lutron/event.py +++ b/homeassistant/components/lutron/event.py @@ -8,7 +8,7 @@ from homeassistant.components.event import EventEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ID from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from . import ATTR_ACTION, ATTR_FULL_ID, ATTR_UUID, DOMAIN, LutronData @@ -33,7 +33,7 @@ LEGACY_EVENT_TYPES: dict[LutronEventType, str] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron event platform.""" entry_data: LutronData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/lutron/fan.py b/homeassistant/components/lutron/fan.py index 7db8b12c8d0..5928c3c2da3 100644 --- a/homeassistant/components/lutron/fan.py +++ b/homeassistant/components/lutron/fan.py @@ -10,7 +10,7 @@ from pylutron import Output from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronDevice @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron fan platform. diff --git a/homeassistant/components/lutron/light.py b/homeassistant/components/lutron/light.py index 7e8829b231c..58183fb0a38 100644 --- a/homeassistant/components/lutron/light.py +++ b/homeassistant/components/lutron/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronDevice @@ -26,7 +26,7 @@ from .entity import LutronDevice async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron light platform. diff --git a/homeassistant/components/lutron/scene.py b/homeassistant/components/lutron/scene.py index 9e8070713a9..4889f9056ac 100644 --- a/homeassistant/components/lutron/scene.py +++ b/homeassistant/components/lutron/scene.py @@ -9,7 +9,7 @@ from pylutron import Button, Keypad, Lutron from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronKeypad @@ -18,7 +18,7 @@ from .entity import LutronKeypad async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron scene platform. diff --git a/homeassistant/components/lutron/switch.py b/homeassistant/components/lutron/switch.py index c8b93dd7398..e1e97d1774a 100644 --- a/homeassistant/components/lutron/switch.py +++ b/homeassistant/components/lutron/switch.py @@ -10,7 +10,7 @@ from pylutron import Button, Keypad, Led, Lutron, Output from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData from .entity import LutronDevice, LutronKeypad @@ -19,7 +19,7 @@ from .entity import LutronDevice, LutronKeypad async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron switch platform. diff --git a/homeassistant/components/lutron_caseta/binary_sensor.py b/homeassistant/components/lutron_caseta/binary_sensor.py index b51756692c1..cb0f0da5227 100644 --- a/homeassistant/components/lutron_caseta/binary_sensor.py +++ b/homeassistant/components/lutron_caseta/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import ATTR_SUGGESTED_AREA from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as CASETA_DOMAIN from .const import CONFIG_URL, MANUFACTURER, UNASSIGNED_AREA @@ -21,7 +21,7 @@ from .util import area_name_from_id async def async_setup_entry( hass: HomeAssistant, config_entry: LutronCasetaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta binary_sensor platform. diff --git a/homeassistant/components/lutron_caseta/button.py b/homeassistant/components/lutron_caseta/button.py index e56758b0af6..f2da502d346 100644 --- a/homeassistant/components/lutron_caseta/button.py +++ b/homeassistant/components/lutron_caseta/button.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .device_trigger import LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP from .entity import LutronCasetaEntity @@ -17,7 +17,7 @@ from .models import LutronCasetaConfigEntry, LutronCasetaData async def async_setup_entry( hass: HomeAssistant, config_entry: LutronCasetaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Lutron pico and keypad buttons.""" data = config_entry.runtime_data diff --git a/homeassistant/components/lutron_caseta/cover.py b/homeassistant/components/lutron_caseta/cover.py index d8fac38ce2b..3727dbf17ba 100644 --- a/homeassistant/components/lutron_caseta/cover.py +++ b/homeassistant/components/lutron_caseta/cover.py @@ -11,7 +11,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import LutronCasetaUpdatableEntity from .models import LutronCasetaConfigEntry @@ -114,7 +114,7 @@ PYLUTRON_TYPE_TO_CLASSES = { async def async_setup_entry( hass: HomeAssistant, config_entry: LutronCasetaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta cover platform. diff --git a/homeassistant/components/lutron_caseta/fan.py b/homeassistant/components/lutron_caseta/fan.py index 69167929e14..1e7fe07b8ba 100644 --- a/homeassistant/components/lutron_caseta/fan.py +++ b/homeassistant/components/lutron_caseta/fan.py @@ -12,7 +12,7 @@ from homeassistant.components.fan import ( FanEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -28,7 +28,7 @@ ORDERED_NAMED_FAN_SPEEDS = [FAN_LOW, FAN_MEDIUM, FAN_MEDIUM_HIGH, FAN_HIGH] async def async_setup_entry( hass: HomeAssistant, config_entry: LutronCasetaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta fan platform. diff --git a/homeassistant/components/lutron_caseta/light.py b/homeassistant/components/lutron_caseta/light.py index 722c9a15d91..b920a95e435 100644 --- a/homeassistant/components/lutron_caseta/light.py +++ b/homeassistant/components/lutron_caseta/light.py @@ -22,7 +22,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DEVICE_TYPE_COLOR_TUNE, @@ -66,7 +66,7 @@ def to_hass_level(level): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta light platform. diff --git a/homeassistant/components/lutron_caseta/scene.py b/homeassistant/components/lutron_caseta/scene.py index db4423495a4..671df82d8e0 100644 --- a/homeassistant/components/lutron_caseta/scene.py +++ b/homeassistant/components/lutron_caseta/scene.py @@ -8,7 +8,7 @@ from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as CASETA_DOMAIN from .util import serial_to_unique_id @@ -17,7 +17,7 @@ from .util import serial_to_unique_id async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta scene platform. diff --git a/homeassistant/components/lutron_caseta/switch.py b/homeassistant/components/lutron_caseta/switch.py index 66f23926fbf..b71ccf4bfa8 100644 --- a/homeassistant/components/lutron_caseta/switch.py +++ b/homeassistant/components/lutron_caseta/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import LutronCasetaUpdatableEntity @@ -13,7 +13,7 @@ from .entity import LutronCasetaUpdatableEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Lutron Caseta switch platform. diff --git a/homeassistant/components/lyric/climate.py b/homeassistant/components/lyric/climate.py index c5d17cfb176..ffcf08b927a 100644 --- a/homeassistant/components/lyric/climate.py +++ b/homeassistant/components/lyric/climate.py @@ -35,7 +35,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -121,7 +121,9 @@ SCHEMA_HOLD_TIME: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Honeywell Lyric climate platform based on a config entry.""" coordinator: DataUpdateCoordinator[Lyric] = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/lyric/sensor.py b/homeassistant/components/lyric/sensor.py index 38cb895a110..065ee0fba9d 100644 --- a/homeassistant/components/lyric/sensor.py +++ b/homeassistant/components/lyric/sensor.py @@ -20,7 +20,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util @@ -159,7 +159,9 @@ def get_datetime_from_future_time(time_str: str) -> datetime: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Honeywell Lyric sensor platform based on a config entry.""" coordinator: DataUpdateCoordinator[Lyric] = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/madvr/binary_sensor.py b/homeassistant/components/madvr/binary_sensor.py index b6820f94fea..45c915aba8c 100644 --- a/homeassistant/components/madvr/binary_sensor.py +++ b/homeassistant/components/madvr/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import MadVRConfigEntry, MadVRCoordinator from .entity import MadVREntity @@ -55,7 +55,7 @@ BINARY_SENSORS: tuple[MadvrBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: MadVRConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensor entities.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/madvr/remote.py b/homeassistant/components/madvr/remote.py index 032a1d718f5..23e969e56e3 100644 --- a/homeassistant/components/madvr/remote.py +++ b/homeassistant/components/madvr/remote.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.remote import RemoteEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import MadVRConfigEntry, MadVRCoordinator from .entity import MadVREntity @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: MadVRConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the madVR remote.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/madvr/sensor.py b/homeassistant/components/madvr/sensor.py index e54e9dca476..783004f3b84 100644 --- a/homeassistant/components/madvr/sensor.py +++ b/homeassistant/components/madvr/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -253,7 +253,7 @@ SENSORS: tuple[MadvrSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: MadVRConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor entities.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/mastodon/__init__.py b/homeassistant/components/mastodon/__init__.py index 2f713a97dfe..ab8514c8321 100644 --- a/homeassistant/components/mastodon/__init__.py +++ b/homeassistant/components/mastodon/__init__.py @@ -47,7 +47,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: MastodonConfigEntry) -> assert entry.unique_id - coordinator = MastodonCoordinator(hass, client) + coordinator = MastodonCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/mastodon/const.py b/homeassistant/components/mastodon/const.py index b7e86eaad5a..a4af49a27a6 100644 --- a/homeassistant/components/mastodon/const.py +++ b/homeassistant/components/mastodon/const.py @@ -26,3 +26,4 @@ ATTR_VISIBILITY = "visibility" ATTR_CONTENT_WARNING = "content_warning" ATTR_MEDIA_WARNING = "media_warning" ATTR_MEDIA = "media" +ATTR_MEDIA_DESCRIPTION = "media_description" diff --git a/homeassistant/components/mastodon/coordinator.py b/homeassistant/components/mastodon/coordinator.py index 4c6fe6b1c88..5d2b193b4a8 100644 --- a/homeassistant/components/mastodon/coordinator.py +++ b/homeassistant/components/mastodon/coordinator.py @@ -32,10 +32,18 @@ type MastodonConfigEntry = ConfigEntry[MastodonData] class MastodonCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching Mastodon data.""" - def __init__(self, hass: HomeAssistant, client: Mastodon) -> None: + config_entry: MastodonConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: MastodonConfigEntry, client: Mastodon + ) -> None: """Initialize coordinator.""" super().__init__( - hass, logger=LOGGER, name="Mastodon", update_interval=timedelta(hours=1) + hass, + logger=LOGGER, + config_entry=config_entry, + name="Mastodon", + update_interval=timedelta(hours=1), ) self.client = client diff --git a/homeassistant/components/mastodon/diagnostics.py b/homeassistant/components/mastodon/diagnostics.py index 7246ae9cf63..dc7c1b785ab 100644 --- a/homeassistant/components/mastodon/diagnostics.py +++ b/homeassistant/components/mastodon/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import MastodonConfigEntry +from .coordinator import MastodonConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/mastodon/entity.py b/homeassistant/components/mastodon/entity.py index 93d630627d7..2ae8c0d852e 100644 --- a/homeassistant/components/mastodon/entity.py +++ b/homeassistant/components/mastodon/entity.py @@ -4,9 +4,8 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import MastodonConfigEntry from .const import DEFAULT_NAME, DOMAIN, INSTANCE_VERSION -from .coordinator import MastodonCoordinator +from .coordinator import MastodonConfigEntry, MastodonCoordinator from .utils import construct_mastodon_username diff --git a/homeassistant/components/mastodon/sensor.py b/homeassistant/components/mastodon/sensor.py index 1bb59ad7c05..74537e33cae 100644 --- a/homeassistant/components/mastodon/sensor.py +++ b/homeassistant/components/mastodon/sensor.py @@ -12,15 +12,15 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import MastodonConfigEntry from .const import ( ACCOUNT_FOLLOWERS_COUNT, ACCOUNT_FOLLOWING_COUNT, ACCOUNT_STATUSES_COUNT, ) +from .coordinator import MastodonConfigEntry from .entity import MastodonEntity # Coordinator is used to centralize the data updates @@ -59,7 +59,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: MastodonConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform for entity.""" coordinator = entry.runtime_data.coordinator diff --git a/homeassistant/components/mastodon/services.py b/homeassistant/components/mastodon/services.py index ab3a89c0c4b..7ab351f8c29 100644 --- a/homeassistant/components/mastodon/services.py +++ b/homeassistant/components/mastodon/services.py @@ -12,16 +12,17 @@ from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant, ServiceCall, ServiceResponse from homeassistant.exceptions import HomeAssistantError, ServiceValidationError -from . import MastodonConfigEntry from .const import ( ATTR_CONFIG_ENTRY_ID, ATTR_CONTENT_WARNING, ATTR_MEDIA, + ATTR_MEDIA_DESCRIPTION, ATTR_MEDIA_WARNING, ATTR_STATUS, ATTR_VISIBILITY, DOMAIN, ) +from .coordinator import MastodonConfigEntry from .utils import get_media_type @@ -42,6 +43,7 @@ SERVICE_POST_SCHEMA = vol.Schema( vol.Optional(ATTR_VISIBILITY): vol.In([x.lower() for x in StatusVisibility]), vol.Optional(ATTR_CONTENT_WARNING): str, vol.Optional(ATTR_MEDIA): str, + vol.Optional(ATTR_MEDIA_DESCRIPTION): str, vol.Optional(ATTR_MEDIA_WARNING): bool, } ) @@ -81,6 +83,7 @@ def setup_services(hass: HomeAssistant) -> None: ) spoiler_text: str | None = call.data.get(ATTR_CONTENT_WARNING) media_path: str | None = call.data.get(ATTR_MEDIA) + media_description: str | None = call.data.get(ATTR_MEDIA_DESCRIPTION) media_warning: str | None = call.data.get(ATTR_MEDIA_WARNING) await hass.async_add_executor_job( @@ -91,6 +94,7 @@ def setup_services(hass: HomeAssistant) -> None: visibility=visibility, spoiler_text=spoiler_text, media_path=media_path, + media_description=media_description, sensitive=media_warning, ) ) @@ -112,9 +116,12 @@ def setup_services(hass: HomeAssistant) -> None: ) media_type = get_media_type(media_path) + media_description = kwargs.get("media_description") try: media_data = client.media_post( - media_file=media_path, mime_type=media_type + media_file=media_path, + mime_type=media_type, + description=media_description, ) except MastodonAPIError as err: @@ -125,6 +132,7 @@ def setup_services(hass: HomeAssistant) -> None: ) from err kwargs.pop("media_path", None) + kwargs.pop("media_description", None) try: media_ids: str | None = None diff --git a/homeassistant/components/mastodon/services.yaml b/homeassistant/components/mastodon/services.yaml index 161a0d152ca..206dc36c1a2 100644 --- a/homeassistant/components/mastodon/services.yaml +++ b/homeassistant/components/mastodon/services.yaml @@ -24,6 +24,10 @@ post: media: selector: text: + media_description: + required: false + selector: + text: media_warning: required: true selector: diff --git a/homeassistant/components/mastodon/strings.json b/homeassistant/components/mastodon/strings.json index 87858f768e4..24a4247636d 100644 --- a/homeassistant/components/mastodon/strings.json +++ b/homeassistant/components/mastodon/strings.json @@ -89,6 +89,10 @@ "name": "Media", "description": "Attach an image or video to the post." }, + "media_description": { + "name": "Media description", + "description": "If an image or video is attached, will add a description for this media for people with visual impairments." + }, "media_warning": { "name": "Media warning", "description": "If an image or video is attached, will mark the media as sensitive (default: no media warning)." diff --git a/homeassistant/components/matter/binary_sensor.py b/homeassistant/components/matter/binary_sensor.py index 484ed94fb90..b5665e5d47a 100644 --- a/homeassistant/components/matter/binary_sensor.py +++ b/homeassistant/components/matter/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity, MatterEntityDescription from .helpers import get_matter @@ -28,7 +28,7 @@ from .models import MatterDiscoverySchema async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter binary sensor from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/button.py b/homeassistant/components/matter/button.py index 634406d18eb..6a0a5fc5b1d 100644 --- a/homeassistant/components/matter/button.py +++ b/homeassistant/components/matter/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity, MatterEntityDescription from .helpers import get_matter @@ -26,7 +26,7 @@ from .models import MatterDiscoverySchema async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter Button platform.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/climate.py b/homeassistant/components/matter/climate.py index 25419c34e42..df57da4ded3 100644 --- a/homeassistant/components/matter/climate.py +++ b/homeassistant/components/matter/climate.py @@ -24,7 +24,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity from .helpers import get_matter @@ -174,7 +174,7 @@ class ThermostatRunningState(IntEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter climate platform from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/cover.py b/homeassistant/components/matter/cover.py index 5b109d52189..2e2d4390b30 100644 --- a/homeassistant/components/matter/cover.py +++ b/homeassistant/components/matter/cover.py @@ -19,7 +19,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER from .entity import MatterEntity @@ -48,7 +48,7 @@ class OperationalStatus(IntEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter Cover from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/event.py b/homeassistant/components/matter/event.py index 3cb3fe385d4..6fa775fd1b9 100644 --- a/homeassistant/components/matter/event.py +++ b/homeassistant/components/matter/event.py @@ -16,7 +16,7 @@ from homeassistant.components.event import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity from .helpers import get_matter @@ -39,7 +39,7 @@ EVENT_TYPES_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter switches from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/fan.py b/homeassistant/components/matter/fan.py index 8b8ebee619d..2c9e190d58a 100644 --- a/homeassistant/components/matter/fan.py +++ b/homeassistant/components/matter/fan.py @@ -16,7 +16,7 @@ from homeassistant.components.fan import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity from .helpers import get_matter @@ -45,7 +45,7 @@ PRESET_SLEEP_WIND = "sleep_wind" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter fan from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/light.py b/homeassistant/components/matter/light.py index 5c20554f065..8ea804a8a7c 100644 --- a/homeassistant/components/matter/light.py +++ b/homeassistant/components/matter/light.py @@ -24,7 +24,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import LOGGER @@ -77,7 +77,7 @@ TRANSITION_BLOCKLIST = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter Light from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/lock.py b/homeassistant/components/matter/lock.py index 8524b39d584..81de7482d46 100644 --- a/homeassistant/components/matter/lock.py +++ b/homeassistant/components/matter/lock.py @@ -15,7 +15,7 @@ from homeassistant.components.lock import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_CODE, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER from .entity import MatterEntity @@ -28,7 +28,7 @@ DoorLockFeature = clusters.DoorLock.Bitmaps.Feature async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter lock from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/number.py b/homeassistant/components/matter/number.py index 93b6b8f75c9..44538f46856 100644 --- a/homeassistant/components/matter/number.py +++ b/homeassistant/components/matter/number.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity, MatterEntityDescription from .helpers import get_matter @@ -32,7 +32,7 @@ from .models import MatterDiscoverySchema async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter Number Input from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/select.py b/homeassistant/components/matter/select.py index b2d1c7f8ddb..e78c34391cd 100644 --- a/homeassistant/components/matter/select.py +++ b/homeassistant/components/matter/select.py @@ -14,7 +14,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity, MatterEntityDescription from .helpers import get_matter @@ -47,7 +47,7 @@ type SelectCluster = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter ModeSelect from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 3503e112db5..10f8db275f5 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -40,7 +40,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from .entity import MatterEntity, MatterEntityDescription @@ -81,7 +81,7 @@ OPERATIONAL_STATE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter sensors from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/switch.py b/homeassistant/components/matter/switch.py index 890ca662295..af4803af9a1 100644 --- a/homeassistant/components/matter/switch.py +++ b/homeassistant/components/matter/switch.py @@ -16,7 +16,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity, MatterEntityDescription from .helpers import get_matter @@ -26,7 +26,7 @@ from .models import MatterDiscoverySchema async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter switches from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/update.py b/homeassistant/components/matter/update.py index 5ee9b2e5fa0..7c9ca991914 100644 --- a/homeassistant/components/matter/update.py +++ b/homeassistant/components/matter/update.py @@ -21,7 +21,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON, Platform from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import ExtraStoredData @@ -60,7 +60,7 @@ class MatterUpdateExtraStoredData(ExtraStoredData): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter lock from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/vacuum.py b/homeassistant/components/matter/vacuum.py index de4a885d8fb..5ea1716a37d 100644 --- a/homeassistant/components/matter/vacuum.py +++ b/homeassistant/components/matter/vacuum.py @@ -17,7 +17,7 @@ from homeassistant.components.vacuum import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity from .helpers import get_matter @@ -50,7 +50,7 @@ class ModeTag(IntEnum): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter vacuum platform from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/matter/valve.py b/homeassistant/components/matter/valve.py index 29946621853..bea11468c6b 100644 --- a/homeassistant/components/matter/valve.py +++ b/homeassistant/components/matter/valve.py @@ -14,7 +14,7 @@ from homeassistant.components.valve import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import MatterEntity from .helpers import get_matter @@ -28,7 +28,7 @@ ValveStateEnum = ValveConfigurationAndControl.Enums.ValveStateEnum async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Matter valve platform from Config Entry.""" matter = get_matter(hass) diff --git a/homeassistant/components/mealie/__init__.py b/homeassistant/components/mealie/__init__.py index 5e1523b939a..e019dae2c33 100644 --- a/homeassistant/components/mealie/__init__.py +++ b/homeassistant/components/mealie/__init__.py @@ -86,9 +86,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: MealieConfigEntry) -> bo sw_version=about.version, ) - mealplan_coordinator = MealieMealplanCoordinator(hass, client) - shoppinglist_coordinator = MealieShoppingListCoordinator(hass, client) - statistics_coordinator = MealieStatisticsCoordinator(hass, client) + mealplan_coordinator = MealieMealplanCoordinator(hass, entry, client) + shoppinglist_coordinator = MealieShoppingListCoordinator(hass, entry, client) + statistics_coordinator = MealieStatisticsCoordinator(hass, entry, client) await mealplan_coordinator.async_config_entry_first_refresh() await shoppinglist_coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/mealie/calendar.py b/homeassistant/components/mealie/calendar.py index 729bc16c6fd..556ddede2e2 100644 --- a/homeassistant/components/mealie/calendar.py +++ b/homeassistant/components/mealie/calendar.py @@ -8,7 +8,7 @@ from aiomealie import Mealplan, MealplanEntryType from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import MealieConfigEntry, MealieMealplanCoordinator from .entity import MealieEntity @@ -19,7 +19,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: MealieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the calendar platform for entity.""" coordinator = entry.runtime_data.mealplan_coordinator diff --git a/homeassistant/components/mealie/coordinator.py b/homeassistant/components/mealie/coordinator.py index cf8dfb5bc90..ae5b9cd8c97 100644 --- a/homeassistant/components/mealie/coordinator.py +++ b/homeassistant/components/mealie/coordinator.py @@ -48,11 +48,14 @@ class MealieDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): _name: str _update_interval: timedelta - def __init__(self, hass: HomeAssistant, client: MealieClient) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: MealieConfigEntry, client: MealieClient + ) -> None: """Initialize the Mealie data coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=f"Mealie {self._name}", update_interval=self._update_interval, ) diff --git a/homeassistant/components/mealie/sensor.py b/homeassistant/components/mealie/sensor.py index e4b1655a9d1..062a2646cab 100644 --- a/homeassistant/components/mealie/sensor.py +++ b/homeassistant/components/mealie/sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import MealieConfigEntry, MealieStatisticsCoordinator @@ -59,7 +59,7 @@ SENSOR_TYPES: tuple[MealieStatisticsSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: MealieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Mealie sensors based on a config entry.""" coordinator = entry.runtime_data.statistics_coordinator diff --git a/homeassistant/components/mealie/todo.py b/homeassistant/components/mealie/todo.py index be04b00113e..d42c9033922 100644 --- a/homeassistant/components/mealie/todo.py +++ b/homeassistant/components/mealie/todo.py @@ -14,7 +14,7 @@ from homeassistant.components.todo import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MealieConfigEntry, MealieShoppingListCoordinator @@ -46,7 +46,7 @@ def _convert_api_item(item: ShoppingItem) -> TodoItem: async def async_setup_entry( hass: HomeAssistant, entry: MealieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the todo platform for entity.""" coordinator = entry.runtime_data.shoppinglist_coordinator diff --git a/homeassistant/components/meater/sensor.py b/homeassistant/components/meater/sensor.py index 2a26d848ac2..00fc28b8718 100644 --- a/homeassistant/components/meater/sensor.py +++ b/homeassistant/components/meater/sensor.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -136,7 +136,9 @@ SENSOR_TYPES = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the entry.""" coordinator: DataUpdateCoordinator[dict[str, MeaterProbe]] = hass.data[DOMAIN][ diff --git a/homeassistant/components/medcom_ble/sensor.py b/homeassistant/components/medcom_ble/sensor.py index b5cb29be845..f837620c829 100644 --- a/homeassistant/components/medcom_ble/sensor.py +++ b/homeassistant/components/medcom_ble/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -37,7 +37,7 @@ SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Medcom BLE radiation monitor sensors.""" diff --git a/homeassistant/components/melcloud/climate.py b/homeassistant/components/melcloud/climate.py index 4defd47bc39..03bb4babf1c 100644 --- a/homeassistant/components/melcloud/climate.py +++ b/homeassistant/components/melcloud/climate.py @@ -28,7 +28,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MelCloudDevice from .const import ( @@ -76,7 +76,9 @@ ATW_ZONE_HVAC_ACTION_LOOKUP = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MelCloud device climate based on config_entry.""" mel_devices = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/melcloud/sensor.py b/homeassistant/components/melcloud/sensor.py index 84585c556ca..51a026e717a 100644 --- a/homeassistant/components/melcloud/sensor.py +++ b/homeassistant/components/melcloud/sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MelCloudDevice from .const import DOMAIN @@ -104,7 +104,9 @@ ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MELCloud device sensors based on config_entry.""" mel_devices = hass.data[DOMAIN].get(entry.entry_id) diff --git a/homeassistant/components/melcloud/water_heater.py b/homeassistant/components/melcloud/water_heater.py index 8de1ac53311..76fbad41575 100644 --- a/homeassistant/components/melcloud/water_heater.py +++ b/homeassistant/components/melcloud/water_heater.py @@ -20,14 +20,16 @@ from homeassistant.components.water_heater import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, MelCloudDevice from .const import ATTR_STATUS async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MelCloud device climate based on config_entry.""" mel_devices = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/melnor/__init__.py b/homeassistant/components/melnor/__init__.py index afaf8eb95f8..6ab725d747c 100644 --- a/homeassistant/components/melnor/__init__.py +++ b/homeassistant/components/melnor/__init__.py @@ -57,7 +57,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: bluetooth.BluetoothScanningMode.PASSIVE, ) - coordinator = MelnorDataUpdateCoordinator(hass, device) + coordinator = MelnorDataUpdateCoordinator(hass, entry, device) await coordinator.async_config_entry_first_refresh() hass.data[DOMAIN][entry.entry_id] = coordinator diff --git a/homeassistant/components/melnor/coordinator.py b/homeassistant/components/melnor/coordinator.py index 669fe916082..52662fd0c4c 100644 --- a/homeassistant/components/melnor/coordinator.py +++ b/homeassistant/components/melnor/coordinator.py @@ -5,6 +5,7 @@ import logging from melnor_bluetooth.device import Device +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -14,13 +15,17 @@ _LOGGER = logging.getLogger(__name__) class MelnorDataUpdateCoordinator(DataUpdateCoordinator[Device]): """Melnor data update coordinator.""" + config_entry: ConfigEntry _device: Device - def __init__(self, hass: HomeAssistant, device: Device) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, device: Device + ) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Melnor Bluetooth", update_interval=timedelta(seconds=5), ) diff --git a/homeassistant/components/melnor/number.py b/homeassistant/components/melnor/number.py index 15c47008346..42c22ae5a43 100644 --- a/homeassistant/components/melnor/number.py +++ b/homeassistant/components/melnor/number.py @@ -16,7 +16,7 @@ from homeassistant.components.number import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MelnorDataUpdateCoordinator @@ -68,7 +68,7 @@ ZONE_ENTITY_DESCRIPTIONS: list[MelnorZoneNumberEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the number platform.""" diff --git a/homeassistant/components/melnor/sensor.py b/homeassistant/components/melnor/sensor.py index bbb3416dcc9..525a29dc6cf 100644 --- a/homeassistant/components/melnor/sensor.py +++ b/homeassistant/components/melnor/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -105,7 +105,7 @@ ZONE_ENTITY_DESCRIPTIONS: list[MelnorZoneSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/melnor/switch.py b/homeassistant/components/melnor/switch.py index d7fb96739b3..cc5abe8f6f3 100644 --- a/homeassistant/components/melnor/switch.py +++ b/homeassistant/components/melnor/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MelnorDataUpdateCoordinator @@ -52,7 +52,7 @@ ZONE_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch platform.""" diff --git a/homeassistant/components/melnor/time.py b/homeassistant/components/melnor/time.py index 08de7e054de..277eb6e36eb 100644 --- a/homeassistant/components/melnor/time.py +++ b/homeassistant/components/melnor/time.py @@ -13,7 +13,7 @@ from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MelnorDataUpdateCoordinator @@ -42,7 +42,7 @@ ZONE_ENTITY_DESCRIPTIONS: list[MelnorZoneTimeEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the number platform.""" diff --git a/homeassistant/components/met/__init__.py b/homeassistant/components/met/__init__.py index 1cd7a4bde57..17fc411bf20 100644 --- a/homeassistant/components/met/__init__.py +++ b/homeassistant/components/met/__init__.py @@ -4,7 +4,6 @@ from __future__ import annotations import logging -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr @@ -15,14 +14,12 @@ from .const import ( DEFAULT_HOME_LONGITUDE, DOMAIN, ) -from .coordinator import MetDataUpdateCoordinator +from .coordinator import MetDataUpdateCoordinator, MetWeatherConfigEntry PLATFORMS = [Platform.WEATHER] _LOGGER = logging.getLogger(__name__) -type MetWeatherConfigEntry = ConfigEntry[MetDataUpdateCoordinator] - async def async_setup_entry( hass: HomeAssistant, config_entry: MetWeatherConfigEntry diff --git a/homeassistant/components/met/coordinator.py b/homeassistant/components/met/coordinator.py index 3887a29f83c..de27da7a07f 100644 --- a/homeassistant/components/met/coordinator.py +++ b/homeassistant/components/met/coordinator.py @@ -31,6 +31,8 @@ URL = "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/2.0/comp _LOGGER = logging.getLogger(__name__) +type MetWeatherConfigEntry = ConfigEntry[MetDataUpdateCoordinator] + class CannotConnect(HomeAssistantError): """Unable to connect to the web site.""" @@ -89,7 +91,11 @@ class MetWeatherData: class MetDataUpdateCoordinator(DataUpdateCoordinator[MetWeatherData]): """Class to manage fetching Met data.""" - def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: + config_entry: MetWeatherConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: MetWeatherConfigEntry + ) -> None: """Initialize global Met data updater.""" self._unsub_track_home: Callable[[], None] | None = None self.weather = MetWeatherData(hass, config_entry.data) @@ -97,7 +103,13 @@ class MetDataUpdateCoordinator(DataUpdateCoordinator[MetWeatherData]): update_interval = timedelta(minutes=randrange(55, 65)) - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=update_interval, + ) async def _async_update_data(self) -> MetWeatherData: """Fetch data from Met.""" diff --git a/homeassistant/components/met/weather.py b/homeassistant/components/met/weather.py index 7b95567366b..c4f9c8e6885 100644 --- a/homeassistant/components/met/weather.py +++ b/homeassistant/components/met/weather.py @@ -34,10 +34,9 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er, sun from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import METRIC_SYSTEM -from . import MetWeatherConfigEntry from .const import ( ATTR_CONDITION_CLEAR_NIGHT, ATTR_CONDITION_SUNNY, @@ -47,7 +46,7 @@ from .const import ( DOMAIN, FORECAST_MAP, ) -from .coordinator import MetDataUpdateCoordinator +from .coordinator import MetDataUpdateCoordinator, MetWeatherConfigEntry DEFAULT_NAME = "Met.no" @@ -55,7 +54,7 @@ DEFAULT_NAME = "Met.no" async def async_setup_entry( hass: HomeAssistant, config_entry: MetWeatherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/met_eireann/weather.py b/homeassistant/components/met_eireann/weather.py index 404ef5d8393..72706ccb70f 100644 --- a/homeassistant/components/met_eireann/weather.py +++ b/homeassistant/components/met_eireann/weather.py @@ -25,7 +25,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util @@ -47,7 +47,7 @@ def format_condition(condition: str | None) -> str | None: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/meteo_france/sensor.py b/homeassistant/components/meteo_france/sensor.py index 826716f1679..c29cc1ceda9 100644 --- a/homeassistant/components/meteo_france/sensor.py +++ b/homeassistant/components/meteo_france/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -182,7 +182,9 @@ SENSOR_TYPES_PROBABILITY: tuple[MeteoFranceSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Meteo-France sensor platform.""" data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/meteo_france/weather.py b/homeassistant/components/meteo_france/weather.py index 8305547afd3..67a56271c2b 100644 --- a/homeassistant/components/meteo_france/weather.py +++ b/homeassistant/components/meteo_france/weather.py @@ -28,7 +28,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -55,7 +55,9 @@ def format_condition(condition: str): async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Meteo-France weather platform.""" coordinator: DataUpdateCoordinator[MeteoFranceForecast] = hass.data[DOMAIN][ diff --git a/homeassistant/components/meteoclimatic/sensor.py b/homeassistant/components/meteoclimatic/sensor.py index 2194f82e43e..e51fcfd3f20 100644 --- a/homeassistant/components/meteoclimatic/sensor.py +++ b/homeassistant/components/meteoclimatic/sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -112,7 +112,9 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Meteoclimatic sensor platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/meteoclimatic/weather.py b/homeassistant/components/meteoclimatic/weather.py index 75a93689efa..fa3b3c92288 100644 --- a/homeassistant/components/meteoclimatic/weather.py +++ b/homeassistant/components/meteoclimatic/weather.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPressure, UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -26,7 +26,9 @@ def format_condition(condition): async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Meteoclimatic weather platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/metoffice/sensor.py b/homeassistant/components/metoffice/sensor.py index 61f825abdc3..5a256144d11 100644 --- a/homeassistant/components/metoffice/sensor.py +++ b/homeassistant/components/metoffice/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -142,7 +142,9 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Met Office weather sensor platform.""" hass_data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/metoffice/weather.py b/homeassistant/components/metoffice/weather.py index 5eeddee8dd4..d3f1320c47e 100644 --- a/homeassistant/components/metoffice/weather.py +++ b/homeassistant/components/metoffice/weather.py @@ -21,7 +21,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPressure, UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import TimestampDataUpdateCoordinator from . import get_device_info @@ -39,7 +39,9 @@ from .data import MetOfficeData async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Met Office weather sensor platform.""" entity_registry = er.async_get(hass) diff --git a/homeassistant/components/microbees/__init__.py b/homeassistant/components/microbees/__init__.py index 488988ab593..12c536121da 100644 --- a/homeassistant/components/microbees/__init__.py +++ b/homeassistant/components/microbees/__init__.py @@ -45,7 +45,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: raise ConfigEntryAuthFailed("Token not valid, trigger renewal") from ex raise ConfigEntryNotReady from ex microbees = MicroBees(token=session.token[CONF_ACCESS_TOKEN]) - coordinator = MicroBeesUpdateCoordinator(hass, microbees) + coordinator = MicroBeesUpdateCoordinator(hass, entry, microbees) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantMicroBeesData( connector=microbees, diff --git a/homeassistant/components/microbees/binary_sensor.py b/homeassistant/components/microbees/binary_sensor.py index 551f68ba354..1dc2a8d9702 100644 --- a/homeassistant/components/microbees/binary_sensor.py +++ b/homeassistant/components/microbees/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -36,7 +36,9 @@ BINARYSENSOR_TYPES = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the microBees binary sensor platform.""" coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/microbees/button.py b/homeassistant/components/microbees/button.py index f449fa9afee..ca3a76753a7 100644 --- a/homeassistant/components/microbees/button.py +++ b/homeassistant/components/microbees/button.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -15,7 +15,9 @@ BUTTON_TRANSLATIONS = {51: "button_gate", 91: "button_panic"} async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the microBees button platform.""" coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/microbees/climate.py b/homeassistant/components/microbees/climate.py index 077048ee352..554ca3b32cc 100644 --- a/homeassistant/components/microbees/climate.py +++ b/homeassistant/components/microbees/climate.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -26,7 +26,9 @@ THERMOVALVE_SENSOR_ID = 782 async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the microBees climate platform.""" coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/microbees/coordinator.py b/homeassistant/components/microbees/coordinator.py index af207507e77..0094dc33e81 100644 --- a/homeassistant/components/microbees/coordinator.py +++ b/homeassistant/components/microbees/coordinator.py @@ -9,6 +9,7 @@ import logging import aiohttp from microBeesPy import Actuator, Bee, MicroBees, MicroBeesException, Sensor +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -28,11 +29,16 @@ class MicroBeesCoordinatorData: class MicroBeesUpdateCoordinator(DataUpdateCoordinator[MicroBeesCoordinatorData]): """MicroBees coordinator.""" - def __init__(self, hass: HomeAssistant, microbees: MicroBees) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, microbees: MicroBees + ) -> None: """Initialize microBees coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="microBees Coordinator", update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/microbees/cover.py b/homeassistant/components/microbees/cover.py index b6d5d366d89..fe87fcddd62 100644 --- a/homeassistant/components/microbees/cover.py +++ b/homeassistant/components/microbees/cover.py @@ -12,7 +12,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from .const import DOMAIN @@ -23,7 +23,9 @@ COVER_IDS = {47: "roller_shutter"} async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the microBees cover platform.""" coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/microbees/light.py b/homeassistant/components/microbees/light.py index 654cdc37182..a7ff60dc64a 100644 --- a/homeassistant/components/microbees/light.py +++ b/homeassistant/components/microbees/light.py @@ -6,7 +6,7 @@ from homeassistant.components.light import ATTR_RGBW_COLOR, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -14,7 +14,9 @@ from .entity import MicroBeesActuatorEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Config entry.""" coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/microbees/sensor.py b/homeassistant/components/microbees/sensor.py index 360422de735..e4be463ab10 100644 --- a/homeassistant/components/microbees/sensor.py +++ b/homeassistant/components/microbees/sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -63,7 +63,9 @@ SENSOR_TYPES = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id].coordinator diff --git a/homeassistant/components/microbees/switch.py b/homeassistant/components/microbees/switch.py index 1d668d041e1..deda2d78d09 100644 --- a/homeassistant/components/microbees/switch.py +++ b/homeassistant/components/microbees/switch.py @@ -6,7 +6,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MicroBeesUpdateCoordinator @@ -17,7 +17,9 @@ SWITCH_PRODUCT_IDS = {25, 26, 27, 35, 38, 46, 63, 64, 65, 86} async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id].coordinator diff --git a/homeassistant/components/mikrotik/__init__.py b/homeassistant/components/mikrotik/__init__.py index cecf96a6c3e..4e17653c05a 100644 --- a/homeassistant/components/mikrotik/__init__.py +++ b/homeassistant/components/mikrotik/__init__.py @@ -1,19 +1,16 @@ """The Mikrotik component.""" -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from .const import ATTR_MANUFACTURER, DOMAIN -from .coordinator import MikrotikDataUpdateCoordinator, get_api +from .coordinator import MikrotikConfigEntry, MikrotikDataUpdateCoordinator, get_api from .errors import CannotConnect, LoginError PLATFORMS = [Platform.DEVICE_TRACKER] -type MikrotikConfigEntry = ConfigEntry[MikrotikDataUpdateCoordinator] - async def async_setup_entry( hass: HomeAssistant, config_entry: MikrotikConfigEntry @@ -47,6 +44,8 @@ async def async_setup_entry( return True -async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_unload_entry( + hass: HomeAssistant, config_entry: MikrotikConfigEntry +) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) diff --git a/homeassistant/components/mikrotik/coordinator.py b/homeassistant/components/mikrotik/coordinator.py index 6cb36d58fbe..c68b13eeca8 100644 --- a/homeassistant/components/mikrotik/coordinator.py +++ b/homeassistant/components/mikrotik/coordinator.py @@ -45,6 +45,8 @@ from .errors import CannotConnect, LoginError _LOGGER = logging.getLogger(__name__) +type MikrotikConfigEntry = ConfigEntry[MikrotikDataUpdateCoordinator] + class MikrotikData: """Handle all communication with the Mikrotik API.""" @@ -246,17 +248,21 @@ class MikrotikData: class MikrotikDataUpdateCoordinator(DataUpdateCoordinator[None]): """Mikrotik Hub Object.""" + config_entry: MikrotikConfigEntry + def __init__( - self, hass: HomeAssistant, config_entry: ConfigEntry, api: librouteros.Api + self, + hass: HomeAssistant, + config_entry: MikrotikConfigEntry, + api: librouteros.Api, ) -> None: """Initialize the Mikrotik Client.""" - self.hass = hass - self.config_entry: ConfigEntry = config_entry - self._mk_data = MikrotikData(self.hass, self.config_entry, api) + self._mk_data = MikrotikData(hass, config_entry, api) super().__init__( - self.hass, + hass, _LOGGER, - name=f"{DOMAIN} - {self.host}", + config_entry=config_entry, + name=f"{DOMAIN} - {config_entry.data[CONF_HOST]}", update_interval=timedelta(seconds=10), ) diff --git a/homeassistant/components/mikrotik/device_tracker.py b/homeassistant/components/mikrotik/device_tracker.py index 19d5c789c09..f7bc10e31d4 100644 --- a/homeassistant/components/mikrotik/device_tracker.py +++ b/homeassistant/components/mikrotik/device_tracker.py @@ -10,18 +10,17 @@ from homeassistant.components.device_tracker import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util -from . import MikrotikConfigEntry -from .coordinator import Device, MikrotikDataUpdateCoordinator +from .coordinator import Device, MikrotikConfigEntry, MikrotikDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: MikrotikConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Mikrotik component.""" coordinator = config_entry.runtime_data @@ -55,7 +54,7 @@ async def async_setup_entry( @callback def update_items( coordinator: MikrotikDataUpdateCoordinator, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: dict[str, MikrotikDataUpdateCoordinatorTracker], ) -> None: """Update tracked device state from the hub.""" diff --git a/homeassistant/components/mill/__init__.py b/homeassistant/components/mill/__init__.py index 116b3ef0341..2fcf2033930 100644 --- a/homeassistant/components/mill/__init__.py +++ b/homeassistant/components/mill/__init__.py @@ -47,9 +47,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except TimeoutError as error: raise ConfigEntryNotReady from error data_coordinator = MillDataUpdateCoordinator( - hass, - mill_data_connection=mill_data_connection, - update_interval=update_interval, + hass, entry, mill_data_connection, update_interval ) await data_coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/mill/climate.py b/homeassistant/components/mill/climate.py index 3cd9247c63a..ba496923a30 100644 --- a/homeassistant/components/mill/climate.py +++ b/homeassistant/components/mill/climate.py @@ -23,7 +23,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -54,7 +54,9 @@ SET_ROOM_TEMP_SCHEMA = vol.Schema( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Mill climate.""" if entry.data.get(CONNECTION_TYPE) == LOCAL: diff --git a/homeassistant/components/mill/coordinator.py b/homeassistant/components/mill/coordinator.py index 9821519ca84..ae527f8cce5 100644 --- a/homeassistant/components/mill/coordinator.py +++ b/homeassistant/components/mill/coordinator.py @@ -8,6 +8,7 @@ import logging from mill import Mill from mill_local import Mill as MillLocal +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -19,12 +20,14 @@ _LOGGER = logging.getLogger(__name__) class MillDataUpdateCoordinator(DataUpdateCoordinator): """Class to manage fetching Mill data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - update_interval: timedelta | None = None, - *, + config_entry: ConfigEntry, mill_data_connection: Mill | MillLocal, + update_interval: timedelta, ) -> None: """Initialize global Mill data updater.""" self.mill_data_connection = mill_data_connection @@ -32,6 +35,7 @@ class MillDataUpdateCoordinator(DataUpdateCoordinator): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_method=mill_data_connection.fetch_heater_and_sensor_data, update_interval=update_interval, diff --git a/homeassistant/components/mill/number.py b/homeassistant/components/mill/number.py index b4ef7bdd2c2..8433a9853c6 100644 --- a/homeassistant/components/mill/number.py +++ b/homeassistant/components/mill/number.py @@ -8,7 +8,7 @@ from homeassistant.components.number import NumberDeviceClass, NumberEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_USERNAME, UnitOfPower from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CLOUD, CONNECTION_TYPE, DOMAIN from .coordinator import MillDataUpdateCoordinator @@ -16,7 +16,9 @@ from .entity import MillBaseEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Mill Number.""" if entry.data.get(CONNECTION_TYPE) == CLOUD: diff --git a/homeassistant/components/mill/sensor.py b/homeassistant/components/mill/sensor.py index 57eead9be18..3a47cb427d2 100644 --- a/homeassistant/components/mill/sensor.py +++ b/homeassistant/components/mill/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -146,7 +146,9 @@ SOCKET_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Mill sensor.""" if entry.data.get(CONNECTION_TYPE) == LOCAL: diff --git a/homeassistant/components/min_max/sensor.py b/homeassistant/components/min_max/sensor.py index 89252a58864..9039c3e9e24 100644 --- a/homeassistant/components/min_max/sensor.py +++ b/homeassistant/components/min_max/sensor.py @@ -25,7 +25,10 @@ from homeassistant.const import ( ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType @@ -75,7 +78,7 @@ PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize min/max/mean config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/minecraft_server/__init__.py b/homeassistant/components/minecraft_server/__init__.py index f1392ea488a..55bf96a7b89 100644 --- a/homeassistant/components/minecraft_server/__init__.py +++ b/homeassistant/components/minecraft_server/__init__.py @@ -10,14 +10,7 @@ import dns.rdataclass import dns.rdatatype from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_ADDRESS, - CONF_HOST, - CONF_NAME, - CONF_PORT, - CONF_TYPE, - Platform, -) +from homeassistant.const import CONF_ADDRESS, CONF_HOST, CONF_PORT, CONF_TYPE, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import device_registry as dr, entity_registry as er @@ -58,7 +51,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: raise ConfigEntryNotReady(f"Initialization failed: {error}") from error # Create coordinator instance. - coordinator = MinecraftServerCoordinator(hass, entry.data[CONF_NAME], api) + coordinator = MinecraftServerCoordinator(hass, entry, api) await coordinator.async_config_entry_first_refresh() # Store coordinator instance. diff --git a/homeassistant/components/minecraft_server/binary_sensor.py b/homeassistant/components/minecraft_server/binary_sensor.py index 60f2e00da0e..d2c8aca57e4 100644 --- a/homeassistant/components/minecraft_server/binary_sensor.py +++ b/homeassistant/components/minecraft_server/binary_sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MinecraftServerCoordinator @@ -28,7 +28,7 @@ BINARY_SENSOR_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Minecraft Server binary sensor platform.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/minecraft_server/coordinator.py b/homeassistant/components/minecraft_server/coordinator.py index 37eeb9f2ac2..f66e4acf214 100644 --- a/homeassistant/components/minecraft_server/coordinator.py +++ b/homeassistant/components/minecraft_server/coordinator.py @@ -5,6 +5,8 @@ from __future__ import annotations from datetime import timedelta import logging +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -23,13 +25,21 @@ _LOGGER = logging.getLogger(__name__) class MinecraftServerCoordinator(DataUpdateCoordinator[MinecraftServerData]): """Minecraft Server data update coordinator.""" - def __init__(self, hass: HomeAssistant, name: str, api: MinecraftServer) -> None: + config_entry: ConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + api: MinecraftServer, + ) -> None: """Initialize coordinator instance.""" self._api = api super().__init__( hass=hass, - name=name, + name=config_entry.data[CONF_NAME], + config_entry=config_entry, logger=_LOGGER, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/minecraft_server/sensor.py b/homeassistant/components/minecraft_server/sensor.py index fae004a015e..50571123003 100644 --- a/homeassistant/components/minecraft_server/sensor.py +++ b/homeassistant/components/minecraft_server/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import SensorEntity, SensorEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TYPE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .api import MinecraftServerData, MinecraftServerType @@ -159,7 +159,7 @@ SENSOR_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Minecraft Server sensor platform.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/mjpeg/camera.py b/homeassistant/components/mjpeg/camera.py index dcb2eff2fd6..c60f1c4d760 100644 --- a/homeassistant/components/mjpeg/camera.py +++ b/homeassistant/components/mjpeg/camera.py @@ -27,7 +27,7 @@ from homeassistant.helpers.aiohttp_client import ( async_get_clientsession, ) from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.httpx_client import get_async_client from .const import CONF_MJPEG_URL, CONF_STILL_IMAGE_URL, DOMAIN, LOGGER @@ -39,7 +39,7 @@ BUFFER_SIZE = 102400 async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a MJPEG IP Camera based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/moat/sensor.py b/homeassistant/components/moat/sensor.py index 66edfbe91f2..e968577d789 100644 --- a/homeassistant/components/moat/sensor.py +++ b/homeassistant/components/moat/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -105,7 +105,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Moat BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/mobile_app/binary_sensor.py b/homeassistant/components/mobile_app/binary_sensor.py index e19e00b1277..8f8b8d97295 100644 --- a/homeassistant/components/mobile_app/binary_sensor.py +++ b/homeassistant/components/mobile_app/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.const import CONF_WEBHOOK_ID, STATE_ON from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_SENSOR_ATTRIBUTES, @@ -28,7 +28,7 @@ from .entity import MobileAppEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up mobile app binary sensor from a config entry.""" entities = [] diff --git a/homeassistant/components/mobile_app/device_tracker.py b/homeassistant/components/mobile_app/device_tracker.py index 7e84930e2e9..7e5a0a291b6 100644 --- a/homeassistant/components/mobile_app/device_tracker.py +++ b/homeassistant/components/mobile_app/device_tracker.py @@ -16,7 +16,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import ( @@ -33,7 +33,9 @@ ATTR_KEYS = (ATTR_ALTITUDE, ATTR_COURSE, ATTR_SPEED, ATTR_VERTICAL_ACCURACY) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Mobile app based off an entry.""" entity = MobileAppEntity(entry) diff --git a/homeassistant/components/mobile_app/sensor.py b/homeassistant/components/mobile_app/sensor.py index 06ab924aba2..8200ad1fccd 100644 --- a/homeassistant/components/mobile_app/sensor.py +++ b/homeassistant/components/mobile_app/sensor.py @@ -11,7 +11,7 @@ from homeassistant.const import CONF_WEBHOOK_ID, STATE_UNKNOWN, UnitOfTemperatur from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -36,7 +36,7 @@ from .webhook import _extract_sensor_unique_id async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up mobile app sensor from a config entry.""" entities = [] diff --git a/homeassistant/components/modem_callerid/button.py b/homeassistant/components/modem_callerid/button.py index 3cad9062be9..954a638818d 100644 --- a/homeassistant/components/modem_callerid/button.py +++ b/homeassistant/components/modem_callerid/button.py @@ -9,13 +9,15 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_KEY_API, DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Modem Caller ID sensor.""" api = hass.data[DOMAIN][entry.entry_id][DATA_KEY_API] diff --git a/homeassistant/components/modem_callerid/sensor.py b/homeassistant/components/modem_callerid/sensor.py index 00c821f3511..de8e4b2f73c 100644 --- a/homeassistant/components/modem_callerid/sensor.py +++ b/homeassistant/components/modem_callerid/sensor.py @@ -9,13 +9,15 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_IDLE from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CID, DATA_KEY_API, DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Modem Caller ID sensor.""" api = hass.data[DOMAIN][entry.entry_id][DATA_KEY_API] diff --git a/homeassistant/components/modern_forms/__init__.py b/homeassistant/components/modern_forms/__init__.py index ef2bbad70ce..901e3f431a1 100644 --- a/homeassistant/components/modern_forms/__init__.py +++ b/homeassistant/components/modern_forms/__init__.py @@ -9,7 +9,7 @@ from typing import Any, Concatenate from aiomodernforms import ModernFormsConnectionError, ModernFormsError from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, Platform +from homeassistant.const import Platform from homeassistant.core import HomeAssistant from .const import DOMAIN @@ -30,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a Modern Forms device from a config entry.""" # Create Modern Forms instance for this entry - coordinator = ModernFormsDataUpdateCoordinator(hass, host=entry.data[CONF_HOST]) + coordinator = ModernFormsDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {}) diff --git a/homeassistant/components/modern_forms/binary_sensor.py b/homeassistant/components/modern_forms/binary_sensor.py index ea903c580a4..2bba85f54d7 100644 --- a/homeassistant/components/modern_forms/binary_sensor.py +++ b/homeassistant/components/modern_forms/binary_sensor.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import CLEAR_TIMER, DOMAIN @@ -16,7 +16,7 @@ from .entity import ModernFormsDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Modern Forms binary sensors.""" coordinator: ModernFormsDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/modern_forms/coordinator.py b/homeassistant/components/modern_forms/coordinator.py index ecd928aa922..203ba54380d 100644 --- a/homeassistant/components/modern_forms/coordinator.py +++ b/homeassistant/components/modern_forms/coordinator.py @@ -8,6 +8,8 @@ import logging from aiomodernforms import ModernFormsDevice, ModernFormsError from aiomodernforms.models import Device as ModernFormsDeviceState +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -21,20 +23,22 @@ _LOGGER = logging.getLogger(__name__) class ModernFormsDataUpdateCoordinator(DataUpdateCoordinator[ModernFormsDeviceState]): """Class to manage fetching Modern Forms data from single endpoint.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - *, - host: str, + config_entry: ConfigEntry, ) -> None: """Initialize global Modern Forms data updater.""" self.modern_forms = ModernFormsDevice( - host, session=async_get_clientsession(hass) + config_entry.data[CONF_HOST], session=async_get_clientsession(hass) ) super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/modern_forms/fan.py b/homeassistant/components/modern_forms/fan.py index 988edcb60e5..26c69b28a5c 100644 --- a/homeassistant/components/modern_forms/fan.py +++ b/homeassistant/components/modern_forms/fan.py @@ -11,7 +11,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -35,7 +35,7 @@ from .entity import ModernFormsDeviceEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Modern Forms platform from config entry.""" diff --git a/homeassistant/components/modern_forms/light.py b/homeassistant/components/modern_forms/light.py index 2b53a414cea..6216efe3ff4 100644 --- a/homeassistant/components/modern_forms/light.py +++ b/homeassistant/components/modern_forms/light.py @@ -11,7 +11,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -36,7 +36,7 @@ BRIGHTNESS_RANGE = (1, 255) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Modern Forms platform from config entry.""" diff --git a/homeassistant/components/modern_forms/sensor.py b/homeassistant/components/modern_forms/sensor.py index 0f1e90cbe52..aa7d163cfdc 100644 --- a/homeassistant/components/modern_forms/sensor.py +++ b/homeassistant/components/modern_forms/sensor.py @@ -7,7 +7,7 @@ from datetime import datetime from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -19,7 +19,7 @@ from .entity import ModernFormsDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Modern Forms sensor based on a config entry.""" coordinator: ModernFormsDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/modern_forms/switch.py b/homeassistant/components/modern_forms/switch.py index f2e8b1b705c..89a5b779d74 100644 --- a/homeassistant/components/modern_forms/switch.py +++ b/homeassistant/components/modern_forms/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import modernforms_exception_handler from .const import DOMAIN @@ -18,7 +18,7 @@ from .entity import ModernFormsDeviceEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Modern Forms switch based on a config entry.""" coordinator: ModernFormsDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/moehlenhoff_alpha2/__init__.py b/homeassistant/components/moehlenhoff_alpha2/__init__.py index 244e3bc701b..b015f9a09dd 100644 --- a/homeassistant/components/moehlenhoff_alpha2/__init__.py +++ b/homeassistant/components/moehlenhoff_alpha2/__init__.py @@ -17,7 +17,7 @@ PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CLIMATE, Platform async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" base = Alpha2Base(entry.data[CONF_HOST]) - coordinator = Alpha2BaseCoordinator(hass, base) + coordinator = Alpha2BaseCoordinator(hass, entry, base) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/moehlenhoff_alpha2/binary_sensor.py b/homeassistant/components/moehlenhoff_alpha2/binary_sensor.py index 1e7018ff1c7..a7479aef5e8 100644 --- a/homeassistant/components/moehlenhoff_alpha2/binary_sensor.py +++ b/homeassistant/components/moehlenhoff_alpha2/binary_sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -17,7 +17,7 @@ from .coordinator import Alpha2BaseCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Alpha2 sensor entities from a config_entry.""" diff --git a/homeassistant/components/moehlenhoff_alpha2/button.py b/homeassistant/components/moehlenhoff_alpha2/button.py index c7ac574724a..57f9d0e31a2 100644 --- a/homeassistant/components/moehlenhoff_alpha2/button.py +++ b/homeassistant/components/moehlenhoff_alpha2/button.py @@ -4,7 +4,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -15,7 +15,7 @@ from .coordinator import Alpha2BaseCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Alpha2 button entities.""" diff --git a/homeassistant/components/moehlenhoff_alpha2/climate.py b/homeassistant/components/moehlenhoff_alpha2/climate.py index 7c24dad4469..85d5939049e 100644 --- a/homeassistant/components/moehlenhoff_alpha2/climate.py +++ b/homeassistant/components/moehlenhoff_alpha2/climate.py @@ -12,7 +12,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, PRESET_AUTO, PRESET_DAY, PRESET_NIGHT @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Alpha2Climate entities from a config_entry.""" diff --git a/homeassistant/components/moehlenhoff_alpha2/coordinator.py b/homeassistant/components/moehlenhoff_alpha2/coordinator.py index 2bac4b49575..50c2f9a5297 100644 --- a/homeassistant/components/moehlenhoff_alpha2/coordinator.py +++ b/homeassistant/components/moehlenhoff_alpha2/coordinator.py @@ -8,6 +8,7 @@ import logging import aiohttp from moehlenhoff_alpha2 import Alpha2Base +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -20,12 +21,17 @@ UPDATE_INTERVAL = timedelta(seconds=60) class Alpha2BaseCoordinator(DataUpdateCoordinator[dict[str, dict]]): """Keep the base instance in one place and centralize the update.""" - def __init__(self, hass: HomeAssistant, base: Alpha2Base) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, base: Alpha2Base + ) -> None: """Initialize Alpha2Base data updater.""" self.base = base super().__init__( hass=hass, logger=_LOGGER, + config_entry=config_entry, name="alpha2_base", update_interval=UPDATE_INTERVAL, ) diff --git a/homeassistant/components/moehlenhoff_alpha2/sensor.py b/homeassistant/components/moehlenhoff_alpha2/sensor.py index 5286257ff61..306e80e54d3 100644 --- a/homeassistant/components/moehlenhoff_alpha2/sensor.py +++ b/homeassistant/components/moehlenhoff_alpha2/sensor.py @@ -4,7 +4,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -14,7 +14,7 @@ from .coordinator import Alpha2BaseCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Alpha2 sensor entities from a config_entry.""" diff --git a/homeassistant/components/mold_indicator/sensor.py b/homeassistant/components/mold_indicator/sensor.py index 750ddce8513..451cc65fb55 100644 --- a/homeassistant/components/mold_indicator/sensor.py +++ b/homeassistant/components/mold_indicator/sensor.py @@ -36,7 +36,10 @@ from homeassistant.core import ( ) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device import async_device_info_to_link_from_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util.unit_conversion import TemperatureConverter @@ -105,7 +108,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Mold indicator sensor entry.""" name: str = entry.options[CONF_NAME] diff --git a/homeassistant/components/monarch_money/__init__.py b/homeassistant/components/monarch_money/__init__.py index 5f9aba7dd07..8b7cfa6aa5b 100644 --- a/homeassistant/components/monarch_money/__init__.py +++ b/homeassistant/components/monarch_money/__init__.py @@ -4,13 +4,10 @@ from __future__ import annotations from typedmonarchmoney import TypedMonarchMoney -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TOKEN, Platform from homeassistant.core import HomeAssistant -from .coordinator import MonarchMoneyDataUpdateCoordinator - -type MonarchMoneyConfigEntry = ConfigEntry[MonarchMoneyDataUpdateCoordinator] +from .coordinator import MonarchMoneyConfigEntry, MonarchMoneyDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] @@ -21,7 +18,7 @@ async def async_setup_entry( """Set up Monarch Money from a config entry.""" monarch_client = TypedMonarchMoney(token=entry.data.get(CONF_TOKEN)) - mm_coordinator = MonarchMoneyDataUpdateCoordinator(hass, monarch_client) + mm_coordinator = MonarchMoneyDataUpdateCoordinator(hass, entry, monarch_client) await mm_coordinator.async_config_entry_first_refresh() entry.runtime_data = mm_coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/monarch_money/coordinator.py b/homeassistant/components/monarch_money/coordinator.py index 3e689c48e91..7f3dac9419f 100644 --- a/homeassistant/components/monarch_money/coordinator.py +++ b/homeassistant/components/monarch_money/coordinator.py @@ -30,21 +30,26 @@ class MonarchData: cashflow_summary: MonarchCashflowSummary +type MonarchMoneyConfigEntry = ConfigEntry[MonarchMoneyDataUpdateCoordinator] + + class MonarchMoneyDataUpdateCoordinator(DataUpdateCoordinator[MonarchData]): """Data update coordinator for Monarch Money.""" - config_entry: ConfigEntry + config_entry: MonarchMoneyConfigEntry subscription_id: str def __init__( self, hass: HomeAssistant, + config_entry: MonarchMoneyConfigEntry, client: TypedMonarchMoney, ) -> None: """Initialize the coordinator.""" super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name="monarchmoney", update_interval=timedelta(hours=4), ) diff --git a/homeassistant/components/monarch_money/sensor.py b/homeassistant/components/monarch_money/sensor.py index fe7c728cf41..1597d9820a1 100644 --- a/homeassistant/components/monarch_money/sensor.py +++ b/homeassistant/components/monarch_money/sensor.py @@ -14,10 +14,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CURRENCY_DOLLAR, PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import MonarchMoneyConfigEntry +from .coordinator import MonarchMoneyConfigEntry from .entity import MonarchMoneyAccountEntity, MonarchMoneyCashFlowEntity @@ -110,7 +110,7 @@ MONARCH_CASHFLOW_SENSORS: tuple[MonarchMoneyCashflowSensorEntityDescription, ... async def async_setup_entry( hass: HomeAssistant, config_entry: MonarchMoneyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Monarch Money sensors for config entries.""" mm_coordinator = config_entry.runtime_data diff --git a/homeassistant/components/monoprice/media_player.py b/homeassistant/components/monoprice/media_player.py index 2dde0832440..9d678c16874 100644 --- a/homeassistant/components/monoprice/media_player.py +++ b/homeassistant/components/monoprice/media_player.py @@ -16,7 +16,7 @@ from homeassistant.const import CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform, service from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_SOURCES, @@ -58,7 +58,7 @@ def _get_sources(config_entry): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Monoprice 6-zone amplifier platform.""" port = config_entry.data[CONF_PORT] diff --git a/homeassistant/components/monzo/__init__.py b/homeassistant/components/monzo/__init__.py index a88082b2ce6..662cfecd2e9 100644 --- a/homeassistant/components/monzo/__init__.py +++ b/homeassistant/components/monzo/__init__.py @@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: external_api = AuthenticatedMonzoAPI(async_get_clientsession(hass), session) - coordinator = MonzoCoordinator(hass, external_api) + coordinator = MonzoCoordinator(hass, entry, external_api) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/monzo/coordinator.py b/homeassistant/components/monzo/coordinator.py index caac551f986..06c751a23e0 100644 --- a/homeassistant/components/monzo/coordinator.py +++ b/homeassistant/components/monzo/coordinator.py @@ -8,6 +8,7 @@ from typing import Any from monzopy import AuthorisationExpiredError, InvalidMonzoAPIResponseError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -29,11 +30,16 @@ class MonzoData: class MonzoCoordinator(DataUpdateCoordinator[MonzoData]): """Class to manage fetching Monzo data from the API.""" - def __init__(self, hass: HomeAssistant, api: AuthenticatedMonzoAPI) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: AuthenticatedMonzoAPI + ) -> None: """Initialize.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(minutes=1), ) diff --git a/homeassistant/components/monzo/sensor.py b/homeassistant/components/monzo/sensor.py index 41b97d90452..0b6ab2b70a5 100644 --- a/homeassistant/components/monzo/sensor.py +++ b/homeassistant/components/monzo/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import MonzoCoordinator @@ -65,7 +65,7 @@ MODEL_POT = "Pot" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator: MonzoCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/moon/sensor.py b/homeassistant/components/moon/sensor.py index 09048579859..12d0ff3ed41 100644 --- a/homeassistant/components/moon/sensor.py +++ b/homeassistant/components/moon/sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -26,7 +26,7 @@ STATE_WAXING_GIBBOUS = "waxing_gibbous" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config_entry.""" async_add_entities([MoonSensorEntity(entry)], True) diff --git a/homeassistant/components/mopeka/sensor.py b/homeassistant/components/mopeka/sensor.py index 0f67efaea1e..53c93f771f2 100644 --- a/homeassistant/components/mopeka/sensor.py +++ b/homeassistant/components/mopeka/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import MopekaConfigEntry @@ -115,7 +115,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: MopekaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Mopeka BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/motion_blinds/__init__.py b/homeassistant/components/motion_blinds/__init__.py index 182ea310029..fa1664353e1 100644 --- a/homeassistant/components/motion_blinds/__init__.py +++ b/homeassistant/components/motion_blinds/__init__.py @@ -1,7 +1,6 @@ """The motion_blinds component.""" import asyncio -from datetime import timedelta import logging from typing import TYPE_CHECKING @@ -25,7 +24,6 @@ from .const import ( KEY_SETUP_LOCK, KEY_UNSUB_STOP, PLATFORMS, - UPDATE_INTERVAL, ) from .coordinator import DataUpdateCoordinatorMotionBlinds from .gateway import ConnectMotionGateway @@ -94,13 +92,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: } coordinator = DataUpdateCoordinatorMotionBlinds( - hass, - _LOGGER, - coordinator_info, - # Name of the data. For logging purposes. - name=entry.title, - # Polling interval. Will only be polled if there are subscribers. - update_interval=timedelta(seconds=UPDATE_INTERVAL), + hass, entry, _LOGGER, coordinator_info ) # Fetch initial data so we have data when entities subscribe diff --git a/homeassistant/components/motion_blinds/button.py b/homeassistant/components/motion_blinds/button.py index 89841bf8fd4..09f29e09c70 100644 --- a/homeassistant/components/motion_blinds/button.py +++ b/homeassistant/components/motion_blinds/button.py @@ -8,7 +8,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, KEY_COORDINATOR, KEY_GATEWAY from .coordinator import DataUpdateCoordinatorMotionBlinds @@ -18,7 +18,7 @@ from .entity import MotionCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Motionblinds.""" entities: list[ButtonEntity] = [] diff --git a/homeassistant/components/motion_blinds/coordinator.py b/homeassistant/components/motion_blinds/coordinator.py index b2abd205ce5..79e26e5aed4 100644 --- a/homeassistant/components/motion_blinds/coordinator.py +++ b/homeassistant/components/motion_blinds/coordinator.py @@ -7,6 +7,7 @@ from typing import Any from motionblinds import DEVICE_TYPES_WIFI, ParseException +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -25,21 +26,22 @@ _LOGGER = logging.getLogger(__name__) class DataUpdateCoordinatorMotionBlinds(DataUpdateCoordinator): """Class to manage fetching data from single endpoint.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, logger: logging.Logger, coordinator_info: dict[str, Any], - *, - name: str, - update_interval: timedelta, ) -> None: """Initialize global data updater.""" super().__init__( hass, logger, - name=name, - update_interval=update_interval, + config_entry=config_entry, + name=config_entry.title, + update_interval=timedelta(seconds=UPDATE_INTERVAL), ) self.api_lock = coordinator_info[KEY_API_LOCK] diff --git a/homeassistant/components/motion_blinds/cover.py b/homeassistant/components/motion_blinds/cover.py index 1ea3a6ed9d6..dbf43e3d30f 100644 --- a/homeassistant/components/motion_blinds/cover.py +++ b/homeassistant/components/motion_blinds/cover.py @@ -18,7 +18,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from .const import ( @@ -83,7 +83,7 @@ SET_ABSOLUTE_POSITION_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Motion Blind from a config entry.""" entities: list[MotionBaseDevice] = [] diff --git a/homeassistant/components/motion_blinds/sensor.py b/homeassistant/components/motion_blinds/sensor.py index 6418cebda0c..60d283aa0b6 100644 --- a/homeassistant/components/motion_blinds/sensor.py +++ b/homeassistant/components/motion_blinds/sensor.py @@ -15,7 +15,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, KEY_COORDINATOR, KEY_GATEWAY from .entity import MotionCoordinatorEntity @@ -26,7 +26,7 @@ ATTR_BATTERY_VOLTAGE = "battery_voltage" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Motionblinds.""" entities: list[SensorEntity] = [] diff --git a/homeassistant/components/motionblinds_ble/button.py b/homeassistant/components/motionblinds_ble/button.py index a099276cd85..12fb6c7a513 100644 --- a/homeassistant/components/motionblinds_ble/button.py +++ b/homeassistant/components/motionblinds_ble/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_CONNECT, ATTR_DISCONNECT, ATTR_FAVORITE, CONF_MAC_CODE, DOMAIN from .entity import MotionblindsBLEEntity @@ -53,7 +53,9 @@ BUTTON_TYPES: list[MotionblindsBLEButtonEntityDescription] = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button entities based on a config entry.""" diff --git a/homeassistant/components/motionblinds_ble/cover.py b/homeassistant/components/motionblinds_ble/cover.py index afeeb5b0d70..beaee8598b5 100644 --- a/homeassistant/components/motionblinds_ble/cover.py +++ b/homeassistant/components/motionblinds_ble/cover.py @@ -19,7 +19,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_BLIND_TYPE, CONF_MAC_CODE, DOMAIN, ICON_VERTICAL_BLIND from .entity import MotionblindsBLEEntity @@ -61,7 +61,9 @@ BLIND_TYPE_TO_ENTITY_DESCRIPTION: dict[str, MotionblindsBLECoverEntityDescriptio async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cover entity based on a config entry.""" diff --git a/homeassistant/components/motionblinds_ble/select.py b/homeassistant/components/motionblinds_ble/select.py index c297c887910..976f51a0a0f 100644 --- a/homeassistant/components/motionblinds_ble/select.py +++ b/homeassistant/components/motionblinds_ble/select.py @@ -11,7 +11,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_SPEED, CONF_MAC_CODE, DOMAIN from .entity import MotionblindsBLEEntity @@ -32,7 +32,9 @@ SELECT_TYPES: dict[str, SelectEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select entities based on a config entry.""" diff --git a/homeassistant/components/motionblinds_ble/sensor.py b/homeassistant/components/motionblinds_ble/sensor.py index 740a0509a9e..8993a3b1cd5 100644 --- a/homeassistant/components/motionblinds_ble/sensor.py +++ b/homeassistant/components/motionblinds_ble/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -92,7 +92,9 @@ SENSORS: tuple[MotionblindsBLESensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities based on a config entry.""" diff --git a/homeassistant/components/motioneye/camera.py b/homeassistant/components/motioneye/camera.py index df4c321037e..159956277a8 100644 --- a/homeassistant/components/motioneye/camera.py +++ b/homeassistant/components/motioneye/camera.py @@ -42,7 +42,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import get_camera_from_cameras, is_acceptable_camera, listen_for_new_cameras @@ -93,7 +93,9 @@ SCHEMA_SERVICE_SET_TEXT = vol.Schema( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up motionEye from a config entry.""" entry_data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/motioneye/sensor.py b/homeassistant/components/motioneye/sensor.py index e0113544848..c160b77c16a 100644 --- a/homeassistant/components/motioneye/sensor.py +++ b/homeassistant/components/motioneye/sensor.py @@ -12,7 +12,7 @@ from motioneye_client.const import KEY_ACTIONS from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -24,7 +24,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up motionEye from a config entry.""" entry_data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/motioneye/switch.py b/homeassistant/components/motioneye/switch.py index 9d704f17740..89d3b8a8727 100644 --- a/homeassistant/components/motioneye/switch.py +++ b/homeassistant/components/motioneye/switch.py @@ -19,7 +19,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import get_camera_from_cameras, listen_for_new_cameras @@ -67,7 +67,9 @@ MOTIONEYE_SWITCHES = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up motionEye from a config entry.""" entry_data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/motionmount/binary_sensor.py b/homeassistant/components/motionmount/binary_sensor.py index f19af67e198..c9d76ebb8d5 100644 --- a/homeassistant/components/motionmount/binary_sensor.py +++ b/homeassistant/components/motionmount/binary_sensor.py @@ -7,16 +7,18 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MotionMountConfigEntry from .entity import MotionMountEntity +PARALLEL_UPDATES = 0 + async def async_setup_entry( hass: HomeAssistant, entry: MotionMountConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vogel's MotionMount from a config entry.""" mm = entry.runtime_data diff --git a/homeassistant/components/motionmount/number.py b/homeassistant/components/motionmount/number.py index 6305820174f..3e2c1b067aa 100644 --- a/homeassistant/components/motionmount/number.py +++ b/homeassistant/components/motionmount/number.py @@ -8,17 +8,19 @@ from homeassistant.components.number import NumberEntity from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MotionMountConfigEntry from .const import DOMAIN from .entity import MotionMountEntity +PARALLEL_UPDATES = 0 + async def async_setup_entry( hass: HomeAssistant, entry: MotionMountConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vogel's MotionMount from a config entry.""" mm = entry.runtime_data diff --git a/homeassistant/components/motionmount/quality_scale.yaml b/homeassistant/components/motionmount/quality_scale.yaml index e4a6a04ceeb..f8fee8739e9 100644 --- a/homeassistant/components/motionmount/quality_scale.yaml +++ b/homeassistant/components/motionmount/quality_scale.yaml @@ -37,7 +37,7 @@ rules: entity-unavailable: done integration-owner: done log-when-unavailable: done - parallel-updates: todo + parallel-updates: done reauthentication-flow: done test-coverage: todo diff --git a/homeassistant/components/motionmount/select.py b/homeassistant/components/motionmount/select.py index 31c5056b91f..a8fcc84f2ec 100644 --- a/homeassistant/components/motionmount/select.py +++ b/homeassistant/components/motionmount/select.py @@ -9,7 +9,7 @@ import motionmount from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MotionMountConfigEntry from .const import DOMAIN, WALL_PRESET_NAME @@ -17,12 +17,13 @@ from .entity import MotionMountEntity _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = timedelta(seconds=60) +PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: MotionMountConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vogel's MotionMount from a config entry.""" mm = entry.runtime_data diff --git a/homeassistant/components/motionmount/sensor.py b/homeassistant/components/motionmount/sensor.py index 685c3ebf932..4950e5d6662 100644 --- a/homeassistant/components/motionmount/sensor.py +++ b/homeassistant/components/motionmount/sensor.py @@ -7,11 +7,13 @@ from motionmount import MotionMountSystemError from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MotionMountConfigEntry from .entity import MotionMountEntity +PARALLEL_UPDATES = 0 + ERROR_MESSAGES: Final = { MotionMountSystemError.MotorError: "motor", MotionMountSystemError.ObstructionDetected: "obstruction", @@ -24,7 +26,7 @@ ERROR_MESSAGES: Final = { async def async_setup_entry( hass: HomeAssistant, entry: MotionMountConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vogel's MotionMount from a config entry.""" mm = entry.runtime_data diff --git a/homeassistant/components/mpd/media_player.py b/homeassistant/components/mpd/media_player.py index db3901016f7..14b69e941b7 100644 --- a/homeassistant/components/mpd/media_player.py +++ b/homeassistant/components/mpd/media_player.py @@ -31,7 +31,7 @@ from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle, dt as dt_util from .const import DOMAIN, LOGGER @@ -68,7 +68,9 @@ PLATFORM_SCHEMA = MEDIA_PLAYER_PLATFORM_SCHEMA.extend( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up media player from config_entry.""" diff --git a/homeassistant/components/mqtt/alarm_control_panel.py b/homeassistant/components/mqtt/alarm_control_panel.py index 7bdc13d0522..64b1a6b05fa 100644 --- a/homeassistant/components/mqtt/alarm_control_panel.py +++ b/homeassistant/components/mqtt/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_CODE, CONF_NAME, CONF_VALUE_TEMPLATE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from . import subscription @@ -115,7 +115,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT alarm control panel through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/binary_sensor.py b/homeassistant/components/mqtt/binary_sensor.py index d736123eae8..a1e146d4e36 100644 --- a/homeassistant/components/mqtt/binary_sensor.py +++ b/homeassistant/components/mqtt/binary_sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers import config_validation as cv, event as evt -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType @@ -69,7 +69,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT binary sensor through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/button.py b/homeassistant/components/mqtt/button.py index b6056c2efd9..5b2bcc8920f 100644 --- a/homeassistant/components/mqtt/button.py +++ b/homeassistant/components/mqtt/button.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .config import DEFAULT_RETAIN, MQTT_BASE_SCHEMA @@ -43,7 +43,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT button through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/camera.py b/homeassistant/components/mqtt/camera.py index 88fabad0446..d3615edcbba 100644 --- a/homeassistant/components/mqtt/camera.py +++ b/homeassistant/components/mqtt/camera.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import subscription @@ -60,7 +60,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT camera through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/climate.py b/homeassistant/components/mqtt/climate.py index 12619609f64..a65eb18e3f1 100644 --- a/homeassistant/components/mqtt/climate.py +++ b/homeassistant/components/mqtt/climate.py @@ -45,7 +45,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -350,7 +350,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT climate through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/cover.py b/homeassistant/components/mqtt/cover.py index 626e0cef64a..c93fdd9c760 100644 --- a/homeassistant/components/mqtt/cover.py +++ b/homeassistant/components/mqtt/cover.py @@ -30,7 +30,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads @@ -220,7 +220,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT cover through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/device_tracker.py b/homeassistant/components/mqtt/device_tracker.py index d3ad57ef43d..4017245cf51 100644 --- a/homeassistant/components/mqtt/device_tracker.py +++ b/homeassistant/components/mqtt/device_tracker.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -79,7 +79,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT event through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/event.py b/homeassistant/components/mqtt/event.py index 5855f94dad7..aef21838d59 100644 --- a/homeassistant/components/mqtt/event.py +++ b/homeassistant/components/mqtt/event.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME, CONF_VALUE_TEMPLATE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads_object @@ -73,7 +73,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT event through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/fan.py b/homeassistant/components/mqtt/fan.py index d8e96eb2734..3fac4d4ffe0 100644 --- a/homeassistant/components/mqtt/fan.py +++ b/homeassistant/components/mqtt/fan.py @@ -28,7 +28,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -190,7 +190,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT fan through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/humidifier.py b/homeassistant/components/mqtt/humidifier.py index bffe0ec1420..07ddcddb13a 100644 --- a/homeassistant/components/mqtt/humidifier.py +++ b/homeassistant/components/mqtt/humidifier.py @@ -31,7 +31,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -183,7 +183,7 @@ TOPICS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT humidifier through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/image.py b/homeassistant/components/mqtt/image.py index 4b7b2d783d2..a668608dd55 100644 --- a/homeassistant/components/mqtt/image.py +++ b/homeassistant/components/mqtt/image.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, VolSchemaType @@ -82,7 +82,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT image through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/lawn_mower.py b/homeassistant/components/mqtt/lawn_mower.py index 87577c4b4d9..7727efcf04d 100644 --- a/homeassistant/components/mqtt/lawn_mower.py +++ b/homeassistant/components/mqtt/lawn_mower.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -80,7 +80,7 @@ DISCOVERY_SCHEMA = vol.All(PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EX async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT lawn mower through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/light/__init__.py b/homeassistant/components/mqtt/light/__init__.py index 328f80cb5ea..3ffad9226be 100644 --- a/homeassistant/components/mqtt/light/__init__.py +++ b/homeassistant/components/mqtt/light/__init__.py @@ -9,7 +9,7 @@ import voluptuous as vol from homeassistant.components import light from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, VolSchemaType from ..entity import async_setup_entity_entry_helper @@ -69,7 +69,7 @@ PLATFORM_SCHEMA_MODERN = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT lights through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/lock.py b/homeassistant/components/mqtt/lock.py index 895bfba3560..727e689798e 100644 --- a/homeassistant/components/mqtt/lock.py +++ b/homeassistant/components/mqtt/lock.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, TemplateVarsType @@ -116,7 +116,7 @@ STATE_CONFIG_KEYS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT lock through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/notify.py b/homeassistant/components/mqtt/notify.py index 7e0a7fd4dd8..0b6dbce38b4 100644 --- a/homeassistant/components/mqtt/notify.py +++ b/homeassistant/components/mqtt/notify.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .config import DEFAULT_RETAIN, MQTT_BASE_SCHEMA @@ -39,7 +39,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT notify through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/number.py b/homeassistant/components/mqtt/number.py index 9b47a3ad23a..5ee93cfba07 100644 --- a/homeassistant/components/mqtt/number.py +++ b/homeassistant/components/mqtt/number.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -109,7 +109,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT number through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/scene.py b/homeassistant/components/mqtt/scene.py index c6651510a36..12f680b6e12 100644 --- a/homeassistant/components/mqtt/scene.py +++ b/homeassistant/components/mqtt/scene.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_PAYLOAD_ON from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType from .config import MQTT_BASE_SCHEMA @@ -43,7 +43,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT scene through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/select.py b/homeassistant/components/mqtt/select.py index 55d56ecd774..1b3ea1a7c44 100644 --- a/homeassistant/components/mqtt/select.py +++ b/homeassistant/components/mqtt/select.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -63,7 +63,7 @@ DISCOVERY_SCHEMA = vol.All(PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EX async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT select through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/sensor.py b/homeassistant/components/mqtt/sensor.py index ad84ebb09a3..3e8a4fef0fa 100644 --- a/homeassistant/components/mqtt/sensor.py +++ b/homeassistant/components/mqtt/sensor.py @@ -31,7 +31,7 @@ from homeassistant.const import ( ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -124,7 +124,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT sensor through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/siren.py b/homeassistant/components/mqtt/siren.py index 5e3ca76e722..48ab4676dea 100644 --- a/homeassistant/components/mqtt/siren.py +++ b/homeassistant/components/mqtt/siren.py @@ -29,7 +29,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.json import json_dumps from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.template import Template @@ -113,7 +113,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT siren through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/switch.py b/homeassistant/components/mqtt/switch.py index a305fa83485..f6996fc77ce 100644 --- a/homeassistant/components/mqtt/switch.py +++ b/homeassistant/components/mqtt/switch.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType @@ -70,7 +70,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT switch through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/text.py b/homeassistant/components/mqtt/text.py index b4ed33a7730..d306fc0819b 100644 --- a/homeassistant/components/mqtt/text.py +++ b/homeassistant/components/mqtt/text.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.service_info.mqtt import ReceivePayloadType from homeassistant.helpers.typing import ConfigType, VolSchemaType @@ -95,7 +95,7 @@ PLATFORM_SCHEMA_MODERN = vol.All(_PLATFORM_SCHEMA_BASE, valid_text_size_configur async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT text through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/update.py b/homeassistant/components/mqtt/update.py index 59742d24b60..c4916b5010c 100644 --- a/homeassistant/components/mqtt/update.py +++ b/homeassistant/components/mqtt/update.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME, CONF_VALUE_TEMPLATE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType, VolSchemaType from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads @@ -82,7 +82,7 @@ MQTT_JSON_UPDATE_SCHEMA = vol.Schema( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT update entity through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/vacuum.py b/homeassistant/components/mqtt/vacuum.py index ae6b25eff14..f1d2eb34fe1 100644 --- a/homeassistant/components/mqtt/vacuum.py +++ b/homeassistant/components/mqtt/vacuum.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_SUPPORTED_FEATURES, CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.json import json_dumps from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, VolSchemaType from homeassistant.util.json import json_loads_object @@ -175,7 +175,7 @@ DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.ALLOW_EXTRA) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT vacuum through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/valve.py b/homeassistant/components/mqtt/valve.py index b380199332b..53f7d06429e 100644 --- a/homeassistant/components/mqtt/valve.py +++ b/homeassistant/components/mqtt/valve.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, VolSchemaType from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads from homeassistant.util.percentage import ( @@ -136,7 +136,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT valve through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mqtt/water_heater.py b/homeassistant/components/mqtt/water_heater.py index 967eceac326..31d4f0fe30e 100644 --- a/homeassistant/components/mqtt/water_heater.py +++ b/homeassistant/components/mqtt/water_heater.py @@ -36,7 +36,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, VolSchemaType from homeassistant.util.unit_conversion import TemperatureConverter @@ -166,7 +166,7 @@ DISCOVERY_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MQTT water heater device through YAML and through MQTT discovery.""" async_setup_entity_entry_helper( diff --git a/homeassistant/components/mullvad/binary_sensor.py b/homeassistant/components/mullvad/binary_sensor.py index 2e649d9a586..ad488058025 100644 --- a/homeassistant/components/mullvad/binary_sensor.py +++ b/homeassistant/components/mullvad/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -28,7 +28,7 @@ BINARY_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = hass.data[DOMAIN] diff --git a/homeassistant/components/music_assistant/media_player.py b/homeassistant/components/music_assistant/media_player.py index 4a7e20046b2..5621b5eb562 100644 --- a/homeassistant/components/music_assistant/media_player.py +++ b/homeassistant/components/music_assistant/media_player.py @@ -41,7 +41,7 @@ from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.util.dt import utc_from_timestamp @@ -137,7 +137,7 @@ def catch_musicassistant_error[_R, **P]( async def async_setup_entry( hass: HomeAssistant, entry: MusicAssistantConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Music Assistant MediaPlayer(s) from Config Entry.""" mass = entry.runtime_data.mass diff --git a/homeassistant/components/mutesync/binary_sensor.py b/homeassistant/components/mutesync/binary_sensor.py index 87bf246f4e0..7a9025762ef 100644 --- a/homeassistant/components/mutesync/binary_sensor.py +++ b/homeassistant/components/mutesync/binary_sensor.py @@ -5,7 +5,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import update_coordinator from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -18,7 +18,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the mütesync button.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/mysensors/binary_sensor.py b/homeassistant/components/mysensors/binary_sensor.py index 54f7036b79c..d42b2194315 100644 --- a/homeassistant/components/mysensors/binary_sensor.py +++ b/homeassistant/components/mysensors/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo @@ -71,7 +71,7 @@ SENSORS: dict[str, MySensorsBinarySensorDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/climate.py b/homeassistant/components/mysensors/climate.py index 23b7c47ebf3..d1504f3afab 100644 --- a/homeassistant/components/mysensors/climate.py +++ b/homeassistant/components/mysensors/climate.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import METRIC_SYSTEM from . import setup_mysensors_platform @@ -43,7 +43,7 @@ OPERATION_LIST = [HVACMode.OFF, HVACMode.AUTO, HVACMode.COOL, HVACMode.HEAT] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/cover.py b/homeassistant/components/mysensors/cover.py index 808589b9022..14e6ff6dc15 100644 --- a/homeassistant/components/mysensors/cover.py +++ b/homeassistant/components/mysensors/cover.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo @@ -31,7 +31,7 @@ class CoverState(Enum): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/device_tracker.py b/homeassistant/components/mysensors/device_tracker.py index 5abe6a64e2d..56d8b2f5923 100644 --- a/homeassistant/components/mysensors/device_tracker.py +++ b/homeassistant/components/mysensors/device_tracker.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo @@ -18,7 +18,7 @@ from .helpers import on_unload async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/light.py b/homeassistant/components/mysensors/light.py index 87f60174cab..9e4054ca3d0 100644 --- a/homeassistant/components/mysensors/light.py +++ b/homeassistant/components/mysensors/light.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.color import rgb_hex_to_rgb_list from . import setup_mysensors_platform @@ -27,7 +27,7 @@ from .helpers import on_unload async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" device_class_map: dict[SensorType, type[MySensorsChildEntity]] = { diff --git a/homeassistant/components/mysensors/remote.py b/homeassistant/components/mysensors/remote.py index 1a4f6fdaa90..ada801f92ab 100644 --- a/homeassistant/components/mysensors/remote.py +++ b/homeassistant/components/mysensors/remote.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo @@ -25,7 +25,7 @@ from .helpers import on_unload async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/sensor.py b/homeassistant/components/mysensors/sensor.py index eec3c6bcd79..33f3d6afaf4 100644 --- a/homeassistant/components/mysensors/sensor.py +++ b/homeassistant/components/mysensors/sensor.py @@ -35,7 +35,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import METRIC_SYSTEM from . import setup_mysensors_platform @@ -210,7 +210,7 @@ SENSORS: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mysensors/switch.py b/homeassistant/components/mysensors/switch.py index 4eabf6374f1..52207c21f77 100644 --- a/homeassistant/components/mysensors/switch.py +++ b/homeassistant/components/mysensors/switch.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo, SensorType @@ -20,7 +20,7 @@ from .helpers import on_unload async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" device_class_map: dict[SensorType, type[MySensorsSwitch]] = { diff --git a/homeassistant/components/mysensors/text.py b/homeassistant/components/mysensors/text.py index 4edb5ccdbd8..8eff7a255e7 100644 --- a/homeassistant/components/mysensors/text.py +++ b/homeassistant/components/mysensors/text.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import setup_mysensors_platform from .const import MYSENSORS_DISCOVERY, DiscoveryInfo @@ -18,7 +18,7 @@ from .helpers import on_unload async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up this platform for a specific ConfigEntry(==Gateway).""" diff --git a/homeassistant/components/mystrom/light.py b/homeassistant/components/mystrom/light.py index 5dabb609437..3942f601a20 100644 --- a/homeassistant/components/mystrom/light.py +++ b/homeassistant/components/mystrom/light.py @@ -18,7 +18,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, MANUFACTURER @@ -31,7 +31,9 @@ EFFECT_SUNRISE = "sunrise" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the myStrom entities.""" info = hass.data[DOMAIN][entry.entry_id].info diff --git a/homeassistant/components/mystrom/sensor.py b/homeassistant/components/mystrom/sensor.py index 2c35d35dad6..bd5c9b923a2 100644 --- a/homeassistant/components/mystrom/sensor.py +++ b/homeassistant/components/mystrom/sensor.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPower, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, MANUFACTURER @@ -55,7 +55,9 @@ SENSOR_TYPES: tuple[MyStromSwitchSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the myStrom entities.""" device: MyStromSwitch = hass.data[DOMAIN][entry.entry_id].device diff --git a/homeassistant/components/mystrom/switch.py b/homeassistant/components/mystrom/switch.py index af135027aac..f626656a4e3 100644 --- a/homeassistant/components/mystrom/switch.py +++ b/homeassistant/components/mystrom/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo, format_mac -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, MANUFACTURER @@ -21,7 +21,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the myStrom entities.""" device = hass.data[DOMAIN][entry.entry_id].device diff --git a/homeassistant/components/myuplink/__init__.py b/homeassistant/components/myuplink/__init__.py index 5ad114e973e..407e4da5475 100644 --- a/homeassistant/components/myuplink/__init__.py +++ b/homeassistant/components/myuplink/__init__.py @@ -9,7 +9,6 @@ from aiohttp import ClientError, ClientResponseError import jwt from myuplink import MyUplinkAPI, get_manufacturer, get_model, get_system_name -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -22,7 +21,7 @@ from homeassistant.helpers.device_registry import DeviceEntry from .api import AsyncConfigEntryAuth from .const import DOMAIN, OAUTH2_SCOPES -from .coordinator import MyUplinkDataCoordinator +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator _LOGGER = logging.getLogger(__name__) @@ -35,8 +34,6 @@ PLATFORMS: list[Platform] = [ Platform.UPDATE, ] -type MyUplinkConfigEntry = ConfigEntry[MyUplinkDataCoordinator] - async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry @@ -77,7 +74,7 @@ async def async_setup_entry( # Setup MyUplinkAPI and coordinator for data fetch api = MyUplinkAPI(auth) - coordinator = MyUplinkDataCoordinator(hass, api) + coordinator = MyUplinkDataCoordinator(hass, config_entry, api) await coordinator.async_config_entry_first_refresh() config_entry.runtime_data = coordinator diff --git a/homeassistant/components/myuplink/binary_sensor.py b/homeassistant/components/myuplink/binary_sensor.py index d903c7cbfae..785a7ff4532 100644 --- a/homeassistant/components/myuplink/binary_sensor.py +++ b/homeassistant/components/myuplink/binary_sensor.py @@ -9,10 +9,10 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator from .const import F_SERIES +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity, MyUplinkSystemEntity from .helpers import find_matching_platform, transform_model_series @@ -58,7 +58,7 @@ def get_description(device_point: DevicePoint) -> BinarySensorEntityDescription async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up myUplink binary_sensor.""" entities: list[BinarySensorEntity] = [] diff --git a/homeassistant/components/myuplink/coordinator.py b/homeassistant/components/myuplink/coordinator.py index 211fd894ac5..6bf762ad642 100644 --- a/homeassistant/components/myuplink/coordinator.py +++ b/homeassistant/components/myuplink/coordinator.py @@ -7,6 +7,7 @@ import logging from myuplink import Device, DevicePoint, MyUplinkAPI, System +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -23,14 +24,22 @@ class CoordinatorData: time: datetime +type MyUplinkConfigEntry = ConfigEntry[MyUplinkDataCoordinator] + + class MyUplinkDataCoordinator(DataUpdateCoordinator[CoordinatorData]): """Coordinator for myUplink data.""" - def __init__(self, hass: HomeAssistant, api: MyUplinkAPI) -> None: + config_entry: MyUplinkConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: MyUplinkConfigEntry, api: MyUplinkAPI + ) -> None: """Initialize myUplink coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="myuplink", update_interval=timedelta(seconds=60), ) diff --git a/homeassistant/components/myuplink/diagnostics.py b/homeassistant/components/myuplink/diagnostics.py index 5e26cf273b4..61605a04fc8 100644 --- a/homeassistant/components/myuplink/diagnostics.py +++ b/homeassistant/components/myuplink/diagnostics.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.diagnostics import async_redact_data from homeassistant.core import HomeAssistant -from . import MyUplinkConfigEntry +from .coordinator import MyUplinkConfigEntry TO_REDACT = {"access_token", "refresh_token", "serialNumber"} diff --git a/homeassistant/components/myuplink/number.py b/homeassistant/components/myuplink/number.py index e1cbd393947..33100850837 100644 --- a/homeassistant/components/myuplink/number.py +++ b/homeassistant/components/myuplink/number.py @@ -7,10 +7,10 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator from .const import DOMAIN, F_SERIES +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity from .helpers import find_matching_platform, skip_entity, transform_model_series @@ -63,7 +63,7 @@ def get_description(device_point: DevicePoint) -> NumberEntityDescription | None async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up myUplink number.""" entities: list[NumberEntity] = [] diff --git a/homeassistant/components/myuplink/select.py b/homeassistant/components/myuplink/select.py index 0074d1c75ff..36f9be63669 100644 --- a/homeassistant/components/myuplink/select.py +++ b/homeassistant/components/myuplink/select.py @@ -9,10 +9,10 @@ from homeassistant.components.select import SelectEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator from .const import DOMAIN +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity from .helpers import find_matching_platform, skip_entity @@ -20,7 +20,7 @@ from .helpers import find_matching_platform, skip_entity async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up myUplink select.""" entities: list[SelectEntity] = [] diff --git a/homeassistant/components/myuplink/sensor.py b/homeassistant/components/myuplink/sensor.py index fa50e8a7001..3b14cdd4630 100644 --- a/homeassistant/components/myuplink/sensor.py +++ b/homeassistant/components/myuplink/sensor.py @@ -21,11 +21,11 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator from .const import F_SERIES +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity from .helpers import find_matching_platform, skip_entity, transform_model_series @@ -214,7 +214,7 @@ def get_description(device_point: DevicePoint) -> SensorEntityDescription | None async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up myUplink sensor.""" diff --git a/homeassistant/components/myuplink/switch.py b/homeassistant/components/myuplink/switch.py index 3addc7ce6a9..2d3706f2bdb 100644 --- a/homeassistant/components/myuplink/switch.py +++ b/homeassistant/components/myuplink/switch.py @@ -9,10 +9,10 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator from .const import DOMAIN, F_SERIES +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity from .helpers import find_matching_platform, skip_entity, transform_model_series @@ -55,7 +55,7 @@ def get_description(device_point: DevicePoint) -> SwitchEntityDescription | None async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up myUplink switch.""" entities: list[SwitchEntity] = [] diff --git a/homeassistant/components/myuplink/update.py b/homeassistant/components/myuplink/update.py index 9e94de0a503..ee259f5cbe8 100644 --- a/homeassistant/components/myuplink/update.py +++ b/homeassistant/components/myuplink/update.py @@ -6,9 +6,9 @@ from homeassistant.components.update import ( UpdateEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import MyUplinkConfigEntry, MyUplinkDataCoordinator +from .coordinator import MyUplinkConfigEntry, MyUplinkDataCoordinator from .entity import MyUplinkEntity UPDATE_DESCRIPTION = UpdateEntityDescription( @@ -20,7 +20,7 @@ UPDATE_DESCRIPTION = UpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: MyUplinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entity.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nam/__init__.py b/homeassistant/components/nam/__init__.py index 624415adb12..6b4ca6ff324 100644 --- a/homeassistant/components/nam/__init__.py +++ b/homeassistant/components/nam/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations import logging -from typing import TYPE_CHECKING from aiohttp.client_exceptions import ClientConnectorError, ClientError from nettigo_air_monitor import ( @@ -14,7 +13,6 @@ from nettigo_air_monitor import ( ) from homeassistant.components.air_quality import DOMAIN as AIR_QUALITY_PLATFORM -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -22,14 +20,12 @@ from homeassistant.helpers import entity_registry as er from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ATTR_SDS011, ATTR_SPS30, DOMAIN -from .coordinator import NAMDataUpdateCoordinator +from .coordinator import NAMConfigEntry, NAMDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.BUTTON, Platform.SENSOR] -type NAMConfigEntry = ConfigEntry[NAMDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: NAMConfigEntry) -> bool: """Set up Nettigo as config entry.""" @@ -52,10 +48,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NAMConfigEntry) -> bool: except AuthFailedError as err: raise ConfigEntryAuthFailed from err - if TYPE_CHECKING: - assert entry.unique_id - - coordinator = NAMDataUpdateCoordinator(hass, nam, entry.unique_id) + coordinator = NAMDataUpdateCoordinator(hass, entry, nam) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/nam/button.py b/homeassistant/components/nam/button.py index 8ac56f3d70e..60145e4fe27 100644 --- a/homeassistant/components/nam/button.py +++ b/homeassistant/components/nam/button.py @@ -11,10 +11,10 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import NAMConfigEntry, NAMDataUpdateCoordinator +from .coordinator import NAMConfigEntry, NAMDataUpdateCoordinator PARALLEL_UPDATES = 1 @@ -28,7 +28,9 @@ RESTART_BUTTON: ButtonEntityDescription = ButtonEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: NAMConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NAMConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a Nettigo Air Monitor entities from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nam/coordinator.py b/homeassistant/components/nam/coordinator.py index 5019f0e3a1d..3e2c9c24474 100644 --- a/homeassistant/components/nam/coordinator.py +++ b/homeassistant/components/nam/coordinator.py @@ -1,6 +1,7 @@ """The Nettigo Air Monitor coordinator.""" import logging +from typing import TYPE_CHECKING from nettigo_air_monitor import ( ApiError, @@ -10,6 +11,7 @@ from nettigo_air_monitor import ( ) from tenacity import RetryError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -18,20 +20,28 @@ from .const import DEFAULT_UPDATE_INTERVAL, DOMAIN, MANUFACTURER _LOGGER = logging.getLogger(__name__) +type NAMConfigEntry = ConfigEntry[NAMDataUpdateCoordinator] + class NAMDataUpdateCoordinator(DataUpdateCoordinator[NAMSensors]): """Class to manage fetching Nettigo Air Monitor data.""" + config_entry: NAMConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: NAMConfigEntry, nam: NettigoAirMonitor, - unique_id: str, ) -> None: """Initialize.""" - self.unique_id = unique_id + if TYPE_CHECKING: + assert config_entry.unique_id + + self.unique_id = config_entry.unique_id + self.device_info = DeviceInfo( - connections={(CONNECTION_NETWORK_MAC, unique_id)}, + connections={(CONNECTION_NETWORK_MAC, self.unique_id)}, name="Nettigo Air Monitor", sw_version=nam.software_version, manufacturer=MANUFACTURER, @@ -40,7 +50,11 @@ class NAMDataUpdateCoordinator(DataUpdateCoordinator[NAMSensors]): self.nam = nam super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=DEFAULT_UPDATE_INTERVAL + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=DEFAULT_UPDATE_INTERVAL, ) async def _async_update_data(self) -> NAMSensors: diff --git a/homeassistant/components/nam/diagnostics.py b/homeassistant/components/nam/diagnostics.py index d29eb40ced7..905c1669496 100644 --- a/homeassistant/components/nam/diagnostics.py +++ b/homeassistant/components/nam/diagnostics.py @@ -9,7 +9,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant -from . import NAMConfigEntry +from .coordinator import NAMConfigEntry TO_REDACT = {CONF_PASSWORD, CONF_USERNAME} diff --git a/homeassistant/components/nam/sensor.py b/homeassistant/components/nam/sensor.py index 27fae62be8a..4478507dc59 100644 --- a/homeassistant/components/nam/sensor.py +++ b/homeassistant/components/nam/sensor.py @@ -27,12 +27,11 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utcnow -from . import NAMConfigEntry, NAMDataUpdateCoordinator from .const import ( ATTR_BME280_HUMIDITY, ATTR_BME280_PRESSURE, @@ -69,6 +68,7 @@ from .const import ( DOMAIN, MIGRATION_SENSORS, ) +from .coordinator import NAMConfigEntry, NAMDataUpdateCoordinator PARALLEL_UPDATES = 1 @@ -356,7 +356,9 @@ SENSORS: tuple[NAMSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: NAMConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NAMConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a Nettigo Air Monitor entities from a config_entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nanoleaf/__init__.py b/homeassistant/components/nanoleaf/__init__.py index 4a34c2843aa..7ee1c14a9b1 100644 --- a/homeassistant/components/nanoleaf/__init__.py +++ b/homeassistant/components/nanoleaf/__init__.py @@ -8,7 +8,6 @@ import logging from aionanoleaf import EffectsEvent, Nanoleaf, StateEvent, TouchEvent -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_DEVICE_ID, CONF_HOST, @@ -22,23 +21,20 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.dispatcher import async_dispatcher_send from .const import DOMAIN, NANOLEAF_EVENT, TOUCH_GESTURE_TRIGGER_MAP, TOUCH_MODELS -from .coordinator import NanoleafCoordinator +from .coordinator import NanoleafConfigEntry, NanoleafCoordinator _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.BUTTON, Platform.EVENT, Platform.LIGHT] -type NanoleafConfigEntry = ConfigEntry[NanoleafCoordinator] - - async def async_setup_entry(hass: HomeAssistant, entry: NanoleafConfigEntry) -> bool: """Set up Nanoleaf from a config entry.""" nanoleaf = Nanoleaf( async_get_clientsession(hass), entry.data[CONF_HOST], entry.data[CONF_TOKEN] ) - coordinator = NanoleafCoordinator(hass, nanoleaf) + coordinator = NanoleafCoordinator(hass, entry, nanoleaf) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/nanoleaf/button.py b/homeassistant/components/nanoleaf/button.py index 34d0f4f5076..813d81ab571 100644 --- a/homeassistant/components/nanoleaf/button.py +++ b/homeassistant/components/nanoleaf/button.py @@ -3,17 +3,16 @@ from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NanoleafConfigEntry -from .coordinator import NanoleafCoordinator +from .coordinator import NanoleafConfigEntry, NanoleafCoordinator from .entity import NanoleafEntity async def async_setup_entry( hass: HomeAssistant, entry: NanoleafConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nanoleaf button.""" async_add_entities([NanoleafIdentifyButton(entry.runtime_data)]) diff --git a/homeassistant/components/nanoleaf/coordinator.py b/homeassistant/components/nanoleaf/coordinator.py index e080afc492e..495a63b9164 100644 --- a/homeassistant/components/nanoleaf/coordinator.py +++ b/homeassistant/components/nanoleaf/coordinator.py @@ -5,20 +5,31 @@ import logging from aionanoleaf import InvalidToken, Nanoleaf, Unavailable +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed _LOGGER = logging.getLogger(__name__) +type NanoleafConfigEntry = ConfigEntry[NanoleafCoordinator] + class NanoleafCoordinator(DataUpdateCoordinator[None]): """Class to manage fetching Nanoleaf data.""" - def __init__(self, hass: HomeAssistant, nanoleaf: Nanoleaf) -> None: + config_entry: NanoleafConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: NanoleafConfigEntry, nanoleaf: Nanoleaf + ) -> None: """Initialize the Nanoleaf data coordinator.""" super().__init__( - hass, _LOGGER, name="Nanoleaf", update_interval=timedelta(minutes=1) + hass, + _LOGGER, + config_entry=config_entry, + name="Nanoleaf", + update_interval=timedelta(minutes=1), ) self.nanoleaf = nanoleaf diff --git a/homeassistant/components/nanoleaf/diagnostics.py b/homeassistant/components/nanoleaf/diagnostics.py index 6f8691905ef..ce2045acf7b 100644 --- a/homeassistant/components/nanoleaf/diagnostics.py +++ b/homeassistant/components/nanoleaf/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_TOKEN from homeassistant.core import HomeAssistant -from . import NanoleafConfigEntry +from .coordinator import NanoleafConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/nanoleaf/entity.py b/homeassistant/components/nanoleaf/entity.py index ffe4a098022..dd0b455fa0f 100644 --- a/homeassistant/components/nanoleaf/entity.py +++ b/homeassistant/components/nanoleaf/entity.py @@ -3,8 +3,8 @@ from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import NanoleafCoordinator from .const import DOMAIN +from .coordinator import NanoleafCoordinator class NanoleafEntity(CoordinatorEntity[NanoleafCoordinator]): diff --git a/homeassistant/components/nanoleaf/event.py b/homeassistant/components/nanoleaf/event.py index 5763c2aa595..78ff889bdc5 100644 --- a/homeassistant/components/nanoleaf/event.py +++ b/homeassistant/components/nanoleaf/event.py @@ -3,17 +3,17 @@ from homeassistant.components.event import EventEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NanoleafConfigEntry, NanoleafCoordinator from .const import TOUCH_MODELS +from .coordinator import NanoleafConfigEntry, NanoleafCoordinator from .entity import NanoleafEntity async def async_setup_entry( hass: HomeAssistant, entry: NanoleafConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nanoleaf event.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nanoleaf/light.py b/homeassistant/components/nanoleaf/light.py index 681053fa573..6d42110d53e 100644 --- a/homeassistant/components/nanoleaf/light.py +++ b/homeassistant/components/nanoleaf/light.py @@ -15,10 +15,9 @@ from homeassistant.components.light import ( LightEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NanoleafConfigEntry -from .coordinator import NanoleafCoordinator +from .coordinator import NanoleafConfigEntry, NanoleafCoordinator from .entity import NanoleafEntity RESERVED_EFFECTS = ("*Solid*", "*Static*", "*Dynamic*") @@ -28,7 +27,7 @@ DEFAULT_NAME = "Nanoleaf" async def async_setup_entry( hass: HomeAssistant, entry: NanoleafConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nanoleaf light.""" async_add_entities([NanoleafLight(entry.runtime_data)]) diff --git a/homeassistant/components/nasweb/switch.py b/homeassistant/components/nasweb/switch.py index c5a9e085b83..740db1ed1a1 100644 --- a/homeassistant/components/nasweb/switch.py +++ b/homeassistant/components/nasweb/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH, SwitchEntit from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.helpers.update_coordinator import ( BaseCoordinatorEntity, @@ -38,7 +38,7 @@ def _get_output(coordinator: NASwebCoordinator, index: int) -> NASwebOutput | No async def async_setup_entry( hass: HomeAssistant, config: NASwebConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up switch platform.""" diff --git a/homeassistant/components/neato/button.py b/homeassistant/components/neato/button.py index 29114ce5188..8658dfd1b1b 100644 --- a/homeassistant/components/neato/button.py +++ b/homeassistant/components/neato/button.py @@ -8,14 +8,16 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NEATO_ROBOTS from .entity import NeatoEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Neato button from config entry.""" entities = [NeatoDismissAlertButton(robot) for robot in hass.data[NEATO_ROBOTS]] diff --git a/homeassistant/components/neato/camera.py b/homeassistant/components/neato/camera.py index e4d5f81f33a..42278a3a48f 100644 --- a/homeassistant/components/neato/camera.py +++ b/homeassistant/components/neato/camera.py @@ -13,7 +13,7 @@ from urllib3.response import HTTPResponse from homeassistant.components.camera import Camera from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NEATO_LOGIN, NEATO_MAP_DATA, NEATO_ROBOTS, SCAN_INTERVAL_MINUTES from .entity import NeatoEntity @@ -26,7 +26,9 @@ ATTR_GENERATED_AT = "generated_at" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Neato camera with config entry.""" neato: NeatoHub = hass.data[NEATO_LOGIN] diff --git a/homeassistant/components/neato/sensor.py b/homeassistant/components/neato/sensor.py index c247cc48493..4be02fe1ef7 100644 --- a/homeassistant/components/neato/sensor.py +++ b/homeassistant/components/neato/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NEATO_LOGIN, NEATO_ROBOTS, SCAN_INTERVAL_MINUTES from .entity import NeatoEntity @@ -27,7 +27,9 @@ BATTERY = "Battery" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Neato sensor using config entry.""" neato: NeatoHub = hass.data[NEATO_LOGIN] diff --git a/homeassistant/components/neato/switch.py b/homeassistant/components/neato/switch.py index 25da1c41df1..1ae06fef44c 100644 --- a/homeassistant/components/neato/switch.py +++ b/homeassistant/components/neato/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NEATO_LOGIN, NEATO_ROBOTS, SCAN_INTERVAL_MINUTES from .entity import NeatoEntity @@ -29,7 +29,9 @@ SWITCH_TYPES = {SWITCH_TYPE_SCHEDULE: ["Schedule"]} async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Neato switch with config entry.""" neato: NeatoHub = hass.data[NEATO_LOGIN] diff --git a/homeassistant/components/neato/vacuum.py b/homeassistant/components/neato/vacuum.py index 1a9285964a2..a1e1382eb04 100644 --- a/homeassistant/components/neato/vacuum.py +++ b/homeassistant/components/neato/vacuum.py @@ -21,7 +21,7 @@ from homeassistant.const import ATTR_MODE from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ACTION, @@ -58,7 +58,9 @@ ATTR_ZONE = "zone" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Neato vacuum with config entry.""" neato: NeatoHub = hass.data[NEATO_LOGIN] diff --git a/homeassistant/components/nest/__init__.py b/homeassistant/components/nest/__init__.py index 8adc0e4f714..67c14bbf544 100644 --- a/homeassistant/components/nest/__init__.py +++ b/homeassistant/components/nest/__init__.py @@ -198,7 +198,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: NestConfigEntry) -> bool entry, unique_id=entry.data[CONF_PROJECT_ID] ) - subscriber = await api.new_subscriber(hass, entry) + auth = await api.new_auth(hass, entry) + try: + await auth.async_get_access_token() + except AuthException as err: + raise ConfigEntryAuthFailed(f"Authentication error: {err!s}") from err + except ConfigurationException as err: + _LOGGER.error("Configuration error: %s", err) + return False + + subscriber = await api.new_subscriber(hass, entry, auth) if not subscriber: return False # Keep media for last N events in memory diff --git a/homeassistant/components/nest/api.py b/homeassistant/components/nest/api.py index e86e326b1c2..d55826f7ed0 100644 --- a/homeassistant/components/nest/api.py +++ b/homeassistant/components/nest/api.py @@ -50,13 +50,14 @@ class AsyncConfigEntryAuth(AbstractAuth): return cast(str, self._oauth_session.token["access_token"]) async def async_get_creds(self) -> Credentials: - """Return an OAuth credential for Pub/Sub Subscriber.""" - # We don't have a way for Home Assistant to refresh creds on behalf - # of the google pub/sub subscriber. Instead, build a full - # Credentials object with enough information for the subscriber to - # handle this on its own. We purposely don't refresh the token here - # even when it is expired to fully hand off this responsibility and - # know it is working at startup (then if not, fail loudly). + """Return an OAuth credential for Pub/Sub Subscriber. + + The subscriber will call this when connecting to the stream to refresh + the token. We construct a credentials object using the underlying + OAuth2Session since the subscriber may expect the expiry fields to + be present. + """ + await self.async_get_access_token() token = self._oauth_session.token creds = Credentials( # type: ignore[no-untyped-call] token=token["access_token"], @@ -101,9 +102,7 @@ class AccessTokenAuthImpl(AbstractAuth): ) -async def new_subscriber( - hass: HomeAssistant, entry: NestConfigEntry -) -> GoogleNestSubscriber | None: +async def new_auth(hass: HomeAssistant, entry: NestConfigEntry) -> AbstractAuth: """Create a GoogleNestSubscriber.""" implementation = ( await config_entry_oauth2_flow.async_get_config_entry_implementation( @@ -114,14 +113,22 @@ async def new_subscriber( implementation, config_entry_oauth2_flow.LocalOAuth2Implementation ): raise TypeError(f"Unexpected auth implementation {implementation}") - if (subscription_name := entry.data.get(CONF_SUBSCRIPTION_NAME)) is None: - subscription_name = entry.data[CONF_SUBSCRIBER_ID] - auth = AsyncConfigEntryAuth( + return AsyncConfigEntryAuth( aiohttp_client.async_get_clientsession(hass), config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation), implementation.client_id, implementation.client_secret, ) + + +async def new_subscriber( + hass: HomeAssistant, + entry: NestConfigEntry, + auth: AbstractAuth, +) -> GoogleNestSubscriber: + """Create a GoogleNestSubscriber.""" + if (subscription_name := entry.data.get(CONF_SUBSCRIPTION_NAME)) is None: + subscription_name = entry.data[CONF_SUBSCRIBER_ID] return GoogleNestSubscriber(auth, entry.data[CONF_PROJECT_ID], subscription_name) diff --git a/homeassistant/components/nest/camera.py b/homeassistant/components/nest/camera.py index df02f17444f..f5985da9ff8 100644 --- a/homeassistant/components/nest/camera.py +++ b/homeassistant/components/nest/camera.py @@ -30,7 +30,7 @@ from homeassistant.components.camera import ( from homeassistant.components.stream import CONF_EXTRA_PART_WAIT_TIME from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.util.dt import utcnow @@ -51,7 +51,9 @@ BACKOFF_MULTIPLIER = 1.5 async def async_setup_entry( - hass: HomeAssistant, entry: NestConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NestConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the cameras.""" diff --git a/homeassistant/components/nest/climate.py b/homeassistant/components/nest/climate.py index 3193d592120..f5eff664f83 100644 --- a/homeassistant/components/nest/climate.py +++ b/homeassistant/components/nest/climate.py @@ -30,7 +30,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .device_info import NestDeviceInfo from .types import NestConfigEntry @@ -76,7 +76,9 @@ MIN_TEMP_RANGE = 1.66667 async def async_setup_entry( - hass: HomeAssistant, entry: NestConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NestConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the client entities.""" diff --git a/homeassistant/components/nest/event.py b/homeassistant/components/nest/event.py index 1a2c0317496..9bb041fce6c 100644 --- a/homeassistant/components/nest/event.py +++ b/homeassistant/components/nest/event.py @@ -13,7 +13,7 @@ from homeassistant.components.event import ( EventEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .device_info import NestDeviceInfo from .events import ( @@ -66,7 +66,9 @@ ENTITY_DESCRIPTIONS = [ async def async_setup_entry( - hass: HomeAssistant, entry: NestConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NestConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" async_add_entities( diff --git a/homeassistant/components/nest/sensor.py b/homeassistant/components/nest/sensor.py index 02a0e305813..a6fda48fe87 100644 --- a/homeassistant/components/nest/sensor.py +++ b/homeassistant/components/nest/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .device_info import NestDeviceInfo from .types import NestConfigEntry @@ -31,7 +31,9 @@ DEVICE_TYPE_MAP = { async def async_setup_entry( - hass: HomeAssistant, entry: NestConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NestConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" diff --git a/homeassistant/components/netatmo/binary_sensor.py b/homeassistant/components/netatmo/binary_sensor.py index c478525753a..d35bfa7e8a6 100644 --- a/homeassistant/components/netatmo/binary_sensor.py +++ b/homeassistant/components/netatmo/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import NETATMO_CREATE_WEATHER_SENSOR from .data_handler import NetatmoDevice @@ -23,7 +23,9 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Netatmo binary sensors based on a config entry.""" diff --git a/homeassistant/components/netatmo/button.py b/homeassistant/components/netatmo/button.py index 7b2899c84aa..e77b5188067 100644 --- a/homeassistant/components/netatmo/button.py +++ b/homeassistant/components/netatmo/button.py @@ -10,7 +10,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_URL_CONTROL, NETATMO_CREATE_BUTTON from .data_handler import HOME, SIGNAL_NAME, NetatmoDevice @@ -22,7 +22,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo button platform.""" diff --git a/homeassistant/components/netatmo/camera.py b/homeassistant/components/netatmo/camera.py index 3bd7bcd859d..f21998bbac8 100644 --- a/homeassistant/components/netatmo/camera.py +++ b/homeassistant/components/netatmo/camera.py @@ -16,7 +16,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_CAMERA_LIGHT_MODE, @@ -48,7 +48,9 @@ DEFAULT_QUALITY = "high" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo camera platform.""" diff --git a/homeassistant/components/netatmo/climate.py b/homeassistant/components/netatmo/climate.py index 02c955beac3..2e3d8c6bcb8 100644 --- a/homeassistant/components/netatmo/climate.py +++ b/homeassistant/components/netatmo/climate.py @@ -30,7 +30,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import ( @@ -118,7 +118,9 @@ NA_VALVE = DeviceType.NRV async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo energy platform.""" diff --git a/homeassistant/components/netatmo/cover.py b/homeassistant/components/netatmo/cover.py index c34b3a1b47b..a599aacd719 100644 --- a/homeassistant/components/netatmo/cover.py +++ b/homeassistant/components/netatmo/cover.py @@ -16,7 +16,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_URL_CONTROL, NETATMO_CREATE_COVER from .data_handler import HOME, SIGNAL_NAME, NetatmoDevice @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo cover platform.""" diff --git a/homeassistant/components/netatmo/fan.py b/homeassistant/components/netatmo/fan.py index 9f3fe7174ff..b0dc74c2b58 100644 --- a/homeassistant/components/netatmo/fan.py +++ b/homeassistant/components/netatmo/fan.py @@ -11,7 +11,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_URL_CONTROL, NETATMO_CREATE_FAN from .data_handler import HOME, SIGNAL_NAME, NetatmoDevice @@ -28,7 +28,7 @@ PRESETS = {v: k for k, v in PRESET_MAPPING.items()} async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo fan platform.""" diff --git a/homeassistant/components/netatmo/light.py b/homeassistant/components/netatmo/light.py index fe30dc0eaa4..ce28c455dea 100644 --- a/homeassistant/components/netatmo/light.py +++ b/homeassistant/components/netatmo/light.py @@ -11,7 +11,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_URL_CONTROL, @@ -30,7 +30,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo camera light platform.""" diff --git a/homeassistant/components/netatmo/select.py b/homeassistant/components/netatmo/select.py index 92568b73e80..e8637c90584 100644 --- a/homeassistant/components/netatmo/select.py +++ b/homeassistant/components/netatmo/select.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_URL_ENERGY, @@ -26,7 +26,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo energy platform schedule selector.""" diff --git a/homeassistant/components/netatmo/sensor.py b/homeassistant/components/netatmo/sensor.py index cc233dcc0ce..5f8084d542c 100644 --- a/homeassistant/components/netatmo/sensor.py +++ b/homeassistant/components/netatmo/sensor.py @@ -38,7 +38,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -385,7 +385,9 @@ BATTERY_SENSOR_DESCRIPTION = NetatmoSensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo sensor platform.""" diff --git a/homeassistant/components/netatmo/switch.py b/homeassistant/components/netatmo/switch.py index 6ba4628a358..9ee37c11528 100644 --- a/homeassistant/components/netatmo/switch.py +++ b/homeassistant/components/netatmo/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_URL_CONTROL, NETATMO_CREATE_SWITCH from .data_handler import HOME, SIGNAL_NAME, NetatmoDevice @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netatmo switch platform.""" diff --git a/homeassistant/components/netgear/button.py b/homeassistant/components/netgear/button.py index e5b9ec209c7..726c1b2296d 100644 --- a/homeassistant/components/netgear/button.py +++ b/homeassistant/components/netgear/button.py @@ -12,7 +12,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, KEY_COORDINATOR, KEY_ROUTER @@ -38,7 +38,9 @@ BUTTONS = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button for Netgear component.""" router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] diff --git a/homeassistant/components/netgear/device_tracker.py b/homeassistant/components/netgear/device_tracker.py index b17430d2abb..56f4ecac14f 100644 --- a/homeassistant/components/netgear/device_tracker.py +++ b/homeassistant/components/netgear/device_tracker.py @@ -7,7 +7,7 @@ import logging from homeassistant.components.device_tracker import ScannerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DEVICE_ICONS, DOMAIN, KEY_COORDINATOR, KEY_ROUTER @@ -18,7 +18,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Netgear component.""" router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] diff --git a/homeassistant/components/netgear/sensor.py b/homeassistant/components/netgear/sensor.py index d807f7aed0a..521e18098eb 100644 --- a/homeassistant/components/netgear/sensor.py +++ b/homeassistant/components/netgear/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -274,7 +274,9 @@ SENSOR_LINK_TYPES = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Netgear component.""" router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] diff --git a/homeassistant/components/netgear/switch.py b/homeassistant/components/netgear/switch.py index 85f214d784a..dd8468df099 100644 --- a/homeassistant/components/netgear/switch.py +++ b/homeassistant/components/netgear/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, KEY_COORDINATOR, KEY_ROUTER @@ -99,7 +99,9 @@ ROUTER_SWITCH_TYPES = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for Netgear component.""" router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] diff --git a/homeassistant/components/netgear/update.py b/homeassistant/components/netgear/update.py index 1fbfee3d892..388ad8bff4f 100644 --- a/homeassistant/components/netgear/update.py +++ b/homeassistant/components/netgear/update.py @@ -12,7 +12,7 @@ from homeassistant.components.update import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, KEY_COORDINATOR_FIRMWARE, KEY_ROUTER @@ -23,7 +23,9 @@ LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entities for Netgear component.""" router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] diff --git a/homeassistant/components/netgear_lte/__init__.py b/homeassistant/components/netgear_lte/__init__.py index 1846d1f7992..a756d85c866 100644 --- a/homeassistant/components/netgear_lte/__init__.py +++ b/homeassistant/components/netgear_lte/__init__.py @@ -6,7 +6,7 @@ from aiohttp.cookiejar import CookieJar import eternalegypt from eternalegypt.eternalegypt import SMS -from homeassistant.config_entries import ConfigEntry, ConfigEntryState +from homeassistant.config_entries import ConfigEntryState from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -23,7 +23,7 @@ from .const import ( DATA_SESSION, DOMAIN, ) -from .coordinator import NetgearLTEDataUpdateCoordinator +from .coordinator import NetgearLTEConfigEntry, NetgearLTEDataUpdateCoordinator from .services import async_setup_services EVENT_SMS = "netgear_lte_sms" @@ -55,7 +55,6 @@ PLATFORMS = [ Platform.NOTIFY, Platform.SENSOR, ] -type NetgearLTEConfigEntry = ConfigEntry[NetgearLTEDataUpdateCoordinator] CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) @@ -94,7 +93,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NetgearLTEConfigEntry) - await modem.add_sms_listener(fire_sms_event) - coordinator = NetgearLTEDataUpdateCoordinator(hass, modem) + coordinator = NetgearLTEDataUpdateCoordinator(hass, entry, modem) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/netgear_lte/binary_sensor.py b/homeassistant/components/netgear_lte/binary_sensor.py index 280d240b90f..890bcb37443 100644 --- a/homeassistant/components/netgear_lte/binary_sensor.py +++ b/homeassistant/components/netgear_lte/binary_sensor.py @@ -9,9 +9,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NetgearLTEConfigEntry +from .coordinator import NetgearLTEConfigEntry from .entity import LTEEntity BINARY_SENSORS: tuple[BinarySensorEntityDescription, ...] = ( @@ -39,7 +39,7 @@ BINARY_SENSORS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: NetgearLTEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netgear LTE binary sensor.""" async_add_entities( diff --git a/homeassistant/components/netgear_lte/coordinator.py b/homeassistant/components/netgear_lte/coordinator.py index afd0cb743bf..7bcefca6403 100644 --- a/homeassistant/components/netgear_lte/coordinator.py +++ b/homeassistant/components/netgear_lte/coordinator.py @@ -3,17 +3,16 @@ from __future__ import annotations from datetime import timedelta -from typing import TYPE_CHECKING from eternalegypt.eternalegypt import Error, Information, Modem +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, LOGGER -if TYPE_CHECKING: - from . import NetgearLTEConfigEntry +type NetgearLTEConfigEntry = ConfigEntry[NetgearLTEDataUpdateCoordinator] class NetgearLTEDataUpdateCoordinator(DataUpdateCoordinator[Information]): @@ -24,12 +23,14 @@ class NetgearLTEDataUpdateCoordinator(DataUpdateCoordinator[Information]): def __init__( self, hass: HomeAssistant, + config_entry: NetgearLTEConfigEntry, modem: Modem, ) -> None: """Initialize the coordinator.""" super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=10), ) diff --git a/homeassistant/components/netgear_lte/entity.py b/homeassistant/components/netgear_lte/entity.py index 3353da6dc77..9d56605b7d2 100644 --- a/homeassistant/components/netgear_lte/entity.py +++ b/homeassistant/components/netgear_lte/entity.py @@ -5,9 +5,8 @@ from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import NetgearLTEConfigEntry from .const import DOMAIN, MANUFACTURER -from .coordinator import NetgearLTEDataUpdateCoordinator +from .coordinator import NetgearLTEConfigEntry, NetgearLTEDataUpdateCoordinator class LTEEntity(CoordinatorEntity[NetgearLTEDataUpdateCoordinator]): diff --git a/homeassistant/components/netgear_lte/sensor.py b/homeassistant/components/netgear_lte/sensor.py index 73e5de7eaeb..49301267d9d 100644 --- a/homeassistant/components/netgear_lte/sensor.py +++ b/homeassistant/components/netgear_lte/sensor.py @@ -19,10 +19,10 @@ from homeassistant.const import ( UnitOfInformation, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import NetgearLTEConfigEntry +from .coordinator import NetgearLTEConfigEntry from .entity import LTEEntity @@ -127,7 +127,7 @@ SENSORS: tuple[NetgearLTESensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: NetgearLTEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Netgear LTE sensor.""" async_add_entities(NetgearLTESensor(entry, description) for description in SENSORS) diff --git a/homeassistant/components/nexia/__init__.py b/homeassistant/components/nexia/__init__.py index 66a8ec5bdb8..8d0d509f8a2 100644 --- a/homeassistant/components/nexia/__init__.py +++ b/homeassistant/components/nexia/__init__.py @@ -58,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NexiaConfigEntry) -> boo f"Error connecting to Nexia service: {os_error}" ) from os_error - coordinator = NexiaDataUpdateCoordinator(hass, nexia_home) + coordinator = NexiaDataUpdateCoordinator(hass, entry, nexia_home) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/nexia/binary_sensor.py b/homeassistant/components/nexia/binary_sensor.py index 204d84ed975..224836c81e6 100644 --- a/homeassistant/components/nexia/binary_sensor.py +++ b/homeassistant/components/nexia/binary_sensor.py @@ -2,7 +2,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import NexiaThermostatEntity from .types import NexiaConfigEntry @@ -11,7 +11,7 @@ from .types import NexiaConfigEntry async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for a Nexia device.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nexia/climate.py b/homeassistant/components/nexia/climate.py index 81e7800fd01..e9de81cca7c 100644 --- a/homeassistant/components/nexia/climate.py +++ b/homeassistant/components/nexia/climate.py @@ -33,7 +33,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import VolDictType @@ -116,7 +116,7 @@ NEXIA_SUPPORTED = ( async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate for a Nexia device.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nexia/coordinator.py b/homeassistant/components/nexia/coordinator.py index 894c491c45b..85e784218f4 100644 --- a/homeassistant/components/nexia/coordinator.py +++ b/homeassistant/components/nexia/coordinator.py @@ -8,6 +8,7 @@ from typing import Any from nexia.home import NexiaHome +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -19,9 +20,12 @@ DEFAULT_UPDATE_RATE = 120 class NexiaDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """DataUpdateCoordinator for nexia homes.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, nexia_home: NexiaHome, ) -> None: """Initialize DataUpdateCoordinator for the nexia home.""" @@ -29,6 +33,7 @@ class NexiaDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Nexia update", update_interval=timedelta(seconds=DEFAULT_UPDATE_RATE), always_update=False, diff --git a/homeassistant/components/nexia/number.py b/homeassistant/components/nexia/number.py index 46cc4d094a3..05d9e5b4614 100644 --- a/homeassistant/components/nexia/number.py +++ b/homeassistant/components/nexia/number.py @@ -7,7 +7,7 @@ from nexia.thermostat import NexiaThermostat from homeassistant.components.number import NumberEntity from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import NexiaDataUpdateCoordinator from .entity import NexiaThermostatEntity @@ -18,7 +18,7 @@ from .util import percent_conv async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for a Nexia device.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nexia/scene.py b/homeassistant/components/nexia/scene.py index 60078fab822..fe75eb07e02 100644 --- a/homeassistant/components/nexia/scene.py +++ b/homeassistant/components/nexia/scene.py @@ -6,7 +6,7 @@ from nexia.automation import NexiaAutomation from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from .const import ATTR_DESCRIPTION @@ -20,7 +20,7 @@ SCENE_ACTIVATION_TIME = 5 async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up automations for a Nexia device.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nexia/sensor.py b/homeassistant/components/nexia/sensor.py index e50bd750c2f..293a9308cb4 100644 --- a/homeassistant/components/nexia/sensor.py +++ b/homeassistant/components/nexia/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import NexiaThermostatEntity, NexiaThermostatZoneEntity from .types import NexiaConfigEntry @@ -22,7 +22,7 @@ from .util import percent_conv async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for a Nexia device.""" diff --git a/homeassistant/components/nexia/switch.py b/homeassistant/components/nexia/switch.py index 9505538e86a..1897ad67414 100644 --- a/homeassistant/components/nexia/switch.py +++ b/homeassistant/components/nexia/switch.py @@ -10,7 +10,7 @@ from nexia.zone import NexiaThermostatZone from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import NexiaDataUpdateCoordinator from .entity import NexiaThermostatEntity, NexiaThermostatZoneEntity @@ -20,7 +20,7 @@ from .types import NexiaConfigEntry async def async_setup_entry( hass: HomeAssistant, config_entry: NexiaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for a Nexia device.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nextbus/sensor.py b/homeassistant/components/nextbus/sensor.py index 554814fe2db..2e184e13fc7 100644 --- a/homeassistant/components/nextbus/sensor.py +++ b/homeassistant/components/nextbus/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_STOP from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utc_from_timestamp @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load values from configuration and initialize the platform.""" _LOGGER.debug(config.data) diff --git a/homeassistant/components/nextcloud/binary_sensor.py b/homeassistant/components/nextcloud/binary_sensor.py index 10e1a000a68..f51796e6c7f 100644 --- a/homeassistant/components/nextcloud/binary_sensor.py +++ b/homeassistant/components/nextcloud/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import NextcloudConfigEntry from .entity import NextcloudEntity @@ -54,7 +54,7 @@ BINARY_SENSORS: Final[list[BinarySensorEntityDescription]] = [ async def async_setup_entry( hass: HomeAssistant, entry: NextcloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nextcloud binary sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nextcloud/sensor.py b/homeassistant/components/nextcloud/sensor.py index a6722821012..63b31f0edde 100644 --- a/homeassistant/components/nextcloud/sensor.py +++ b/homeassistant/components/nextcloud/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utc_from_timestamp from .coordinator import NextcloudConfigEntry @@ -602,7 +602,7 @@ SENSORS: Final[list[NextcloudSensorEntityDescription]] = [ async def async_setup_entry( hass: HomeAssistant, entry: NextcloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nextcloud sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nextcloud/update.py b/homeassistant/components/nextcloud/update.py index aad6412b7b3..b991b001117 100644 --- a/homeassistant/components/nextcloud/update.py +++ b/homeassistant/components/nextcloud/update.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.update import UpdateEntity, UpdateEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import NextcloudConfigEntry from .entity import NextcloudEntity @@ -13,7 +13,7 @@ from .entity import NextcloudEntity async def async_setup_entry( hass: HomeAssistant, entry: NextcloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nextcloud update entity.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/nextdns/__init__.py b/homeassistant/components/nextdns/__init__.py index 7f0729bca1e..478ff215c30 100644 --- a/homeassistant/components/nextdns/__init__.py +++ b/homeassistant/components/nextdns/__init__.py @@ -98,7 +98,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: NextDnsConfigEntry) -> b # Independent DataUpdateCoordinator is used for each API endpoint to avoid # unnecessary requests when entities using this endpoint are disabled. for coordinator_name, coordinator_class, update_interval in COORDINATORS: - coordinator = coordinator_class(hass, nextdns, profile_id, update_interval) + coordinator = coordinator_class( + hass, entry, nextdns, profile_id, update_interval + ) tasks.append(coordinator.async_config_entry_first_refresh()) coordinators[coordinator_name] = coordinator diff --git a/homeassistant/components/nextdns/binary_sensor.py b/homeassistant/components/nextdns/binary_sensor.py index 08a1f89418f..ed244146efc 100644 --- a/homeassistant/components/nextdns/binary_sensor.py +++ b/homeassistant/components/nextdns/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import NextDnsConfigEntry @@ -51,7 +51,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: NextDnsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add NextDNS entities from a config_entry.""" coordinator = entry.runtime_data.connection diff --git a/homeassistant/components/nextdns/button.py b/homeassistant/components/nextdns/button.py index 164d725b393..b36c243a463 100644 --- a/homeassistant/components/nextdns/button.py +++ b/homeassistant/components/nextdns/button.py @@ -7,7 +7,7 @@ from nextdns import AnalyticsStatus from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import NextDnsConfigEntry @@ -25,7 +25,7 @@ CLEAR_LOGS_BUTTON = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: NextDnsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add aNextDNS entities from a config_entry.""" coordinator = entry.runtime_data.status diff --git a/homeassistant/components/nextdns/coordinator.py b/homeassistant/components/nextdns/coordinator.py index 6b35e35a027..850702e4488 100644 --- a/homeassistant/components/nextdns/coordinator.py +++ b/homeassistant/components/nextdns/coordinator.py @@ -1,8 +1,10 @@ """NextDns coordinator.""" +from __future__ import annotations + from datetime import timedelta import logging -from typing import TypeVar +from typing import TYPE_CHECKING, TypeVar from aiohttp.client_exceptions import ClientConnectorError from nextdns import ( @@ -25,6 +27,9 @@ from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import NextDnsConfigEntry + from .const import DOMAIN _LOGGER = logging.getLogger(__name__) @@ -35,9 +40,12 @@ CoordinatorDataT = TypeVar("CoordinatorDataT", bound=NextDnsData) class NextDnsUpdateCoordinator(DataUpdateCoordinator[CoordinatorDataT]): """Class to manage fetching NextDNS data API.""" + config_entry: NextDnsConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: NextDnsConfigEntry, nextdns: NextDns, profile_id: str, update_interval: timedelta, @@ -54,7 +62,13 @@ class NextDnsUpdateCoordinator(DataUpdateCoordinator[CoordinatorDataT]): name=self.profile_name, ) - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=update_interval, + ) async def _async_update_data(self) -> CoordinatorDataT: """Update data via internal method.""" diff --git a/homeassistant/components/nextdns/sensor.py b/homeassistant/components/nextdns/sensor.py index ef2b5140fa1..0a4a8eaad8f 100644 --- a/homeassistant/components/nextdns/sensor.py +++ b/homeassistant/components/nextdns/sensor.py @@ -21,7 +21,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -286,7 +286,7 @@ SENSORS: tuple[NextDnsSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: NextDnsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a NextDNS entities from a config_entry.""" async_add_entities( diff --git a/homeassistant/components/nextdns/switch.py b/homeassistant/components/nextdns/switch.py index 37ff22c7521..b7c77bd9dbd 100644 --- a/homeassistant/components/nextdns/switch.py +++ b/homeassistant/components/nextdns/switch.py @@ -14,7 +14,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import NextDnsConfigEntry @@ -525,7 +525,7 @@ SWITCHES = ( async def async_setup_entry( hass: HomeAssistant, entry: NextDnsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add NextDNS entities from a config_entry.""" coordinator = entry.runtime_data.settings diff --git a/homeassistant/components/nibe_heatpump/__init__.py b/homeassistant/components/nibe_heatpump/__init__.py index b3ceb00a834..ac201ed2322 100644 --- a/homeassistant/components/nibe_heatpump/__init__.py +++ b/homeassistant/components/nibe_heatpump/__init__.py @@ -81,7 +81,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop) ) - coordinator = CoilCoordinator(hass, heatpump, connection) + coordinator = CoilCoordinator(hass, entry, heatpump, connection) data = hass.data.setdefault(DOMAIN, {}) data[entry.entry_id] = coordinator diff --git a/homeassistant/components/nibe_heatpump/binary_sensor.py b/homeassistant/components/nibe_heatpump/binary_sensor.py index 0cb16bf4485..284e4d83569 100644 --- a/homeassistant/components/nibe_heatpump/binary_sensor.py +++ b/homeassistant/components/nibe_heatpump/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT, BinarySenso from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CoilCoordinator @@ -18,7 +18,7 @@ from .entity import CoilEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/button.py b/homeassistant/components/nibe_heatpump/button.py index df8ceef6479..849912af656 100644 --- a/homeassistant/components/nibe_heatpump/button.py +++ b/homeassistant/components/nibe_heatpump/button.py @@ -9,7 +9,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, LOGGER @@ -19,7 +19,7 @@ from .coordinator import CoilCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/climate.py b/homeassistant/components/nibe_heatpump/climate.py index 94db90e7f58..1b8a0ecc0df 100644 --- a/homeassistant/components/nibe_heatpump/climate.py +++ b/homeassistant/components/nibe_heatpump/climate.py @@ -27,7 +27,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -44,7 +44,7 @@ from .coordinator import CoilCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/coordinator.py b/homeassistant/components/nibe_heatpump/coordinator.py index faaac5f165a..2451e2fbda9 100644 --- a/homeassistant/components/nibe_heatpump/coordinator.py +++ b/homeassistant/components/nibe_heatpump/coordinator.py @@ -71,12 +71,17 @@ class CoilCoordinator(ContextCoordinator[dict[int, CoilData], int]): def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, heatpump: HeatPump, connection: Connection, ) -> None: """Initialize coordinator.""" super().__init__( - hass, LOGGER, name="Nibe Heat Pump", update_interval=timedelta(seconds=60) + hass, + LOGGER, + config_entry=config_entry, + name="Nibe Heat Pump", + update_interval=timedelta(seconds=60), ) self.data = {} diff --git a/homeassistant/components/nibe_heatpump/number.py b/homeassistant/components/nibe_heatpump/number.py index cb379139eed..d85e5e9b765 100644 --- a/homeassistant/components/nibe_heatpump/number.py +++ b/homeassistant/components/nibe_heatpump/number.py @@ -8,7 +8,7 @@ from homeassistant.components.number import ENTITY_ID_FORMAT, NumberEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CoilCoordinator @@ -18,7 +18,7 @@ from .entity import CoilEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/select.py b/homeassistant/components/nibe_heatpump/select.py index 3aecff94649..c92c12a882a 100644 --- a/homeassistant/components/nibe_heatpump/select.py +++ b/homeassistant/components/nibe_heatpump/select.py @@ -8,7 +8,7 @@ from homeassistant.components.select import ENTITY_ID_FORMAT, SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CoilCoordinator @@ -18,7 +18,7 @@ from .entity import CoilEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/sensor.py b/homeassistant/components/nibe_heatpump/sensor.py index d34fed50977..ac4f9eba308 100644 --- a/homeassistant/components/nibe_heatpump/sensor.py +++ b/homeassistant/components/nibe_heatpump/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CoilCoordinator @@ -127,7 +127,7 @@ UNIT_DESCRIPTIONS = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/switch.py b/homeassistant/components/nibe_heatpump/switch.py index 72b7c20c7b3..2daf3fc48ff 100644 --- a/homeassistant/components/nibe_heatpump/switch.py +++ b/homeassistant/components/nibe_heatpump/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import CoilCoordinator @@ -20,7 +20,7 @@ from .entity import CoilEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nibe_heatpump/water_heater.py b/homeassistant/components/nibe_heatpump/water_heater.py index f53df596d27..a72851e7eab 100644 --- a/homeassistant/components/nibe_heatpump/water_heater.py +++ b/homeassistant/components/nibe_heatpump/water_heater.py @@ -17,7 +17,7 @@ from homeassistant.components.water_heater import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -32,7 +32,7 @@ from .coordinator import CoilCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform.""" diff --git a/homeassistant/components/nice_go/__init__.py b/homeassistant/components/nice_go/__init__.py index b217112c192..a8d2bd71ac4 100644 --- a/homeassistant/components/nice_go/__init__.py +++ b/homeassistant/components/nice_go/__init__.py @@ -4,11 +4,10 @@ from __future__ import annotations import logging -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_STOP, Platform from homeassistant.core import HomeAssistant -from .coordinator import NiceGOUpdateCoordinator +from .coordinator import NiceGOConfigEntry, NiceGOUpdateCoordinator _LOGGER = logging.getLogger(__name__) PLATFORMS: list[Platform] = [ @@ -18,13 +17,11 @@ PLATFORMS: list[Platform] = [ Platform.SWITCH, ] -type NiceGOConfigEntry = ConfigEntry[NiceGOUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: NiceGOConfigEntry) -> bool: """Set up Nice G.O. from a config entry.""" - coordinator = NiceGOUpdateCoordinator(hass) + coordinator = NiceGOUpdateCoordinator(hass, entry) entry.async_on_unload( hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, coordinator.async_ha_stop) ) diff --git a/homeassistant/components/nice_go/coordinator.py b/homeassistant/components/nice_go/coordinator.py index 07b20bbbf10..e486263fbe5 100644 --- a/homeassistant/components/nice_go/coordinator.py +++ b/homeassistant/components/nice_go/coordinator.py @@ -54,19 +54,18 @@ class NiceGODevice: vacation_mode: bool | None +type NiceGOConfigEntry = ConfigEntry[NiceGOUpdateCoordinator] + + class NiceGOUpdateCoordinator(DataUpdateCoordinator[dict[str, NiceGODevice]]): """DataUpdateCoordinator for Nice G.O.""" - config_entry: ConfigEntry + config_entry: NiceGOConfigEntry organization_id: str - def __init__(self, hass: HomeAssistant) -> None: + def __init__(self, hass: HomeAssistant, config_entry: NiceGOConfigEntry) -> None: """Initialize DataUpdateCoordinator for Nice G.O.""" - super().__init__( - hass, - _LOGGER, - name="Nice G.O.", - ) + super().__init__(hass, _LOGGER, config_entry=config_entry, name="Nice G.O.") self.refresh_token = self.config_entry.data[CONF_REFRESH_TOKEN] self.refresh_token_creation_time = self.config_entry.data[ diff --git a/homeassistant/components/nice_go/cover.py b/homeassistant/components/nice_go/cover.py index 6360e398b96..03124971410 100644 --- a/homeassistant/components/nice_go/cover.py +++ b/homeassistant/components/nice_go/cover.py @@ -12,10 +12,10 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NiceGOConfigEntry from .const import DOMAIN +from .coordinator import NiceGOConfigEntry from .entity import NiceGOEntity DEVICE_CLASSES = { @@ -29,7 +29,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: NiceGOConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Nice G.O. cover.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nice_go/diagnostics.py b/homeassistant/components/nice_go/diagnostics.py index 2c9a695d4b5..2a663d8925a 100644 --- a/homeassistant/components/nice_go/diagnostics.py +++ b/homeassistant/components/nice_go/diagnostics.py @@ -9,8 +9,8 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_EMAIL, CONF_PASSWORD from homeassistant.core import HomeAssistant -from . import NiceGOConfigEntry from .const import CONF_REFRESH_TOKEN +from .coordinator import NiceGOConfigEntry TO_REDACT = {CONF_PASSWORD, CONF_EMAIL, CONF_REFRESH_TOKEN, "title", "unique_id"} diff --git a/homeassistant/components/nice_go/event.py b/homeassistant/components/nice_go/event.py index cd9198bcd26..400cc3d2144 100644 --- a/homeassistant/components/nice_go/event.py +++ b/homeassistant/components/nice_go/event.py @@ -5,9 +5,9 @@ from typing import Any from homeassistant.components.event import EventEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NiceGOConfigEntry +from .coordinator import NiceGOConfigEntry from .entity import NiceGOEntity _LOGGER = logging.getLogger(__name__) @@ -16,7 +16,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: NiceGOConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Nice G.O. event.""" diff --git a/homeassistant/components/nice_go/light.py b/homeassistant/components/nice_go/light.py index abb192adde1..5b06c02f5db 100644 --- a/homeassistant/components/nice_go/light.py +++ b/homeassistant/components/nice_go/light.py @@ -10,15 +10,15 @@ from homeassistant.components.light import ColorMode, LightEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NiceGOConfigEntry from .const import ( DOMAIN, KNOWN_UNSUPPORTED_DEVICE_TYPES, SUPPORTED_DEVICE_TYPES, UNSUPPORTED_DEVICE_WARNING, ) +from .coordinator import NiceGOConfigEntry from .entity import NiceGOEntity _LOGGER = logging.getLogger(__name__) @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: NiceGOConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Nice G.O. light.""" diff --git a/homeassistant/components/nice_go/switch.py b/homeassistant/components/nice_go/switch.py index e3b85528f3b..e81ea489d2f 100644 --- a/homeassistant/components/nice_go/switch.py +++ b/homeassistant/components/nice_go/switch.py @@ -12,15 +12,15 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import NiceGOConfigEntry from .const import ( DOMAIN, KNOWN_UNSUPPORTED_DEVICE_TYPES, SUPPORTED_DEVICE_TYPES, UNSUPPORTED_DEVICE_WARNING, ) +from .coordinator import NiceGOConfigEntry from .entity import NiceGOEntity _LOGGER = logging.getLogger(__name__) @@ -29,7 +29,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: NiceGOConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Nice G.O. switch.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/nightscout/sensor.py b/homeassistant/components/nightscout/sensor.py index 620349ec3c3..de1dadf1143 100644 --- a/homeassistant/components/nightscout/sensor.py +++ b/homeassistant/components/nightscout/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_DATE, UnitOfBloodGlucoseConcentration from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_DELTA, ATTR_DEVICE, ATTR_DIRECTION, DOMAIN @@ -27,7 +27,7 @@ DEFAULT_NAME = "Blood Glucose" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Glucose Sensor.""" api = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/niko_home_control/cover.py b/homeassistant/components/niko_home_control/cover.py index b3546b517d5..2ab3438c4d9 100644 --- a/homeassistant/components/niko_home_control/cover.py +++ b/homeassistant/components/niko_home_control/cover.py @@ -8,7 +8,7 @@ from nhc.cover import NHCCover from homeassistant.components.cover import CoverEntity, CoverEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NikoHomeControlConfigEntry from .entity import NikoHomeControlEntity @@ -17,7 +17,7 @@ from .entity import NikoHomeControlEntity async def async_setup_entry( hass: HomeAssistant, entry: NikoHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Niko Home Control cover entry.""" controller = entry.runtime_data diff --git a/homeassistant/components/niko_home_control/light.py b/homeassistant/components/niko_home_control/light.py index 7c0d11b3388..b0a2d12b004 100644 --- a/homeassistant/components/niko_home_control/light.py +++ b/homeassistant/components/niko_home_control/light.py @@ -19,7 +19,10 @@ from homeassistant.const import CONF_HOST from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant from homeassistant.data_entry_flow import FlowResultType from homeassistant.helpers import config_validation as cv, issue_registry as ir -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import NHCController, NikoHomeControlConfigEntry @@ -80,7 +83,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: NikoHomeControlConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Niko Home Control light entry.""" controller = entry.runtime_data diff --git a/homeassistant/components/nina/__init__.py b/homeassistant/components/nina/__init__.py index d5b1c5ccb35..b02d6711e74 100644 --- a/homeassistant/components/nina/__init__.py +++ b/homeassistant/components/nina/__init__.py @@ -11,7 +11,6 @@ from .const import ( CONF_AREA_FILTER, CONF_FILTER_CORONA, CONF_HEADLINE_FILTER, - CONF_REGIONS, DOMAIN, NO_MATCH_REGEX, ) @@ -22,9 +21,6 @@ PLATFORMS: list[str] = [Platform.BINARY_SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up platform from a ConfigEntry.""" - - regions: dict[str, str] = entry.data[CONF_REGIONS] - if CONF_HEADLINE_FILTER not in entry.data: filter_regex = NO_MATCH_REGEX @@ -39,12 +35,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: new_data = {**entry.data, CONF_AREA_FILTER: ALL_MATCH_REGEX} hass.config_entries.async_update_entry(entry, data=new_data) - coordinator = NINADataUpdateCoordinator( - hass, - regions, - entry.data[CONF_HEADLINE_FILTER], - entry.data[CONF_AREA_FILTER], - ) + coordinator = NINADataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/nina/binary_sensor.py b/homeassistant/components/nina/binary_sensor.py index 10d3008fd82..3f7d496aca9 100644 --- a/homeassistant/components/nina/binary_sensor.py +++ b/homeassistant/components/nina/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -36,7 +36,7 @@ from .coordinator import NINADataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entries.""" diff --git a/homeassistant/components/nina/coordinator.py b/homeassistant/components/nina/coordinator.py index 2d9548f3d12..3c27729ef09 100644 --- a/homeassistant/components/nina/coordinator.py +++ b/homeassistant/components/nina/coordinator.py @@ -9,11 +9,19 @@ from typing import Any from pynina import ApiError, Nina +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import _LOGGER, DOMAIN, SCAN_INTERVAL +from .const import ( + _LOGGER, + CONF_AREA_FILTER, + CONF_HEADLINE_FILTER, + CONF_REGIONS, + DOMAIN, + SCAN_INTERVAL, +) @dataclass @@ -39,23 +47,29 @@ class NINADataUpdateCoordinator( ): """Class to manage fetching NINA data API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - regions: dict[str, str], - headline_filter: str, - area_filter: str, + config_entry: ConfigEntry, ) -> None: """Initialize.""" - self._regions: dict[str, str] = regions self._nina: Nina = Nina(async_get_clientsession(hass)) - self.headline_filter: str = headline_filter - self.area_filter: str = area_filter + self.headline_filter: str = config_entry.data[CONF_HEADLINE_FILTER] + self.area_filter: str = config_entry.data[CONF_AREA_FILTER] + regions: dict[str, str] = config_entry.data[CONF_REGIONS] for region in regions: self._nina.addRegion(region) - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) async def _async_update_data(self) -> dict[str, list[NinaWarningData]]: """Update data.""" diff --git a/homeassistant/components/nmap_tracker/device_tracker.py b/homeassistant/components/nmap_tracker/device_tracker.py index c8e7e7c25ea..afac3f06435 100644 --- a/homeassistant/components/nmap_tracker/device_tracker.py +++ b/homeassistant/components/nmap_tracker/device_tracker.py @@ -9,7 +9,7 @@ from homeassistant.components.device_tracker import ScannerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NmapDevice, NmapDeviceScanner, short_hostname, signal_device_update from .const import DOMAIN @@ -18,7 +18,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Nmap Tracker component.""" nmap_tracker = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/nmbs/sensor.py b/homeassistant/components/nmbs/sensor.py index 6d13777e10a..c6dea2d0843 100644 --- a/homeassistant/components/nmbs/sensor.py +++ b/homeassistant/components/nmbs/sensor.py @@ -23,7 +23,10 @@ from homeassistant.const import ( ) from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -151,7 +154,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up NMBS sensor entities based on a config entry.""" api_client = iRail() diff --git a/homeassistant/components/noaa_tides/helpers.py b/homeassistant/components/noaa_tides/helpers.py new file mode 100644 index 00000000000..734cca68f44 --- /dev/null +++ b/homeassistant/components/noaa_tides/helpers.py @@ -0,0 +1,6 @@ +"""Helpers for NOAA Tides integration.""" + + +def get_station_unique_id(station_id: str) -> str: + """Convert a station ID to a unique ID.""" + return f"{station_id.lower()}" diff --git a/homeassistant/components/noaa_tides/sensor.py b/homeassistant/components/noaa_tides/sensor.py index 0af2c340960..3b5a13b0f15 100644 --- a/homeassistant/components/noaa_tides/sensor.py +++ b/homeassistant/components/noaa_tides/sensor.py @@ -22,6 +22,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util.unit_system import METRIC_SYSTEM +from .helpers import get_station_unique_id + if TYPE_CHECKING: from pandas import Timestamp @@ -105,6 +107,7 @@ class NOAATidesAndCurrentsSensor(SensorEntity): self._unit_system = unit_system self._station = station self.data: NOAATidesData | None = None + self._attr_unique_id = f"{get_station_unique_id(station_id)}_summary" @property def name(self) -> str: diff --git a/homeassistant/components/nobo_hub/climate.py b/homeassistant/components/nobo_hub/climate.py index a089209cde5..771da420213 100644 --- a/homeassistant/components/nobo_hub/climate.py +++ b/homeassistant/components/nobo_hub/climate.py @@ -21,7 +21,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_NAME, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import ( @@ -46,7 +46,7 @@ MAX_TEMPERATURE = 40 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nobø Ecohub platform from UI configuration.""" diff --git a/homeassistant/components/nobo_hub/select.py b/homeassistant/components/nobo_hub/select.py index 43f177dd7a0..c24dbe3d21d 100644 --- a/homeassistant/components/nobo_hub/select.py +++ b/homeassistant/components/nobo_hub/select.py @@ -10,7 +10,7 @@ from homeassistant.const import ATTR_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_HARDWARE_VERSION, @@ -26,7 +26,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up any temperature sensors connected to the Nobø Ecohub.""" diff --git a/homeassistant/components/nobo_hub/sensor.py b/homeassistant/components/nobo_hub/sensor.py index 1632b6ba5e7..382fd1b0bf4 100644 --- a/homeassistant/components/nobo_hub/sensor.py +++ b/homeassistant/components/nobo_hub/sensor.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_MODEL, ATTR_NAME, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ATTR_SERIAL, ATTR_ZONE_ID, DOMAIN, NOBO_MANUFACTURER @@ -22,7 +22,7 @@ from .const import ATTR_SERIAL, ATTR_ZONE_ID, DOMAIN, NOBO_MANUFACTURER async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up any temperature sensors connected to the Nobø Ecohub.""" diff --git a/homeassistant/components/nordpool/sensor.py b/homeassistant/components/nordpool/sensor.py index 30910f8e5f6..c6993826239 100644 --- a/homeassistant/components/nordpool/sensor.py +++ b/homeassistant/components/nordpool/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util, slugify from . import NordPoolConfigEntry @@ -271,7 +271,7 @@ DAILY_AVERAGE_PRICES_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: NordPoolConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Nord Pool sensor platform.""" diff --git a/homeassistant/components/nordpool/services.py b/homeassistant/components/nordpool/services.py index 872bd5b1e6b..6607edfdbcb 100644 --- a/homeassistant/components/nordpool/services.py +++ b/homeassistant/components/nordpool/services.py @@ -41,7 +41,7 @@ ATTR_CURRENCY = "currency" SERVICE_GET_PRICES_FOR_DATE = "get_prices_for_date" SERVICE_GET_PRICES_SCHEMA = vol.Schema( { - vol.Required(ATTR_CONFIG_ENTRY): ConfigEntrySelector(), + vol.Required(ATTR_CONFIG_ENTRY): ConfigEntrySelector({"integration": DOMAIN}), vol.Required(ATTR_DATE): cv.date, vol.Optional(ATTR_AREAS): vol.All(vol.In(list(AREAS)), cv.ensure_list, [str]), vol.Optional(ATTR_CURRENCY): vol.All( diff --git a/homeassistant/components/notion/binary_sensor.py b/homeassistant/components/notion/binary_sensor.py index 8c57310752a..5552305e867 100644 --- a/homeassistant/components/notion/binary_sensor.py +++ b/homeassistant/components/notion/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -107,7 +107,9 @@ BINARY_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Notion sensors based on a config entry.""" coordinator: NotionDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/notion/coordinator.py b/homeassistant/components/notion/coordinator.py index c3fd23abc84..d77bfa95f47 100644 --- a/homeassistant/components/notion/coordinator.py +++ b/homeassistant/components/notion/coordinator.py @@ -117,16 +117,16 @@ class NotionDataUpdateCoordinator(DataUpdateCoordinator[NotionData]): super().__init__( hass, LOGGER, + config_entry=entry, name=entry.data[CONF_USERNAME], update_interval=DEFAULT_SCAN_INTERVAL, ) self._client = client - self._entry = entry async def _async_update_data(self) -> NotionData: """Fetch data from Notion.""" - data = NotionData(hass=self.hass, entry=self._entry) + data = NotionData(hass=self.hass, entry=self.config_entry) try: async with asyncio.TaskGroup() as tg: diff --git a/homeassistant/components/notion/sensor.py b/homeassistant/components/notion/sensor.py index fb853e65d7d..24496c8391a 100644 --- a/homeassistant/components/notion/sensor.py +++ b/homeassistant/components/notion/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, SENSOR_MOLD, SENSOR_TEMPERATURE from .coordinator import NotionDataUpdateCoordinator @@ -42,7 +42,9 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Notion sensors based on a config entry.""" coordinator: NotionDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/nuheat/climate.py b/homeassistant/components/nuheat/climate.py index 8248c1b9b82..376a07ddb7b 100644 --- a/homeassistant/components/nuheat/climate.py +++ b/homeassistant/components/nuheat/climate.py @@ -23,7 +23,7 @@ from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import event as event_helper from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER, NUHEAT_API_STATE_SHIFT_DELAY @@ -55,7 +55,7 @@ SCHEDULE_MODE_TO_PRESET_MODE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the NuHeat thermostat(s).""" thermostat, coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/nuki/__init__.py b/homeassistant/components/nuki/__init__.py index 4f3f56f7f03..5c02b6e972e 100644 --- a/homeassistant/components/nuki/__init__.py +++ b/homeassistant/components/nuki/__init__.py @@ -222,7 +222,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_nuki) ) - coordinator = NukiCoordinator(hass, bridge, locks, openers) + coordinator = NukiCoordinator(hass, entry, bridge, locks, openers) hass.data[DOMAIN][entry.entry_id] = NukiEntryData( coordinator=coordinator, bridge=bridge, diff --git a/homeassistant/components/nuki/binary_sensor.py b/homeassistant/components/nuki/binary_sensor.py index 8269c43813e..2785c46ca17 100644 --- a/homeassistant/components/nuki/binary_sensor.py +++ b/homeassistant/components/nuki/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NukiEntryData from .const import DOMAIN as NUKI_DOMAIN @@ -20,7 +20,9 @@ from .entity import NukiEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nuki binary sensors.""" entry_data: NukiEntryData = hass.data[NUKI_DOMAIN][entry.entry_id] diff --git a/homeassistant/components/nuki/coordinator.py b/homeassistant/components/nuki/coordinator.py index 114b4aee4c9..cccff99e397 100644 --- a/homeassistant/components/nuki/coordinator.py +++ b/homeassistant/components/nuki/coordinator.py @@ -12,6 +12,7 @@ from pynuki.bridge import InvalidCredentialsException from pynuki.device import NukiDevice from requests.exceptions import RequestException +from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er @@ -28,9 +29,12 @@ UPDATE_INTERVAL = timedelta(seconds=30) class NukiCoordinator(DataUpdateCoordinator[None]): """Data Update Coordinator for the Nuki integration.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, bridge: NukiBridge, locks: list[NukiLock], openers: list[NukiOpener], @@ -39,9 +43,8 @@ class NukiCoordinator(DataUpdateCoordinator[None]): super().__init__( hass, _LOGGER, - # Name of the data. For logging purposes. + config_entry=config_entry, name="nuki devices", - # Polling interval. Will only be polled if there are subscribers. update_interval=UPDATE_INTERVAL, ) self.bridge = bridge diff --git a/homeassistant/components/nuki/lock.py b/homeassistant/components/nuki/lock.py index a2bf7559fc4..3cc972d3555 100644 --- a/homeassistant/components/nuki/lock.py +++ b/homeassistant/components/nuki/lock.py @@ -15,7 +15,7 @@ from homeassistant.components.lock import LockEntity, LockEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NukiEntryData from .const import ATTR_ENABLE, ATTR_UNLATCH, DOMAIN as NUKI_DOMAIN, ERROR_STATES @@ -24,7 +24,9 @@ from .helpers import CannotConnect async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nuki lock platform.""" entry_data: NukiEntryData = hass.data[NUKI_DOMAIN][entry.entry_id] diff --git a/homeassistant/components/nuki/sensor.py b/homeassistant/components/nuki/sensor.py index d89202ac7d7..4f3890a10cf 100644 --- a/homeassistant/components/nuki/sensor.py +++ b/homeassistant/components/nuki/sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NukiEntryData from .const import DOMAIN as NUKI_DOMAIN @@ -16,7 +16,9 @@ from .entity import NukiEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Nuki lock sensor.""" entry_data: NukiEntryData = hass.data[NUKI_DOMAIN][entry.entry_id] diff --git a/homeassistant/components/nut/sensor.py b/homeassistant/components/nut/sensor.py index bb702873052..22e0496d0de 100644 --- a/homeassistant/components/nut/sensor.py +++ b/homeassistant/components/nut/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -963,7 +963,7 @@ def _get_nut_device_info(data: PyNUTData) -> DeviceInfo: async def async_setup_entry( hass: HomeAssistant, config_entry: NutConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the NUT sensors.""" diff --git a/homeassistant/components/nws/__init__.py b/homeassistant/components/nws/__init__.py index c700476ed3d..633619bcf05 100644 --- a/homeassistant/components/nws/__init__.py +++ b/homeassistant/components/nws/__init__.py @@ -101,10 +101,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NWSConfigEntry) -> bool: return update_forecast_hourly - coordinator_observation = NWSObservationDataUpdateCoordinator( - hass, - nws_data, - ) + coordinator_observation = NWSObservationDataUpdateCoordinator(hass, entry, nws_data) # Don't use retries in setup coordinator_forecast = TimestampDataUpdateCoordinator( diff --git a/homeassistant/components/nws/coordinator.py b/homeassistant/components/nws/coordinator.py index 104b1812c67..4e6560947e8 100644 --- a/homeassistant/components/nws/coordinator.py +++ b/homeassistant/components/nws/coordinator.py @@ -1,7 +1,10 @@ """The NWS coordinator.""" +from __future__ import annotations + from datetime import datetime import logging +from typing import TYPE_CHECKING from aiohttp import ClientResponseError from pynws import NwsNoDataError, SimpleNWS, call_with_retry @@ -14,6 +17,9 @@ from homeassistant.helpers.update_coordinator import ( ) from homeassistant.util.dt import utcnow +if TYPE_CHECKING: + from . import NWSConfigEntry + from .const import ( DEBOUNCE_TIME, DEFAULT_SCAN_INTERVAL, @@ -29,9 +35,12 @@ _LOGGER = logging.getLogger(__name__) class NWSObservationDataUpdateCoordinator(TimestampDataUpdateCoordinator[None]): """Class to manage fetching NWS observation data.""" + config_entry: NWSConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: NWSConfigEntry, nws: SimpleNWS, ) -> None: """Initialize.""" @@ -42,6 +51,7 @@ class NWSObservationDataUpdateCoordinator(TimestampDataUpdateCoordinator[None]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"NWS observation station {nws.station}", update_interval=DEFAULT_SCAN_INTERVAL, request_refresh_debouncer=debounce.Debouncer( diff --git a/homeassistant/components/nws/sensor.py b/homeassistant/components/nws/sensor.py index d1992056d47..63579c95883 100644 --- a/homeassistant/components/nws/sensor.py +++ b/homeassistant/components/nws/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, TimestampDataUpdateCoordinator, @@ -148,7 +148,9 @@ SENSOR_TYPES: tuple[NWSSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: NWSConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NWSConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the NWS weather platform.""" nws_data = entry.runtime_data diff --git a/homeassistant/components/nws/weather.py b/homeassistant/components/nws/weather.py index d34a5abe8af..c90c67edcb7 100644 --- a/homeassistant/components/nws/weather.py +++ b/homeassistant/components/nws/weather.py @@ -40,7 +40,7 @@ from homeassistant.core import ( callback, ) from homeassistant.helpers import entity_platform, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import TimestampDataUpdateCoordinator from homeassistant.util.json import JsonValueType from homeassistant.util.unit_conversion import SpeedConverter, TemperatureConverter @@ -87,7 +87,9 @@ def convert_condition(time: str, weather: tuple[tuple[str, int | None], ...]) -> async def async_setup_entry( - hass: HomeAssistant, entry: NWSConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: NWSConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the NWS weather platform.""" entity_registry = er.async_get(hass) diff --git a/homeassistant/components/nyt_games/__init__.py b/homeassistant/components/nyt_games/__init__.py index 94dc22fe89e..d1c6ca5c2a4 100644 --- a/homeassistant/components/nyt_games/__init__.py +++ b/homeassistant/components/nyt_games/__init__.py @@ -4,21 +4,17 @@ from __future__ import annotations from nyt_games import NYTGamesClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TOKEN, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_create_clientsession -from .coordinator import NYTGamesCoordinator +from .coordinator import NYTGamesConfigEntry, NYTGamesCoordinator PLATFORMS: list[Platform] = [ Platform.SENSOR, ] -type NYTGamesConfigEntry = ConfigEntry[NYTGamesCoordinator] - - async def async_setup_entry(hass: HomeAssistant, entry: NYTGamesConfigEntry) -> bool: """Set up NYTGames from a config entry.""" @@ -26,7 +22,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NYTGamesConfigEntry) -> entry.data[CONF_TOKEN], session=async_create_clientsession(hass) ) - coordinator = NYTGamesCoordinator(hass, client) + coordinator = NYTGamesCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/nyt_games/coordinator.py b/homeassistant/components/nyt_games/coordinator.py index 5e88a5dd92a..ae9ea4f03a0 100644 --- a/homeassistant/components/nyt_games/coordinator.py +++ b/homeassistant/components/nyt_games/coordinator.py @@ -4,18 +4,15 @@ from __future__ import annotations from dataclasses import dataclass from datetime import timedelta -from typing import TYPE_CHECKING from nyt_games import Connections, NYTGamesClient, NYTGamesError, SpellingBee, Wordle +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import LOGGER -if TYPE_CHECKING: - from . import NYTGamesConfigEntry - @dataclass class NYTGamesData: @@ -26,16 +23,25 @@ class NYTGamesData: connections: Connections | None +type NYTGamesConfigEntry = ConfigEntry[NYTGamesCoordinator] + + class NYTGamesCoordinator(DataUpdateCoordinator[NYTGamesData]): """Class to manage fetching NYT Games data.""" config_entry: NYTGamesConfigEntry - def __init__(self, hass: HomeAssistant, client: NYTGamesClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: NYTGamesConfigEntry, + client: NYTGamesClient, + ) -> None: """Initialize coordinator.""" super().__init__( hass, logger=LOGGER, + config_entry=config_entry, name="NYT Games", update_interval=timedelta(minutes=15), ) diff --git a/homeassistant/components/nyt_games/sensor.py b/homeassistant/components/nyt_games/sensor.py index 01b2db4620b..5009eafd85a 100644 --- a/homeassistant/components/nyt_games/sensor.py +++ b/homeassistant/components/nyt_games/sensor.py @@ -14,11 +14,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import NYTGamesConfigEntry -from .coordinator import NYTGamesCoordinator +from .coordinator import NYTGamesConfigEntry, NYTGamesCoordinator from .entity import ConnectionsEntity, SpellingBeeEntity, WordleEntity @@ -147,7 +146,7 @@ CONNECTIONS_SENSORS: tuple[NYTGamesConnectionsSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: NYTGamesConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up NYT Games sensor entities based on a config entry.""" diff --git a/homeassistant/components/nzbget/__init__.py b/homeassistant/components/nzbget/__init__.py index 84456c4c006..e9e5856d524 100644 --- a/homeassistant/components/nzbget/__init__.py +++ b/homeassistant/components/nzbget/__init__.py @@ -31,10 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up NZBGet from a config entry.""" hass.data.setdefault(DOMAIN, {}) - coordinator = NZBGetDataUpdateCoordinator( - hass, - config=entry.data, - ) + coordinator = NZBGetDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/nzbget/coordinator.py b/homeassistant/components/nzbget/coordinator.py index cf9625ce4ec..9e6b06da760 100644 --- a/homeassistant/components/nzbget/coordinator.py +++ b/homeassistant/components/nzbget/coordinator.py @@ -1,13 +1,12 @@ """Provides the NZBGet DataUpdateCoordinator.""" import asyncio -from collections.abc import Mapping from datetime import timedelta import logging -from typing import Any from pynzbgetapi import NZBGetAPI, NZBGetAPIException +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, @@ -27,27 +26,32 @@ _LOGGER = logging.getLogger(__name__) class NZBGetDataUpdateCoordinator(DataUpdateCoordinator): """Class to manage fetching NZBGet data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - *, - config: Mapping[str, Any], + config_entry: ConfigEntry, ) -> None: """Initialize global NZBGet data updater.""" self.nzbget = NZBGetAPI( - config[CONF_HOST], - config.get(CONF_USERNAME), - config.get(CONF_PASSWORD), - config[CONF_SSL], - config[CONF_VERIFY_SSL], - config[CONF_PORT], + config_entry.data[CONF_HOST], + config_entry.data.get(CONF_USERNAME), + config_entry.data.get(CONF_PASSWORD), + config_entry.data[CONF_SSL], + config_entry.data[CONF_VERIFY_SSL], + config_entry.data[CONF_PORT], ) self._completed_downloads_init = False self._completed_downloads = set[tuple]() super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=timedelta(seconds=5) + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=timedelta(seconds=5), ) def _check_completed_downloads(self, history): diff --git a/homeassistant/components/nzbget/sensor.py b/homeassistant/components/nzbget/sensor.py index f6a4e4cc973..2328bf453f0 100644 --- a/homeassistant/components/nzbget/sensor.py +++ b/homeassistant/components/nzbget/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, UnitOfDataRate, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow @@ -93,7 +93,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up NZBGet sensor based on a config entry.""" coordinator: NZBGetDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/nzbget/switch.py b/homeassistant/components/nzbget/switch.py index 552a1854902..0796f628507 100644 --- a/homeassistant/components/nzbget/switch.py +++ b/homeassistant/components/nzbget/switch.py @@ -8,7 +8,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_COORDINATOR, DOMAIN from .coordinator import NZBGetDataUpdateCoordinator @@ -18,7 +18,7 @@ from .entity import NZBGetEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up NZBGet sensor based on a config entry.""" coordinator: NZBGetDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/obihai/button.py b/homeassistant/components/obihai/button.py index d1b924b4693..9cef92d3fce 100644 --- a/homeassistant/components/obihai/button.py +++ b/homeassistant/components/obihai/button.py @@ -27,7 +27,7 @@ BUTTON_DESCRIPTION = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: entity_platform.AddEntitiesCallback, + async_add_entities: entity_platform.AddConfigEntryEntitiesCallback, ) -> None: """Set up the Obihai sensor entries.""" diff --git a/homeassistant/components/obihai/sensor.py b/homeassistant/components/obihai/sensor.py index c162bd6c559..ec29238201a 100644 --- a/homeassistant/components/obihai/sensor.py +++ b/homeassistant/components/obihai/sensor.py @@ -9,7 +9,7 @@ from requests.exceptions import RequestException from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .connectivity import ObihaiConnection from .const import DOMAIN, LOGGER, OBIHAI @@ -18,7 +18,9 @@ SCAN_INTERVAL = datetime.timedelta(seconds=5) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Obihai sensor entries.""" diff --git a/homeassistant/components/octoprint/binary_sensor.py b/homeassistant/components/octoprint/binary_sensor.py index 10a637e5a3b..a20738de150 100644 --- a/homeassistant/components/octoprint/binary_sensor.py +++ b/homeassistant/components/octoprint/binary_sensor.py @@ -9,7 +9,7 @@ from pyoctoprintapi import OctoprintPrinterInfo from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import OctoprintDataUpdateCoordinator @@ -19,7 +19,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the available OctoPrint binary sensors.""" coordinator: OctoprintDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/octoprint/button.py b/homeassistant/components/octoprint/button.py index 2a2e5015303..3a128fcd7aa 100644 --- a/homeassistant/components/octoprint/button.py +++ b/homeassistant/components/octoprint/button.py @@ -6,7 +6,7 @@ from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import OctoprintDataUpdateCoordinator @@ -16,7 +16,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Octoprint control buttons.""" coordinator: OctoprintDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/octoprint/camera.py b/homeassistant/components/octoprint/camera.py index e6430c55fa2..37347539d5b 100644 --- a/homeassistant/components/octoprint/camera.py +++ b/homeassistant/components/octoprint/camera.py @@ -8,7 +8,7 @@ from homeassistant.components.mjpeg import MjpegCamera from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_VERIFY_SSL from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import OctoprintDataUpdateCoordinator @@ -18,7 +18,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the available OctoPrint camera.""" coordinator: OctoprintDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/octoprint/coordinator.py b/homeassistant/components/octoprint/coordinator.py index d4f8f652b80..bb006329ff1 100644 --- a/homeassistant/components/octoprint/coordinator.py +++ b/homeassistant/components/octoprint/coordinator.py @@ -39,10 +39,10 @@ class OctoprintDataUpdateCoordinator(DataUpdateCoordinator): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"octoprint-{config_entry.entry_id}", update_interval=timedelta(seconds=interval), ) - self.config_entry = config_entry self._octoprint = octoprint self._printer_offline = False self.data = {"printer": None, "job": None, "last_read_time": None} diff --git a/homeassistant/components/octoprint/sensor.py b/homeassistant/components/octoprint/sensor.py index fb5f292d669..71db1d804c5 100644 --- a/homeassistant/components/octoprint/sensor.py +++ b/homeassistant/components/octoprint/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import OctoprintDataUpdateCoordinator @@ -38,7 +38,7 @@ def _is_printer_printing(printer: OctoprintPrinterInfo) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the available OctoPrint binary sensors.""" coordinator: OctoprintDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/ohme/__init__.py b/homeassistant/components/ohme/__init__.py index 8518e55c0a3..e3e252cbf8b 100644 --- a/homeassistant/components/ohme/__init__.py +++ b/homeassistant/components/ohme/__init__.py @@ -1,10 +1,7 @@ """Set up ohme integration.""" -from dataclasses import dataclass - from ohme import ApiException, AuthException, OhmeApiClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -15,23 +12,14 @@ from .const import DOMAIN, PLATFORMS from .coordinator import ( OhmeAdvancedSettingsCoordinator, OhmeChargeSessionCoordinator, + OhmeConfigEntry, OhmeDeviceInfoCoordinator, + OhmeRuntimeData, ) from .services import async_setup_services CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) -type OhmeConfigEntry = ConfigEntry[OhmeRuntimeData] - - -@dataclass() -class OhmeRuntimeData: - """Dataclass to hold ohme coordinators.""" - - charge_session_coordinator: OhmeChargeSessionCoordinator - advanced_settings_coordinator: OhmeAdvancedSettingsCoordinator - device_info_coordinator: OhmeDeviceInfoCoordinator - async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up Ohme integration.""" @@ -62,9 +50,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: OhmeConfigEntry) -> bool ) from e coordinators = ( - OhmeChargeSessionCoordinator(hass, client), - OhmeAdvancedSettingsCoordinator(hass, client), - OhmeDeviceInfoCoordinator(hass, client), + OhmeChargeSessionCoordinator(hass, entry, client), + OhmeAdvancedSettingsCoordinator(hass, entry, client), + OhmeDeviceInfoCoordinator(hass, entry, client), ) for coordinator in coordinators: diff --git a/homeassistant/components/ohme/button.py b/homeassistant/components/ohme/button.py index 0b0590428ce..6e942215c0f 100644 --- a/homeassistant/components/ohme/button.py +++ b/homeassistant/components/ohme/button.py @@ -10,10 +10,10 @@ from ohme import ApiException, ChargerStatus, OhmeApiClient from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry from .const import DOMAIN +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @@ -40,7 +40,7 @@ BUTTON_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons.""" coordinator = config_entry.runtime_data.charge_session_coordinator diff --git a/homeassistant/components/ohme/coordinator.py b/homeassistant/components/ohme/coordinator.py index 199eb7380a7..864b03e9a7c 100644 --- a/homeassistant/components/ohme/coordinator.py +++ b/homeassistant/components/ohme/coordinator.py @@ -1,11 +1,15 @@ """Ohme coordinators.""" +from __future__ import annotations + from abc import abstractmethod +from dataclasses import dataclass from datetime import timedelta import logging from ohme import ApiException, OhmeApiClient +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -14,18 +18,34 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) +@dataclass() +class OhmeRuntimeData: + """Dataclass to hold ohme coordinators.""" + + charge_session_coordinator: OhmeChargeSessionCoordinator + advanced_settings_coordinator: OhmeAdvancedSettingsCoordinator + device_info_coordinator: OhmeDeviceInfoCoordinator + + +type OhmeConfigEntry = ConfigEntry[OhmeRuntimeData] + + class OhmeBaseCoordinator(DataUpdateCoordinator[None]): """Base for all Ohme coordinators.""" + config_entry: OhmeConfigEntry client: OhmeApiClient _default_update_interval: timedelta | None = timedelta(minutes=1) coordinator_name: str = "" - def __init__(self, hass: HomeAssistant, client: OhmeApiClient) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: OhmeConfigEntry, client: OhmeApiClient + ) -> None: """Initialise coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="", update_interval=self._default_update_interval, ) diff --git a/homeassistant/components/ohme/number.py b/homeassistant/components/ohme/number.py index d618d4a873b..8c5be2b48be 100644 --- a/homeassistant/components/ohme/number.py +++ b/homeassistant/components/ohme/number.py @@ -9,10 +9,10 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry from .const import DOMAIN +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @@ -43,7 +43,7 @@ NUMBER_DESCRIPTION = [ async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up numbers.""" coordinators = config_entry.runtime_data diff --git a/homeassistant/components/ohme/select.py b/homeassistant/components/ohme/select.py index a357e98f0a6..17cc7c67e9a 100644 --- a/homeassistant/components/ohme/select.py +++ b/homeassistant/components/ohme/select.py @@ -11,10 +11,10 @@ from ohme import ApiException, ChargerMode, OhmeApiClient from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry from .const import DOMAIN +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @@ -41,7 +41,7 @@ SELECT_DESCRIPTION: Final[OhmeSelectDescription] = OhmeSelectDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ohme selects.""" coordinator = config_entry.runtime_data.charge_session_coordinator diff --git a/homeassistant/components/ohme/sensor.py b/homeassistant/components/ohme/sensor.py index 230314cba83..1e0572fe858 100644 --- a/homeassistant/components/ohme/sensor.py +++ b/homeassistant/components/ohme/sensor.py @@ -20,9 +20,9 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 0 @@ -91,7 +91,7 @@ SENSOR_ADVANCED_SETTINGS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" coordinators = config_entry.runtime_data diff --git a/homeassistant/components/ohme/switch.py b/homeassistant/components/ohme/switch.py index d1eb1a80b56..c4465ec7e97 100644 --- a/homeassistant/components/ohme/switch.py +++ b/homeassistant/components/ohme/switch.py @@ -9,10 +9,10 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry from .const import DOMAIN +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @@ -53,7 +53,7 @@ SWITCH_DEVICE_INFO = [ async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" coordinators = config_entry.runtime_data diff --git a/homeassistant/components/ohme/time.py b/homeassistant/components/ohme/time.py index a7de913ef8e..264b2afd41a 100644 --- a/homeassistant/components/ohme/time.py +++ b/homeassistant/components/ohme/time.py @@ -9,10 +9,10 @@ from ohme import ApiException, OhmeApiClient from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import OhmeConfigEntry from .const import DOMAIN +from .coordinator import OhmeConfigEntry from .entity import OhmeEntity, OhmeEntityDescription PARALLEL_UPDATES = 1 @@ -43,7 +43,7 @@ TIME_DESCRIPTION = [ async def async_setup_entry( hass: HomeAssistant, config_entry: OhmeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up time entities.""" coordinators = config_entry.runtime_data diff --git a/homeassistant/components/ollama/conversation.py b/homeassistant/components/ollama/conversation.py index c0fbfae6444..90e81544f66 100644 --- a/homeassistant/components/ollama/conversation.py +++ b/homeassistant/components/ollama/conversation.py @@ -2,25 +2,21 @@ from __future__ import annotations -from collections.abc import Callable +from collections.abc import AsyncGenerator, Callable import json import logging -import time from typing import Any, Literal import ollama -import voluptuous as vol from voluptuous_openapi import convert from homeassistant.components import assist_pipeline, conversation -from homeassistant.components.conversation import trace from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_LLM_HASS_API, MATCH_ALL from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError, TemplateError -from homeassistant.helpers import intent, llm, template -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.util import ulid as ulid_util +from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers import chat_session, intent, llm +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_KEEP_ALIVE, @@ -32,7 +28,6 @@ from .const import ( DEFAULT_MAX_HISTORY, DEFAULT_NUM_CTX, DOMAIN, - MAX_HISTORY_SECONDS, ) from .models import MessageHistory, MessageRole @@ -45,7 +40,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up conversation entities.""" agent = OllamaConversationEntity(config_entry) @@ -93,6 +88,84 @@ def _parse_tool_args(arguments: dict[str, Any]) -> dict[str, Any]: return {k: _fix_invalid_arguments(v) for k, v in arguments.items() if v} +def _convert_content( + chat_content: conversation.Content + | conversation.ToolResultContent + | conversation.AssistantContent, +) -> ollama.Message: + """Create tool response content.""" + if isinstance(chat_content, conversation.ToolResultContent): + return ollama.Message( + role=MessageRole.TOOL.value, + content=json.dumps(chat_content.tool_result), + ) + if isinstance(chat_content, conversation.AssistantContent): + return ollama.Message( + role=MessageRole.ASSISTANT.value, + content=chat_content.content, + tool_calls=[ + ollama.Message.ToolCall( + function=ollama.Message.ToolCall.Function( + name=tool_call.tool_name, + arguments=tool_call.tool_args, + ) + ) + for tool_call in chat_content.tool_calls or () + ], + ) + if isinstance(chat_content, conversation.UserContent): + return ollama.Message( + role=MessageRole.USER.value, + content=chat_content.content, + ) + if isinstance(chat_content, conversation.SystemContent): + return ollama.Message( + role=MessageRole.SYSTEM.value, + content=chat_content.content, + ) + raise TypeError(f"Unexpected content type: {type(chat_content)}") + + +async def _transform_stream( + result: AsyncGenerator[ollama.Message], +) -> AsyncGenerator[conversation.AssistantContentDeltaDict]: + """Transform the response stream into HA format. + + An Ollama streaming response may come in chunks like this: + + response: message=Message(role="assistant", content="Paris") + response: message=Message(role="assistant", content=".") + response: message=Message(role="assistant", content=""), done: True, done_reason: "stop" + response: message=Message(role="assistant", tool_calls=[...]) + response: message=Message(role="assistant", content=""), done: True, done_reason: "stop" + + This generator conforms to the chatlog delta stream expectations in that it + yields deltas, then the role only once the response is done. + """ + + new_msg = True + async for response in result: + _LOGGER.debug("Received response: %s", response) + response_message = response["message"] + chunk: conversation.AssistantContentDeltaDict = {} + if new_msg: + new_msg = False + chunk["role"] = "assistant" + if (tool_calls := response_message.get("tool_calls")) is not None: + chunk["tool_calls"] = [ + llm.ToolInput( + tool_name=tool_call["function"]["name"], + tool_args=_parse_tool_args(tool_call["function"]["arguments"]), + ) + for tool_call in tool_calls + ] + if (content := response_message.get("content")) is not None: + chunk["content"] = content + if response_message.get("done"): + new_msg = True + yield chunk + + class OllamaConversationEntity( conversation.ConversationEntity, conversation.AbstractConversationAgent ): @@ -105,7 +178,6 @@ class OllamaConversationEntity( self.entry = entry # conversation id -> message history - self._history: dict[str, MessageHistory] = {} self._attr_name = entry.title self._attr_unique_id = entry.entry_id if self.entry.options.get(CONF_LLM_HASS_API): @@ -138,208 +210,112 @@ class OllamaConversationEntity( self, user_input: conversation.ConversationInput ) -> conversation.ConversationResult: """Process a sentence.""" + with ( + chat_session.async_get_chat_session( + self.hass, user_input.conversation_id + ) as session, + conversation.async_get_chat_log(self.hass, session, user_input) as chat_log, + ): + return await self._async_handle_message(user_input, chat_log) + + async def _async_handle_message( + self, + user_input: conversation.ConversationInput, + chat_log: conversation.ChatLog, + ) -> conversation.ConversationResult: + """Call the API.""" settings = {**self.entry.data, **self.entry.options} client = self.hass.data[DOMAIN][self.entry.entry_id] - conversation_id = user_input.conversation_id or ulid_util.ulid_now() model = settings[CONF_MODEL] - intent_response = intent.IntentResponse(language=user_input.language) - llm_api: llm.APIInstance | None = None - tools: list[dict[str, Any]] | None = None - user_name: str | None = None - llm_context = llm.LLMContext( - platform=DOMAIN, - context=user_input.context, - user_prompt=user_input.text, - language=user_input.language, - assistant=conversation.DOMAIN, - device_id=user_input.device_id, - ) - if settings.get(CONF_LLM_HASS_API): - try: - llm_api = await llm.async_get_api( - self.hass, - settings[CONF_LLM_HASS_API], - llm_context, - ) - except HomeAssistantError as err: - _LOGGER.error("Error getting LLM API: %s", err) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Error preparing LLM API: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=user_input.conversation_id - ) + try: + await chat_log.async_update_llm_data( + DOMAIN, + user_input, + settings.get(CONF_LLM_HASS_API), + settings.get(CONF_PROMPT), + ) + except conversation.ConverseError as err: + return err.as_conversation_result() + + tools: list[dict[str, Any]] | None = None + if chat_log.llm_api: tools = [ - _format_tool(tool, llm_api.custom_serializer) for tool in llm_api.tools + _format_tool(tool, chat_log.llm_api.custom_serializer) + for tool in chat_log.llm_api.tools ] - if ( - user_input.context - and user_input.context.user_id - and ( - user := await self.hass.auth.async_get_user(user_input.context.user_id) - ) - ): - user_name = user.name - - # Look up message history - message_history: MessageHistory | None = None - message_history = self._history.get(conversation_id) - if message_history is None: - # New history - # - # Render prompt and error out early if there's a problem - try: - prompt_parts = [ - template.Template( - llm.BASE_PROMPT - + settings.get(CONF_PROMPT, llm.DEFAULT_INSTRUCTIONS_PROMPT), - self.hass, - ).async_render( - { - "ha_name": self.hass.config.location_name, - "user_name": user_name, - "llm_context": llm_context, - }, - parse_result=False, - ) - ] - - except TemplateError as err: - _LOGGER.error("Error rendering prompt: %s", err) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Sorry, I had a problem generating my prompt: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id - ) - - if llm_api: - prompt_parts.append(llm_api.api_prompt) - - prompt = "\n".join(prompt_parts) - _LOGGER.debug("Prompt: %s", prompt) - _LOGGER.debug("Tools: %s", tools) - - message_history = MessageHistory( - timestamp=time.monotonic(), - messages=[ - ollama.Message(role=MessageRole.SYSTEM.value, content=prompt) - ], - ) - self._history[conversation_id] = message_history - else: - # Bump timestamp so this conversation won't get cleaned up - message_history.timestamp = time.monotonic() - - # Clean up old histories - self._prune_old_histories() - - # Trim this message history to keep a maximum number of *user* messages + message_history: MessageHistory = MessageHistory( + [_convert_content(content) for content in chat_log.content] + ) max_messages = int(settings.get(CONF_MAX_HISTORY, DEFAULT_MAX_HISTORY)) self._trim_history(message_history, max_messages) - # Add new user message - message_history.messages.append( - ollama.Message(role=MessageRole.USER.value, content=user_input.text) - ) - - trace.async_conversation_trace_append( - trace.ConversationTraceEventType.AGENT_DETAIL, - {"messages": message_history.messages}, - ) - # Get response # To prevent infinite loops, we limit the number of iterations for _iteration in range(MAX_TOOL_ITERATIONS): try: - response = await client.chat( + response_generator = await client.chat( model=model, # Make a copy of the messages because we mutate the list later messages=list(message_history.messages), tools=tools, - stream=False, + stream=True, # keep_alive requires specifying unit. In this case, seconds keep_alive=f"{settings.get(CONF_KEEP_ALIVE, DEFAULT_KEEP_ALIVE)}s", options={CONF_NUM_CTX: settings.get(CONF_NUM_CTX, DEFAULT_NUM_CTX)}, ) except (ollama.RequestError, ollama.ResponseError) as err: _LOGGER.error("Unexpected error talking to Ollama server: %s", err) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - f"Sorry, I had a problem talking to the Ollama server: {err}", - ) - return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id - ) + raise HomeAssistantError( + f"Sorry, I had a problem talking to the Ollama server: {err}" + ) from err - response_message = response["message"] - message_history.messages.append( - ollama.Message( - role=response_message["role"], - content=response_message.get("content"), - tool_calls=response_message.get("tool_calls"), - ) + message_history.messages.extend( + [ + _convert_content(content) + async for content in chat_log.async_add_delta_content_stream( + user_input.agent_id, _transform_stream(response_generator) + ) + ] ) - tool_calls = response_message.get("tool_calls") - if not tool_calls or not llm_api: + if not chat_log.unresponded_tool_results: break - for tool_call in tool_calls: - tool_input = llm.ToolInput( - tool_name=tool_call["function"]["name"], - tool_args=_parse_tool_args(tool_call["function"]["arguments"]), - ) - _LOGGER.debug( - "Tool call: %s(%s)", tool_input.tool_name, tool_input.tool_args - ) - - try: - tool_response = await llm_api.async_call_tool(tool_input) - except (HomeAssistantError, vol.Invalid) as e: - tool_response = {"error": type(e).__name__} - if str(e): - tool_response["error_text"] = str(e) - - _LOGGER.debug("Tool response: %s", tool_response) - message_history.messages.append( - ollama.Message( - role=MessageRole.TOOL.value, - content=json.dumps(tool_response), - ) - ) - # Create intent response - intent_response.async_set_speech(response_message["content"]) + intent_response = intent.IntentResponse(language=user_input.language) + if not isinstance(chat_log.content[-1], conversation.AssistantContent): + raise TypeError( + f"Unexpected last message type: {type(chat_log.content[-1])}" + ) + intent_response.async_set_speech(chat_log.content[-1].content or "") return conversation.ConversationResult( - response=intent_response, conversation_id=conversation_id + response=intent_response, conversation_id=chat_log.conversation_id ) - def _prune_old_histories(self) -> None: - """Remove old message histories.""" - now = time.monotonic() - self._history = { - conversation_id: message_history - for conversation_id, message_history in self._history.items() - if (now - message_history.timestamp) <= MAX_HISTORY_SECONDS - } - def _trim_history(self, message_history: MessageHistory, max_messages: int) -> None: - """Trims excess messages from a single history.""" + """Trims excess messages from a single history. + + This sets the max history to allow a configurable size history may take + up in the context window. + + Note that some messages in the history may not be from ollama only, and + may come from other anents, so the assumptions here may not strictly hold, + but generally should be effective. + """ if max_messages < 1: # Keep all messages return - if message_history.num_user_messages >= max_messages: + # Ignore the in progress user message + num_previous_rounds = message_history.num_user_messages - 1 + if num_previous_rounds >= max_messages: # Trim history but keep system prompt (first message). # Every other message should be an assistant message, so keep 2x - # message objects. - num_keep = 2 * max_messages + # message objects. Also keep the last in progress user message + num_keep = 2 * max_messages + 1 drop_index = len(message_history.messages) - num_keep message_history.messages = [ message_history.messages[0] diff --git a/homeassistant/components/ollama/models.py b/homeassistant/components/ollama/models.py index 3b6fc958587..fd268664919 100644 --- a/homeassistant/components/ollama/models.py +++ b/homeassistant/components/ollama/models.py @@ -19,9 +19,6 @@ class MessageRole(StrEnum): class MessageHistory: """Chat message history.""" - timestamp: float - """Timestamp of last use in seconds.""" - messages: list[ollama.Message] """List of message history, including system prompt and assistant responses.""" diff --git a/homeassistant/components/omnilogic/sensor.py b/homeassistant/components/omnilogic/sensor.py index c87b589e1f6..d941eb3ae4d 100644 --- a/homeassistant/components/omnilogic/sensor.py +++ b/homeassistant/components/omnilogic/sensor.py @@ -13,7 +13,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import check_guard from .const import COORDINATOR, DEFAULT_PH_OFFSET, DOMAIN, PUMP_TYPES @@ -22,7 +22,9 @@ from .entity import OmniLogicEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/omnilogic/switch.py b/homeassistant/components/omnilogic/switch.py index eb57d03bc34..a9f8bc77d8a 100644 --- a/homeassistant/components/omnilogic/switch.py +++ b/homeassistant/components/omnilogic/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import check_guard from .const import COORDINATOR, DOMAIN, PUMP_TYPES @@ -22,7 +22,9 @@ OMNILOGIC_SWITCH_OFF = 7 async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the light platform.""" diff --git a/homeassistant/components/onboarding/views.py b/homeassistant/components/onboarding/views.py index 1e29860e3c5..cb0dc4fdfa7 100644 --- a/homeassistant/components/onboarding/views.py +++ b/homeassistant/components/onboarding/views.py @@ -357,7 +357,7 @@ def with_backup_manager[_ViewT: BackupOnboardingView, **_P]( manager = async_get_backup_manager(request.app[KEY_HASS]) except HomeAssistantError: return self.json( - {"error": "backup_disabled"}, + {"code": "backup_disabled"}, status_code=HTTPStatus.INTERNAL_SERVER_ERROR, ) @@ -420,7 +420,12 @@ class RestoreBackupView(BackupOnboardingView): ) except IncorrectPasswordError: return self.json( - {"message": "incorrect_password"}, status_code=HTTPStatus.BAD_REQUEST + {"code": "incorrect_password"}, status_code=HTTPStatus.BAD_REQUEST + ) + except HomeAssistantError as err: + return self.json( + {"code": "restore_failed", "message": str(err)}, + status_code=HTTPStatus.BAD_REQUEST, ) return web.Response(status=HTTPStatus.OK) diff --git a/homeassistant/components/oncue/binary_sensor.py b/homeassistant/components/oncue/binary_sensor.py index 961b082a5c5..8dc9ba1be6f 100644 --- a/homeassistant/components/oncue/binary_sensor.py +++ b/homeassistant/components/oncue/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import OncueEntity from .types import OncueConfigEntry @@ -28,7 +28,7 @@ SENSOR_MAP = {description.key: description for description in SENSOR_TYPES} async def async_setup_entry( hass: HomeAssistant, config_entry: OncueConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/oncue/sensor.py b/homeassistant/components/oncue/sensor.py index a0f275ef692..669c34157d4 100644 --- a/homeassistant/components/oncue/sensor.py +++ b/homeassistant/components/oncue/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .entity import OncueEntity @@ -180,7 +180,7 @@ UNIT_MAPPINGS = { async def async_setup_entry( hass: HomeAssistant, config_entry: OncueConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/ondilo_ico/__init__.py b/homeassistant/components/ondilo_ico/__init__.py index fb78035c630..ddcd7ab8831 100644 --- a/homeassistant/components/ondilo_ico/__init__.py +++ b/homeassistant/components/ondilo_ico/__init__.py @@ -8,7 +8,7 @@ from homeassistant.helpers import config_entry_oauth2_flow from .api import OndiloClient from .config_flow import OndiloIcoOAuth2FlowHandler from .const import DOMAIN -from .coordinator import OndiloIcoCoordinator +from .coordinator import OndiloIcoPoolsCoordinator from .oauth_impl import OndiloOauth2Implementation PLATFORMS = [Platform.SENSOR] @@ -28,7 +28,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) ) - coordinator = OndiloIcoCoordinator(hass, OndiloClient(hass, entry, implementation)) + coordinator = OndiloIcoPoolsCoordinator( + hass, entry, OndiloClient(hass, entry, implementation) + ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/ondilo_ico/coordinator.py b/homeassistant/components/ondilo_ico/coordinator.py index ff1502a89fd..7545f6d61e0 100644 --- a/homeassistant/components/ondilo_ico/coordinator.py +++ b/homeassistant/components/ondilo_ico/coordinator.py @@ -1,77 +1,191 @@ """Define an object to coordinate fetching Ondilo ICO data.""" -from dataclasses import dataclass -from datetime import timedelta +from __future__ import annotations + +import asyncio +from dataclasses import dataclass, field +from datetime import datetime, timedelta import logging from typing import Any from ondilo import OndiloError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +from homeassistant.util import dt as dt_util from . import DOMAIN from .api import OndiloClient _LOGGER = logging.getLogger(__name__) +TIME_TO_NEXT_UPDATE = timedelta(hours=1, minutes=5) +UPDATE_LOCK = asyncio.Lock() + @dataclass -class OndiloIcoData: - """Class for storing the data.""" +class OndiloIcoPoolData: + """Store the pools the data.""" ico: dict[str, Any] pool: dict[str, Any] + measures_coordinator: OndiloIcoMeasuresCoordinator = field(init=False) + + +@dataclass +class OndiloIcoMeasurementData: + """Store the measurement data for one pool.""" + sensors: dict[str, Any] -class OndiloIcoCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoData]]): - """Class to manage fetching Ondilo ICO data from API.""" +class OndiloIcoPoolsCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoPoolData]]): + """Fetch Ondilo ICO pools data from API.""" - def __init__(self, hass: HomeAssistant, api: OndiloClient) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: OndiloClient + ) -> None: """Initialize.""" super().__init__( hass, logger=_LOGGER, - name=DOMAIN, - update_interval=timedelta(hours=1), + config_entry=config_entry, + name=f"{DOMAIN}_pools", + update_interval=timedelta(minutes=20), ) self.api = api + self.config_entry = config_entry + self._device_registry = dr.async_get(self.hass) - async def _async_update_data(self) -> dict[str, OndiloIcoData]: - """Fetch data from API endpoint.""" + async def _async_update_data(self) -> dict[str, OndiloIcoPoolData]: + """Fetch pools data from API endpoint and update devices.""" + known_pools: set[str] = set(self.data) if self.data else set() try: - return await self.hass.async_add_executor_job(self._update_data) + async with UPDATE_LOCK: + data = await self.hass.async_add_executor_job(self._update_data) except OndiloError as err: raise UpdateFailed(f"Error communicating with API: {err}") from err - def _update_data(self) -> dict[str, OndiloIcoData]: - """Fetch data from API endpoint.""" + current_pools = set(data) + + new_pools = current_pools - known_pools + for pool_id in new_pools: + pool_data = data[pool_id] + pool_data.measures_coordinator = OndiloIcoMeasuresCoordinator( + self.hass, self.config_entry, self.api, pool_id + ) + self._device_registry.async_get_or_create( + config_entry_id=self.config_entry.entry_id, + identifiers={(DOMAIN, pool_data.ico["serial_number"])}, + manufacturer="Ondilo", + model="ICO", + name=pool_data.pool["name"], + sw_version=pool_data.ico["sw_version"], + ) + + removed_pools = known_pools - current_pools + for pool_id in removed_pools: + pool_data = self.data.pop(pool_id) + await pool_data.measures_coordinator.async_shutdown() + device_entry = self._device_registry.async_get_device( + identifiers={(DOMAIN, pool_data.ico["serial_number"])} + ) + if device_entry: + self._device_registry.async_update_device( + device_id=device_entry.id, + remove_config_entry_id=self.config_entry.entry_id, + ) + + for pool_id in current_pools: + pool_data = data[pool_id] + measures_coordinator = pool_data.measures_coordinator + measures_coordinator.set_next_refresh(pool_data) + if not measures_coordinator.data: + await measures_coordinator.async_refresh() + + return data + + def _update_data(self) -> dict[str, OndiloIcoPoolData]: + """Fetch pools data from API endpoint.""" res = {} pools = self.api.get_pools() _LOGGER.debug("Pools: %s", pools) error: OndiloError | None = None for pool in pools: pool_id = pool["id"] + if (data := self.data) and pool_id in data: + pool_data = res[pool_id] = data[pool_id] + pool_data.pool = pool + # Skip requesting new ICO data for known pools + # to avoid unnecessary API calls. + continue try: ico = self.api.get_ICO_details(pool_id) - if not ico: - _LOGGER.debug( - "The pool id %s does not have any ICO attached", pool_id - ) - continue - sensors = self.api.get_last_pool_measures(pool_id) except OndiloError as err: error = err _LOGGER.debug("Error communicating with API for %s: %s", pool_id, err) continue - res[pool_id] = OndiloIcoData( - ico=ico, - pool=pool, - sensors={sensor["data_type"]: sensor["value"] for sensor in sensors}, - ) + + if not ico: + _LOGGER.debug("The pool id %s does not have any ICO attached", pool_id) + continue + + res[pool_id] = OndiloIcoPoolData(ico=ico, pool=pool) if not res: if error: raise UpdateFailed(f"Error communicating with API: {error}") from error - raise UpdateFailed("No data available") return res + + +class OndiloIcoMeasuresCoordinator(DataUpdateCoordinator[OndiloIcoMeasurementData]): + """Fetch Ondilo ICO measurement data for one pool from API.""" + + def __init__( + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + api: OndiloClient, + pool_id: str, + ) -> None: + """Initialize.""" + super().__init__( + hass, + config_entry=config_entry, + logger=_LOGGER, + name=f"{DOMAIN}_measures_{pool_id}", + ) + self.api = api + self._next_refresh: datetime | None = None + self._pool_id = pool_id + + async def _async_update_data(self) -> OndiloIcoMeasurementData: + """Fetch measurement data from API endpoint.""" + async with UPDATE_LOCK: + data = await self.hass.async_add_executor_job(self._update_data) + if next_refresh := self._next_refresh: + now = dt_util.utcnow() + # If we've missed the next refresh, schedule a refresh in one hour. + if next_refresh <= now: + next_refresh = now + timedelta(hours=1) + self.update_interval = next_refresh - now + + return data + + def _update_data(self) -> OndiloIcoMeasurementData: + """Fetch measurement data from API endpoint.""" + try: + sensors = self.api.get_last_pool_measures(self._pool_id) + except OndiloError as err: + raise UpdateFailed(f"Error communicating with API: {err}") from err + return OndiloIcoMeasurementData( + sensors={sensor["data_type"]: sensor["value"] for sensor in sensors}, + ) + + def set_next_refresh(self, pool_data: OndiloIcoPoolData) -> None: + """Set next refresh of this coordinator.""" + last_update = datetime.fromisoformat(pool_data.pool["updated_at"]) + self._next_refresh = last_update + TIME_TO_NEXT_UPDATE diff --git a/homeassistant/components/ondilo_ico/sensor.py b/homeassistant/components/ondilo_ico/sensor.py index 66b07335663..ddc4a94853f 100644 --- a/homeassistant/components/ondilo_ico/sensor.py +++ b/homeassistant/components/ondilo_ico/sensor.py @@ -15,14 +15,18 @@ from homeassistant.const import ( UnitOfElectricPotential, UnitOfTemperature, ) -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN -from .coordinator import OndiloIcoCoordinator, OndiloIcoData +from .coordinator import ( + OndiloIcoMeasuresCoordinator, + OndiloIcoPoolData, + OndiloIcoPoolsCoordinator, +) SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( SensorEntityDescription( @@ -70,53 +74,72 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ondilo ICO sensors.""" + pools_coordinator: OndiloIcoPoolsCoordinator = hass.data[DOMAIN][entry.entry_id] + known_entities: set[str] = set() - coordinator: OndiloIcoCoordinator = hass.data[DOMAIN][entry.entry_id] + async_add_entities(get_new_entities(pools_coordinator, known_entities)) - async_add_entities( - OndiloICO(coordinator, pool_id, description) - for pool_id, pool in coordinator.data.items() - for description in SENSOR_TYPES - if description.key in pool.sensors - ) + @callback + def add_new_entities(): + """Add any new entities after update of the pools coordinator.""" + async_add_entities(get_new_entities(pools_coordinator, known_entities)) + + entry.async_on_unload(pools_coordinator.async_add_listener(add_new_entities)) -class OndiloICO(CoordinatorEntity[OndiloIcoCoordinator], SensorEntity): +@callback +def get_new_entities( + pools_coordinator: OndiloIcoPoolsCoordinator, + known_entities: set[str], +) -> list[OndiloICO]: + """Return new Ondilo ICO sensor entities.""" + entities = [] + for pool_id, pool_data in pools_coordinator.data.items(): + for description in SENSOR_TYPES: + measurement_id = f"{pool_id}-{description.key}" + if ( + measurement_id in known_entities + or (data := pool_data.measures_coordinator.data) is None + or description.key not in data.sensors + ): + continue + known_entities.add(measurement_id) + entities.append( + OndiloICO( + pool_data.measures_coordinator, description, pool_id, pool_data + ) + ) + + return entities + + +class OndiloICO(CoordinatorEntity[OndiloIcoMeasuresCoordinator], SensorEntity): """Representation of a Sensor.""" _attr_has_entity_name = True def __init__( self, - coordinator: OndiloIcoCoordinator, - pool_id: str, + coordinator: OndiloIcoMeasuresCoordinator, description: SensorEntityDescription, + pool_id: str, + pool_data: OndiloIcoPoolData, ) -> None: """Initialize sensor entity with data from coordinator.""" super().__init__(coordinator) self.entity_description = description - self._pool_id = pool_id - - data = self.pool_data - self._attr_unique_id = f"{data.ico['serial_number']}-{description.key}" + self._attr_unique_id = f"{pool_data.ico['serial_number']}-{description.key}" self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, data.ico["serial_number"])}, - manufacturer="Ondilo", - model="ICO", - name=data.pool["name"], - sw_version=data.ico["sw_version"], + identifiers={(DOMAIN, pool_data.ico["serial_number"])}, ) - @property - def pool_data(self) -> OndiloIcoData: - """Get pool data.""" - return self.coordinator.data[self._pool_id] - @property def native_value(self) -> StateType: """Last value of the sensor.""" - return self.pool_data.sensors[self.entity_description.key] + return self.coordinator.data.sensors[self.entity_description.key] diff --git a/homeassistant/components/onedrive/backup.py b/homeassistant/components/onedrive/backup.py index 9926bd9cbc7..343c332f384 100644 --- a/homeassistant/components/onedrive/backup.py +++ b/homeassistant/components/onedrive/backup.py @@ -3,10 +3,12 @@ from __future__ import annotations from collections.abc import AsyncIterator, Callable, Coroutine +from dataclasses import dataclass from functools import wraps from html import unescape from json import dumps, loads import logging +from time import time from typing import Any, Concatenate from aiohttp import ClientTimeout @@ -16,7 +18,7 @@ from onedrive_personal_sdk.exceptions import ( HashMismatchError, OneDriveException, ) -from onedrive_personal_sdk.models.items import File, Folder, ItemUpdate +from onedrive_personal_sdk.models.items import ItemUpdate from onedrive_personal_sdk.models.upload import FileInfo from homeassistant.components.backup import ( @@ -35,6 +37,7 @@ _LOGGER = logging.getLogger(__name__) UPLOAD_CHUNK_SIZE = 16 * 320 * 1024 # 5.2MB TIMEOUT = ClientTimeout(connect=10, total=43200) # 12 hours METADATA_VERSION = 2 +CACHE_TTL = 300 async def async_get_backup_agents( @@ -99,6 +102,15 @@ def handle_backup_errors[_R, **P]( return wrapper +@dataclass(kw_only=True) +class OneDriveBackup: + """Define a OneDrive backup.""" + + backup: AgentBackup + backup_file_id: str + metadata_file_id: str + + class OneDriveBackupAgent(BackupAgent): """OneDrive backup agent.""" @@ -115,24 +127,20 @@ class OneDriveBackupAgent(BackupAgent): self.name = entry.title assert entry.unique_id self.unique_id = entry.unique_id + self._backup_cache: dict[str, OneDriveBackup] = {} + self._cache_expiration = time() @handle_backup_errors async def async_download_backup( self, backup_id: str, **kwargs: Any ) -> AsyncIterator[bytes]: """Download a backup file.""" - metadata_item = await self._find_item_by_backup_id(backup_id) - if ( - metadata_item is None - or metadata_item.description is None - or "backup_file_id" not in metadata_item.description - ): + backups = await self._list_cached_backups() + if backup_id not in backups: raise BackupAgentError("Backup not found") - metadata_info = loads(unescape(metadata_item.description)) - stream = await self._client.download_drive_item( - metadata_info["backup_file_id"], timeout=TIMEOUT + backups[backup_id].backup_file_id, timeout=TIMEOUT ) return stream.iter_chunked(1024) @@ -181,6 +189,7 @@ class OneDriveBackupAgent(BackupAgent): path_or_id=metadata_file.id, data=ItemUpdate(description=dumps(metadata_description)), ) + self._cache_expiration = time() @handle_backup_errors async def async_delete_backup( @@ -189,28 +198,21 @@ class OneDriveBackupAgent(BackupAgent): **kwargs: Any, ) -> None: """Delete a backup file.""" - metadata_item = await self._find_item_by_backup_id(backup_id) - if ( - metadata_item is None - or metadata_item.description is None - or "backup_file_id" not in metadata_item.description - ): + backups = await self._list_cached_backups() + if backup_id not in backups: return - metadata_info = loads(unescape(metadata_item.description)) - await self._client.delete_drive_item(metadata_info["backup_file_id"]) - await self._client.delete_drive_item(metadata_item.id) + backup = backups[backup_id] + + await self._client.delete_drive_item(backup.backup_file_id) + await self._client.delete_drive_item(backup.metadata_file_id) + self._cache_expiration = time() @handle_backup_errors async def async_list_backups(self, **kwargs: Any) -> list[AgentBackup]: """List backups.""" - items = await self._client.list_drive_items(self._folder_id) return [ - await self._download_backup_metadata(item.id) - for item in items - if item.description - and "backup_id" in item.description - and f'"metadata_version": {METADATA_VERSION}' in unescape(item.description) + backup.backup for backup in (await self._list_cached_backups()).values() ] @handle_backup_errors @@ -218,27 +220,34 @@ class OneDriveBackupAgent(BackupAgent): self, backup_id: str, **kwargs: Any ) -> AgentBackup | None: """Return a backup.""" - metadata_file = await self._find_item_by_backup_id(backup_id) - if metadata_file is None or metadata_file.description is None: - return None + backups = await self._list_cached_backups() + return backups[backup_id].backup if backup_id in backups else None - return await self._download_backup_metadata(metadata_file.id) + async def _list_cached_backups(self) -> dict[str, OneDriveBackup]: + """List backups with a cache.""" + if time() <= self._cache_expiration: + return self._backup_cache - async def _find_item_by_backup_id(self, backup_id: str) -> File | Folder | None: - """Find an item by backup ID.""" - return next( - ( - item - for item in await self._client.list_drive_items(self._folder_id) - if item.description - and backup_id in item.description - and f'"metadata_version": {METADATA_VERSION}' - in unescape(item.description) - ), - None, - ) + items = await self._client.list_drive_items(self._folder_id) - async def _download_backup_metadata(self, item_id: str) -> AgentBackup: - metadata_stream = await self._client.download_drive_item(item_id) - metadata_json = loads(await metadata_stream.read()) - return AgentBackup.from_dict(metadata_json) + async def download_backup_metadata(item_id: str) -> AgentBackup: + metadata_stream = await self._client.download_drive_item(item_id) + metadata_json = loads(await metadata_stream.read()) + return AgentBackup.from_dict(metadata_json) + + backups: dict[str, OneDriveBackup] = {} + for item in items: + if item.description and f'"metadata_version": {METADATA_VERSION}' in ( + metadata_description_json := unescape(item.description) + ): + backup = await download_backup_metadata(item.id) + metadata_description = loads(metadata_description_json) + backups[backup.backup_id] = OneDriveBackup( + backup=backup, + backup_file_id=metadata_description["backup_file_id"], + metadata_file_id=item.id, + ) + + self._cache_expiration = time() + CACHE_TTL + self._backup_cache = backups + return backups diff --git a/homeassistant/components/onedrive/manifest.json b/homeassistant/components/onedrive/manifest.json index fcc922b3e46..899a5e77b47 100644 --- a/homeassistant/components/onedrive/manifest.json +++ b/homeassistant/components/onedrive/manifest.json @@ -9,5 +9,5 @@ "iot_class": "cloud_polling", "loggers": ["onedrive_personal_sdk"], "quality_scale": "bronze", - "requirements": ["onedrive-personal-sdk==0.0.9"] + "requirements": ["onedrive-personal-sdk==0.0.10"] } diff --git a/homeassistant/components/onewire/binary_sensor.py b/homeassistant/components/onewire/binary_sensor.py index 60a1d165b15..2bb393e48a8 100644 --- a/homeassistant/components/onewire/binary_sensor.py +++ b/homeassistant/components/onewire/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEVICE_KEYS_0_3, DEVICE_KEYS_0_7, DEVICE_KEYS_A_B, READ_MODE_BOOL from .entity import OneWireEntity, OneWireEntityDescription @@ -101,7 +101,7 @@ def get_sensor_types( async def async_setup_entry( hass: HomeAssistant, config_entry: OneWireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up 1-Wire platform.""" diff --git a/homeassistant/components/onewire/select.py b/homeassistant/components/onewire/select.py index 7a26ecdbb31..7f4111243aa 100644 --- a/homeassistant/components/onewire/select.py +++ b/homeassistant/components/onewire/select.py @@ -10,7 +10,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import READ_MODE_INT from .entity import OneWireEntity, OneWireEntityDescription @@ -48,7 +48,7 @@ ENTITY_DESCRIPTIONS: dict[str, tuple[OneWireEntityDescription, ...]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: OneWireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up 1-Wire platform.""" diff --git a/homeassistant/components/onewire/sensor.py b/homeassistant/components/onewire/sensor.py index 04141f87847..5e1c7d35bd6 100644 --- a/homeassistant/components/onewire/sensor.py +++ b/homeassistant/components/onewire/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -388,7 +388,7 @@ def get_sensor_types( async def async_setup_entry( hass: HomeAssistant, config_entry: OneWireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up 1-Wire platform.""" diff --git a/homeassistant/components/onewire/switch.py b/homeassistant/components/onewire/switch.py index 7215b1ec020..d2cc3b80185 100644 --- a/homeassistant/components/onewire/switch.py +++ b/homeassistant/components/onewire/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEVICE_KEYS_0_3, DEVICE_KEYS_0_7, DEVICE_KEYS_A_B, READ_MODE_BOOL from .entity import OneWireEntity, OneWireEntityDescription @@ -161,7 +161,7 @@ def get_sensor_types( async def async_setup_entry( hass: HomeAssistant, config_entry: OneWireConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up 1-Wire platform.""" diff --git a/homeassistant/components/onkyo/media_player.py b/homeassistant/components/onkyo/media_player.py index acb57e594b8..711cede15bc 100644 --- a/homeassistant/components/onkyo/media_player.py +++ b/homeassistant/components/onkyo/media_player.py @@ -22,7 +22,10 @@ from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, ca from homeassistant.data_entry_flow import FlowResultType from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -286,7 +289,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: OnkyoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MediaPlayer for config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/onvif/binary_sensor.py b/homeassistant/components/onvif/binary_sensor.py index 92c5ab45129..d29f732ef67 100644 --- a/homeassistant/components/onvif/binary_sensor.py +++ b/homeassistant/components/onvif/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.util.enum import try_parse_enum @@ -22,7 +22,7 @@ from .entity import ONVIFBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a ONVIF binary sensor.""" device: ONVIFDevice = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/onvif/button.py b/homeassistant/components/onvif/button.py index 644a7c942f7..8e92cb07a8c 100644 --- a/homeassistant/components/onvif/button.py +++ b/homeassistant/components/onvif/button.py @@ -4,7 +4,7 @@ from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .device import ONVIFDevice @@ -14,7 +14,7 @@ from .entity import ONVIFBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ONVIF button based on a config entry.""" device = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/onvif/camera.py b/homeassistant/components/onvif/camera.py index 8c0fd027b95..da99e170ff6 100644 --- a/homeassistant/components/onvif/camera.py +++ b/homeassistant/components/onvif/camera.py @@ -22,7 +22,7 @@ from homeassistant.const import HTTP_BASIC_AUTHENTICATION from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ABSOLUTE_MOVE, @@ -57,7 +57,7 @@ from .models import Profile async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ONVIF camera video stream.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/onvif/sensor.py b/homeassistant/components/onvif/sensor.py index 46db26361bc..a0162a05f76 100644 --- a/homeassistant/components/onvif/sensor.py +++ b/homeassistant/components/onvif/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import RestoreSensor, SensorDeviceClass from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.enum import try_parse_enum @@ -21,7 +21,7 @@ from .entity import ONVIFBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a ONVIF binary sensor.""" device: ONVIFDevice = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/onvif/switch.py b/homeassistant/components/onvif/switch.py index ff62e469af0..d8e1020c6a3 100644 --- a/homeassistant/components/onvif/switch.py +++ b/homeassistant/components/onvif/switch.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .device import ONVIFDevice @@ -66,7 +66,7 @@ SWITCHES: tuple[ONVIFSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a ONVIF switch platform.""" device = hass.data[DOMAIN][config_entry.unique_id] diff --git a/homeassistant/components/open_meteo/weather.py b/homeassistant/components/open_meteo/weather.py index 51ee91de083..9782051ab22 100644 --- a/homeassistant/components/open_meteo/weather.py +++ b/homeassistant/components/open_meteo/weather.py @@ -20,7 +20,7 @@ from homeassistant.components.weather import ( from homeassistant.const import UnitOfPrecipitationDepth, UnitOfSpeed, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util @@ -31,7 +31,7 @@ from .coordinator import OpenMeteoConfigEntry async def async_setup_entry( hass: HomeAssistant, entry: OpenMeteoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Open-Meteo weather entity based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/openai_conversation/conversation.py b/homeassistant/components/openai_conversation/conversation.py index eaa62bd1adc..fddabb740ac 100644 --- a/homeassistant/components/openai_conversation/conversation.py +++ b/homeassistant/components/openai_conversation/conversation.py @@ -1,14 +1,15 @@ """Conversation support for OpenAI.""" -from collections.abc import Callable +from collections.abc import AsyncGenerator, Callable import json from typing import Any, Literal, cast import openai +from openai._streaming import AsyncStream from openai._types import NOT_GIVEN from openai.types.chat import ( ChatCompletionAssistantMessageParam, - ChatCompletionMessage, + ChatCompletionChunk, ChatCompletionMessageParam, ChatCompletionMessageToolCallParam, ChatCompletionToolMessageParam, @@ -24,7 +25,7 @@ from homeassistant.const import CONF_LLM_HASS_API, MATCH_ALL from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import chat_session, device_registry as dr, intent, llm -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenAIConfigEntry from .const import ( @@ -50,7 +51,7 @@ MAX_TOOL_ITERATIONS = 10 async def async_setup_entry( hass: HomeAssistant, config_entry: OpenAIConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up conversation entities.""" agent = OpenAIConversationEntity(config_entry) @@ -70,32 +71,6 @@ def _format_tool( return ChatCompletionToolParam(type="function", function=tool_spec) -def _convert_message_to_param( - message: ChatCompletionMessage, -) -> ChatCompletionMessageParam: - """Convert from class to TypedDict.""" - tool_calls: list[ChatCompletionMessageToolCallParam] = [] - if message.tool_calls: - tool_calls = [ - ChatCompletionMessageToolCallParam( - id=tool_call.id, - function=Function( - arguments=tool_call.function.arguments, - name=tool_call.function.name, - ), - type=tool_call.type, - ) - for tool_call in message.tool_calls - ] - param = ChatCompletionAssistantMessageParam( - role=message.role, - content=message.content, - ) - if tool_calls: - param["tool_calls"] = tool_calls - return param - - def _convert_content_to_param( content: conversation.Content, ) -> ChatCompletionMessageParam: @@ -135,6 +110,74 @@ def _convert_content_to_param( ) +async def _transform_stream( + result: AsyncStream[ChatCompletionChunk], +) -> AsyncGenerator[conversation.AssistantContentDeltaDict]: + """Transform an OpenAI delta stream into HA format.""" + current_tool_call: dict | None = None + + async for chunk in result: + LOGGER.debug("Received chunk: %s", chunk) + choice = chunk.choices[0] + + if choice.finish_reason: + if current_tool_call: + yield { + "tool_calls": [ + llm.ToolInput( + id=current_tool_call["id"], + tool_name=current_tool_call["tool_name"], + tool_args=json.loads(current_tool_call["tool_args"]), + ) + ] + } + + break + + delta = chunk.choices[0].delta + + # We can yield delta messages not continuing or starting tool calls + if current_tool_call is None and not delta.tool_calls: + yield { # type: ignore[misc] + key: value + for key in ("role", "content") + if (value := getattr(delta, key)) is not None + } + continue + + # When doing tool calls, we should always have a tool call + # object or we have gotten stopped above with a finish_reason set. + if ( + not delta.tool_calls + or not (delta_tool_call := delta.tool_calls[0]) + or not delta_tool_call.function + ): + raise ValueError("Expected delta with tool call") + + if current_tool_call and delta_tool_call.index == current_tool_call["index"]: + current_tool_call["tool_args"] += delta_tool_call.function.arguments or "" + continue + + # We got tool call with new index, so we need to yield the previous + if current_tool_call: + yield { + "tool_calls": [ + llm.ToolInput( + id=current_tool_call["id"], + tool_name=current_tool_call["tool_name"], + tool_args=json.loads(current_tool_call["tool_args"]), + ) + ] + } + + current_tool_call = { + "index": delta_tool_call.index, + "id": delta_tool_call.id, + "tool_name": delta_tool_call.function.name, + "tool_args": delta_tool_call.function.arguments or "", + } + + class OpenAIConversationEntity( conversation.ConversationEntity, conversation.AbstractConversationAgent ): @@ -234,6 +277,7 @@ class OpenAIConversationEntity( "top_p": options.get(CONF_TOP_P, RECOMMENDED_TOP_P), "temperature": options.get(CONF_TEMPERATURE, RECOMMENDED_TEMPERATURE), "user": chat_log.conversation_id, + "stream": True, } if model.startswith("o"): @@ -247,39 +291,21 @@ class OpenAIConversationEntity( LOGGER.error("Error talking to OpenAI: %s", err) raise HomeAssistantError("Error talking to OpenAI") from err - LOGGER.debug("Response %s", result) - response = result.choices[0].message - messages.append(_convert_message_to_param(response)) - - tool_calls: list[llm.ToolInput] | None = None - if response.tool_calls: - tool_calls = [ - llm.ToolInput( - id=tool_call.id, - tool_name=tool_call.function.name, - tool_args=json.loads(tool_call.function.arguments), - ) - for tool_call in response.tool_calls - ] - messages.extend( [ - _convert_content_to_param(tool_response) - async for tool_response in chat_log.async_add_assistant_content( - conversation.AssistantContent( - agent_id=user_input.agent_id, - content=response.content or "", - tool_calls=tool_calls, - ) + _convert_content_to_param(content) + async for content in chat_log.async_add_delta_content_stream( + user_input.agent_id, _transform_stream(result) ) ] ) - if not tool_calls: + if not chat_log.unresponded_tool_results: break intent_response = intent.IntentResponse(language=user_input.language) - intent_response.async_set_speech(response.content or "") + assert type(chat_log.content[-1]) is conversation.AssistantContent + intent_response.async_set_speech(chat_log.content[-1].content or "") return conversation.ConversationResult( response=intent_response, conversation_id=chat_log.conversation_id ) diff --git a/homeassistant/components/openexchangerates/__init__.py b/homeassistant/components/openexchangerates/__init__.py index 65005235c6b..ed704a61fed 100644 --- a/homeassistant/components/openexchangerates/__init__.py +++ b/homeassistant/components/openexchangerates/__init__.py @@ -33,6 +33,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: update_interval = BASE_UPDATE_INTERVAL * (len(existing_coordinator_for_api_key) + 1) coordinator = OpenexchangeratesCoordinator( hass, + entry, async_get_clientsession(hass), api_key, base, diff --git a/homeassistant/components/openexchangerates/coordinator.py b/homeassistant/components/openexchangerates/coordinator.py index 627e0d92e32..6245877ddbd 100644 --- a/homeassistant/components/openexchangerates/coordinator.py +++ b/homeassistant/components/openexchangerates/coordinator.py @@ -13,6 +13,7 @@ from aioopenexchangerates import ( OpenExchangeRatesClientError, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -23,9 +24,12 @@ from .const import CLIENT_TIMEOUT, DOMAIN, LOGGER class OpenexchangeratesCoordinator(DataUpdateCoordinator[Latest]): """Represent a coordinator for Open Exchange Rates API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, session: ClientSession, api_key: str, base: str, @@ -33,7 +37,11 @@ class OpenexchangeratesCoordinator(DataUpdateCoordinator[Latest]): ) -> None: """Initialize the coordinator.""" super().__init__( - hass, LOGGER, name=f"{DOMAIN} base {base}", update_interval=update_interval + hass, + LOGGER, + config_entry=config_entry, + name=f"{DOMAIN} base {base}", + update_interval=update_interval, ) self.base = base self.client = Client(api_key, session) diff --git a/homeassistant/components/openexchangerates/sensor.py b/homeassistant/components/openexchangerates/sensor.py index 55ca7bd2fb9..756823ff0ec 100644 --- a/homeassistant/components/openexchangerates/sensor.py +++ b/homeassistant/components/openexchangerates/sensor.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_QUOTE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -19,7 +19,7 @@ ATTRIBUTION = "Data provided by openexchangerates.org" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Open Exchange Rates sensor.""" quote: str = config_entry.data.get(CONF_QUOTE, "EUR") diff --git a/homeassistant/components/opengarage/__init__.py b/homeassistant/components/opengarage/__init__.py index 12c2f96d7e4..f1f080b30f8 100644 --- a/homeassistant/components/opengarage/__init__.py +++ b/homeassistant/components/opengarage/__init__.py @@ -24,8 +24,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async_get_clientsession(hass), ) open_garage_data_coordinator = OpenGarageDataUpdateCoordinator( - hass, - open_garage_connection=open_garage_connection, + hass, entry, open_garage_connection ) await open_garage_data_coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = open_garage_data_coordinator diff --git a/homeassistant/components/opengarage/binary_sensor.py b/homeassistant/components/opengarage/binary_sensor.py index 55cacfb5f90..33420ab3fd5 100644 --- a/homeassistant/components/opengarage/binary_sensor.py +++ b/homeassistant/components/opengarage/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import OpenGarageDataUpdateCoordinator @@ -29,7 +29,9 @@ SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenGarage binary sensors.""" open_garage_data_coordinator: OpenGarageDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/opengarage/button.py b/homeassistant/components/opengarage/button.py index 9f93e0fa716..64a4f2f20e7 100644 --- a/homeassistant/components/opengarage/button.py +++ b/homeassistant/components/opengarage/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import OpenGarageDataUpdateCoordinator @@ -43,7 +43,7 @@ BUTTONS: tuple[OpenGarageButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenGarage button entities.""" coordinator: OpenGarageDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/opengarage/coordinator.py b/homeassistant/components/opengarage/coordinator.py index d35dc22d288..5d5440d6b1b 100644 --- a/homeassistant/components/opengarage/coordinator.py +++ b/homeassistant/components/opengarage/coordinator.py @@ -8,6 +8,7 @@ from typing import Any import opengarage +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import update_coordinator from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -20,10 +21,12 @@ _LOGGER = logging.getLogger(__name__) class OpenGarageDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching Opengarage data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - *, + config_entry: ConfigEntry, open_garage_connection: opengarage.OpenGarage, ) -> None: """Initialize global Opengarage data updater.""" @@ -32,6 +35,7 @@ class OpenGarageDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=5), ) diff --git a/homeassistant/components/opengarage/cover.py b/homeassistant/components/opengarage/cover.py index 9623050c090..859e3382772 100644 --- a/homeassistant/components/opengarage/cover.py +++ b/homeassistant/components/opengarage/cover.py @@ -13,7 +13,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import OpenGarageDataUpdateCoordinator @@ -25,7 +25,9 @@ STATES_MAP = {0: CoverState.CLOSED, 1: CoverState.OPEN} async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenGarage covers.""" async_add_entities( diff --git a/homeassistant/components/opengarage/sensor.py b/homeassistant/components/opengarage/sensor.py index 003e0e0fa5a..14d14dd5d23 100644 --- a/homeassistant/components/opengarage/sensor.py +++ b/homeassistant/components/opengarage/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import OpenGarageDataUpdateCoordinator @@ -59,7 +59,9 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenGarage sensors.""" open_garage_data_coordinator: OpenGarageDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/openhome/media_player.py b/homeassistant/components/openhome/media_player.py index 8c903c90bbb..9f8840b8487 100644 --- a/homeassistant/components/openhome/media_player.py +++ b/homeassistant/components/openhome/media_player.py @@ -24,7 +24,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_PIN_INDEX, DOMAIN, SERVICE_INVOKE_PIN @@ -40,7 +40,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Openhome config entry.""" diff --git a/homeassistant/components/openhome/update.py b/homeassistant/components/openhome/update.py index bbe4fdac3b3..cc210866e64 100644 --- a/homeassistant/components/openhome/update.py +++ b/homeassistant/components/openhome/update.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entities for Reolink component.""" diff --git a/homeassistant/components/opensky/__init__.py b/homeassistant/components/opensky/__init__.py index c95dc1283a4..c69cade5842 100644 --- a/homeassistant/components/opensky/__init__.py +++ b/homeassistant/components/opensky/__init__.py @@ -32,7 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except OpenSkyError as exc: raise ConfigEntryNotReady from exc - coordinator = OpenSkyDataUpdateCoordinator(hass, client) + coordinator = OpenSkyDataUpdateCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/opensky/coordinator.py b/homeassistant/components/opensky/coordinator.py index f54e01b0006..f9aab88c904 100644 --- a/homeassistant/components/opensky/coordinator.py +++ b/homeassistant/components/opensky/coordinator.py @@ -36,11 +36,14 @@ class OpenSkyDataUpdateCoordinator(DataUpdateCoordinator[int]): config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant, opensky: OpenSky) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, opensky: OpenSky + ) -> None: """Initialize the OpenSky data coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval={ True: timedelta(seconds=90), @@ -50,11 +53,11 @@ class OpenSkyDataUpdateCoordinator(DataUpdateCoordinator[int]): self._opensky = opensky self._previously_tracked: set[str] | None = None self._bounding_box = OpenSky.get_bounding_box( - self.config_entry.data[CONF_LATITUDE], - self.config_entry.data[CONF_LONGITUDE], - self.config_entry.options[CONF_RADIUS], + config_entry.data[CONF_LATITUDE], + config_entry.data[CONF_LONGITUDE], + config_entry.options[CONF_RADIUS], ) - self._altitude = self.config_entry.options.get(CONF_ALTITUDE, DEFAULT_ALTITUDE) + self._altitude = config_entry.options.get(CONF_ALTITUDE, DEFAULT_ALTITUDE) async def _async_update_data(self) -> int: try: diff --git a/homeassistant/components/opensky/sensor.py b/homeassistant/components/opensky/sensor.py index 9d317ae3e0d..0ab5b49f086 100644 --- a/homeassistant/components/opensky/sensor.py +++ b/homeassistant/components/opensky/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER @@ -16,7 +16,7 @@ from .coordinator import OpenSkyDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize the entries.""" diff --git a/homeassistant/components/opentherm_gw/binary_sensor.py b/homeassistant/components/opentherm_gw/binary_sensor.py index 5d542bedc07..8e73392da05 100644 --- a/homeassistant/components/opentherm_gw/binary_sensor.py +++ b/homeassistant/components/opentherm_gw/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( BOILER_DEVICE_DESCRIPTION, @@ -393,7 +393,7 @@ BINARY_SENSOR_DESCRIPTIONS: tuple[OpenThermBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway binary sensors.""" gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] diff --git a/homeassistant/components/opentherm_gw/button.py b/homeassistant/components/opentherm_gw/button.py index 00b91ad33e0..046b44bfa8c 100644 --- a/homeassistant/components/opentherm_gw/button.py +++ b/homeassistant/components/opentherm_gw/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenThermGatewayHub from .const import ( @@ -53,7 +53,7 @@ BUTTON_DESCRIPTIONS: tuple[OpenThermButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway buttons.""" gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] diff --git a/homeassistant/components/opentherm_gw/climate.py b/homeassistant/components/opentherm_gw/climate.py index e8aa99f7325..c69151c293a 100644 --- a/homeassistant/components/opentherm_gw/climate.py +++ b/homeassistant/components/opentherm_gw/climate.py @@ -22,7 +22,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, CONF_ID, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenThermGatewayHub from .const import ( @@ -50,7 +50,7 @@ class OpenThermClimateEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an OpenTherm Gateway climate entity.""" ents = [] diff --git a/homeassistant/components/opentherm_gw/select.py b/homeassistant/components/opentherm_gw/select.py index cee1632dc48..da3fa1e80ec 100644 --- a/homeassistant/components/opentherm_gw/select.py +++ b/homeassistant/components/opentherm_gw/select.py @@ -20,7 +20,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenThermGatewayHub from .const import ( @@ -234,7 +234,7 @@ SELECT_DESCRIPTIONS: tuple[OpenThermSelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway select entities.""" gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] diff --git a/homeassistant/components/opentherm_gw/sensor.py b/homeassistant/components/opentherm_gw/sensor.py index 5ccb4166665..f9ac1b272be 100644 --- a/homeassistant/components/opentherm_gw/sensor.py +++ b/homeassistant/components/opentherm_gw/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( BOILER_DEVICE_DESCRIPTION, @@ -875,7 +875,7 @@ SENSOR_DESCRIPTIONS: tuple[OpenThermSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway sensors.""" gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] diff --git a/homeassistant/components/opentherm_gw/switch.py b/homeassistant/components/opentherm_gw/switch.py index 41ffa03a932..873675f0211 100644 --- a/homeassistant/components/opentherm_gw/switch.py +++ b/homeassistant/components/opentherm_gw/switch.py @@ -8,7 +8,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenThermGatewayHub from .const import DATA_GATEWAYS, DATA_OPENTHERM_GW, GATEWAY_DEVICE_DESCRIPTION @@ -48,7 +48,7 @@ SWITCH_DESCRIPTIONS: tuple[OpenThermSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway switches.""" gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] diff --git a/homeassistant/components/openuv/binary_sensor.py b/homeassistant/components/openuv/binary_sensor.py index 018d91710df..f45404ce38e 100644 --- a/homeassistant/components/openuv/binary_sensor.py +++ b/homeassistant/components/openuv/binary_sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import as_local, parse_datetime, utcnow from .const import DATA_PROTECTION_WINDOW, DOMAIN, LOGGER, TYPE_PROTECTION_WINDOW @@ -25,7 +25,9 @@ BINARY_SENSOR_DESCRIPTION_PROTECTION_WINDOW = BinarySensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: # Once we've successfully authenticated, we re-enable client request retries: """Set up an OpenUV sensor based on a config entry.""" diff --git a/homeassistant/components/openuv/coordinator.py b/homeassistant/components/openuv/coordinator.py index 32d502cb8ce..cc09161b3e9 100644 --- a/homeassistant/components/openuv/coordinator.py +++ b/homeassistant/components/openuv/coordinator.py @@ -38,6 +38,7 @@ class OpenUvCoordinator(DataUpdateCoordinator[dict[str, Any]]): super().__init__( hass, LOGGER, + config_entry=entry, name=name, update_method=update_method, request_refresh_debouncer=Debouncer( @@ -48,7 +49,6 @@ class OpenUvCoordinator(DataUpdateCoordinator[dict[str, Any]]): ), ) - self._entry = entry self.latitude = latitude self.longitude = longitude diff --git a/homeassistant/components/openuv/sensor.py b/homeassistant/components/openuv/sensor.py index 742017be639..5b681655e2b 100644 --- a/homeassistant/components/openuv/sensor.py +++ b/homeassistant/components/openuv/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UV_INDEX, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import as_local, parse_datetime from .const import ( @@ -166,7 +166,9 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a OpenUV sensor based on a config entry.""" coordinators: dict[str, OpenUvCoordinator] = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/openweathermap/__init__.py b/homeassistant/components/openweathermap/__init__.py index 33cd23c4f6c..fa51b91dc6d 100644 --- a/homeassistant/components/openweathermap/__init__.py +++ b/homeassistant/components/openweathermap/__init__.py @@ -8,14 +8,7 @@ import logging from pyopenweathermap import create_owm_client from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_API_KEY, - CONF_LANGUAGE, - CONF_LATITUDE, - CONF_LONGITUDE, - CONF_MODE, - CONF_NAME, -) +from homeassistant.const import CONF_API_KEY, CONF_LANGUAGE, CONF_MODE, CONF_NAME from homeassistant.core import HomeAssistant from .const import CONFIG_FLOW_VERSION, OWM_MODE_V25, PLATFORMS @@ -43,8 +36,6 @@ async def async_setup_entry( """Set up OpenWeatherMap as config entry.""" name = entry.data[CONF_NAME] api_key = entry.data[CONF_API_KEY] - latitude = entry.data.get(CONF_LATITUDE, hass.config.latitude) - longitude = entry.data.get(CONF_LONGITUDE, hass.config.longitude) language = entry.options[CONF_LANGUAGE] mode = entry.options[CONF_MODE] @@ -54,9 +45,7 @@ async def async_setup_entry( async_delete_issue(hass, entry.entry_id) owm_client = create_owm_client(api_key, mode, lang=language) - weather_coordinator = WeatherUpdateCoordinator( - owm_client, latitude, longitude, hass - ) + weather_coordinator = WeatherUpdateCoordinator(hass, entry, owm_client) await weather_coordinator.async_config_entry_first_refresh() @@ -69,7 +58,9 @@ async def async_setup_entry( return True -async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_migrate_entry( + hass: HomeAssistant, entry: OpenweathermapConfigEntry +) -> bool: """Migrate old entry.""" config_entries = hass.config_entries data = entry.data @@ -93,7 +84,9 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return True -async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def async_update_options( + hass: HomeAssistant, entry: OpenweathermapConfigEntry +) -> None: """Update options.""" await hass.config_entries.async_reload(entry.entry_id) diff --git a/homeassistant/components/openweathermap/coordinator.py b/homeassistant/components/openweathermap/coordinator.py index 3ef0eda0c8f..55c1aa469c2 100644 --- a/homeassistant/components/openweathermap/coordinator.py +++ b/homeassistant/components/openweathermap/coordinator.py @@ -1,7 +1,10 @@ """Weather data coordinator for the OpenWeatherMap (OWM) service.""" +from __future__ import annotations + from datetime import timedelta import logging +from typing import TYPE_CHECKING from pyopenweathermap import ( CurrentWeather, @@ -17,11 +20,15 @@ from homeassistant.components.weather import ( ATTR_CONDITION_SUNNY, Forecast, ) +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE from homeassistant.core import HomeAssistant from homeassistant.helpers import sun from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util +if TYPE_CHECKING: + from . import OpenweathermapConfigEntry + from .const import ( ATTR_API_CLOUDS, ATTR_API_CONDITION, @@ -56,20 +63,25 @@ WEATHER_UPDATE_INTERVAL = timedelta(minutes=10) class WeatherUpdateCoordinator(DataUpdateCoordinator): """Weather data update coordinator.""" + config_entry: OpenweathermapConfigEntry + def __init__( self, - owm_client: OWMClient, - latitude, - longitude, hass: HomeAssistant, + config_entry: OpenweathermapConfigEntry, + owm_client: OWMClient, ) -> None: """Initialize coordinator.""" self._owm_client = owm_client - self._latitude = latitude - self._longitude = longitude + self._latitude = config_entry.data.get(CONF_LATITUDE, hass.config.latitude) + self._longitude = config_entry.data.get(CONF_LONGITUDE, hass.config.longitude) super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=WEATHER_UPDATE_INTERVAL + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=WEATHER_UPDATE_INTERVAL, ) async def _async_update_data(self): diff --git a/homeassistant/components/openweathermap/repairs.py b/homeassistant/components/openweathermap/repairs.py index c54484e1e1e..2bde5750ca4 100644 --- a/homeassistant/components/openweathermap/repairs.py +++ b/homeassistant/components/openweathermap/repairs.py @@ -1,14 +1,18 @@ """Issues for OpenWeatherMap.""" -from typing import cast +from __future__ import annotations + +from typing import TYPE_CHECKING, cast from homeassistant import data_entry_flow from homeassistant.components.repairs import RepairsFlow -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_MODE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import issue_registry as ir +if TYPE_CHECKING: + from . import OpenweathermapConfigEntry + from .const import DOMAIN, OWM_MODE_V30 from .utils import validate_api_key @@ -16,7 +20,7 @@ from .utils import validate_api_key class DeprecatedV25RepairFlow(RepairsFlow): """Handler for an issue fixing flow.""" - def __init__(self, entry: ConfigEntry) -> None: + def __init__(self, entry: OpenweathermapConfigEntry) -> None: """Create flow.""" super().__init__() self.entry = entry diff --git a/homeassistant/components/openweathermap/sensor.py b/homeassistant/components/openweathermap/sensor.py index 46789f4b3d2..0afab69b638 100644 --- a/homeassistant/components/openweathermap/sensor.py +++ b/homeassistant/components/openweathermap/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -156,7 +156,7 @@ WEATHER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: OpenweathermapConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OpenWeatherMap sensor entities based on a config entry.""" domain_data = config_entry.runtime_data diff --git a/homeassistant/components/openweathermap/weather.py b/homeassistant/components/openweathermap/weather.py index 3a134a0ee26..43e9c0a868a 100644 --- a/homeassistant/components/openweathermap/weather.py +++ b/homeassistant/components/openweathermap/weather.py @@ -16,7 +16,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OpenweathermapConfigEntry from .const import ( @@ -48,7 +48,7 @@ from .coordinator import WeatherUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: OpenweathermapConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OpenWeatherMap weather entity based on a config entry.""" domain_data = config_entry.runtime_data diff --git a/homeassistant/components/opower/__init__.py b/homeassistant/components/opower/__init__.py index b8e4f4381d0..23c8e7a8136 100644 --- a/homeassistant/components/opower/__init__.py +++ b/homeassistant/components/opower/__init__.py @@ -13,7 +13,7 @@ PLATFORMS: list[Platform] = [Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: OpowerConfigEntry) -> bool: """Set up Opower from a config entry.""" - coordinator = OpowerCoordinator(hass, entry.data) + coordinator = OpowerCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/opower/coordinator.py b/homeassistant/components/opower/coordinator.py index 8d7ef1ace94..aed89ccf46e 100644 --- a/homeassistant/components/opower/coordinator.py +++ b/homeassistant/components/opower/coordinator.py @@ -2,8 +2,7 @@ from datetime import datetime, timedelta import logging -from types import MappingProxyType -from typing import Any, cast +from typing import cast from opower import ( Account, @@ -46,12 +45,13 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): def __init__( self, hass: HomeAssistant, - entry_data: MappingProxyType[str, Any], + config_entry: OpowerConfigEntry, ) -> None: """Initialize the data handler.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Opower", # Data is updated daily on Opower. # Refresh every 12h to be at most 12h behind. @@ -59,12 +59,11 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): ) self.api = Opower( aiohttp_client.async_get_clientsession(hass), - entry_data[CONF_UTILITY], - entry_data[CONF_USERNAME], - entry_data[CONF_PASSWORD], - entry_data.get(CONF_TOTP_SECRET), + config_entry.data[CONF_UTILITY], + config_entry.data[CONF_USERNAME], + config_entry.data[CONF_PASSWORD], + config_entry.data.get(CONF_TOTP_SECRET), ) - self._statistic_ids: set[str] = set() @callback def _dummy_listener() -> None: @@ -76,12 +75,6 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): # _async_update_data not periodically getting called which is needed for _insert_statistics. self.async_add_listener(_dummy_listener) - self.config_entry.async_on_unload(self._clear_statistics) - - def _clear_statistics(self) -> None: - """Clear statistics.""" - get_instance(self.hass).async_clear_statistics(list(self._statistic_ids)) - async def _async_update_data( self, ) -> dict[str, Forecast]: @@ -127,8 +120,6 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): ) cost_statistic_id = f"{DOMAIN}:{id_prefix}_energy_cost" consumption_statistic_id = f"{DOMAIN}:{id_prefix}_energy_consumption" - self._statistic_ids.add(cost_statistic_id) - self._statistic_ids.add(consumption_statistic_id) _LOGGER.debug( "Updating Statistics for %s and %s", cost_statistic_id, diff --git a/homeassistant/components/opower/sensor.py b/homeassistant/components/opower/sensor.py index 1b3aa0fd710..61b0e0567b3 100644 --- a/homeassistant/components/opower/sensor.py +++ b/homeassistant/components/opower/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import EntityCategory, UnitOfEnergy, UnitOfVolume from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -184,7 +184,7 @@ GAS_SENSORS: tuple[OpowerEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: OpowerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Opower sensor.""" diff --git a/homeassistant/components/oralb/sensor.py b/homeassistant/components/oralb/sensor.py index 9994bfc6443..3b345f4b36a 100644 --- a/homeassistant/components/oralb/sensor.py +++ b/homeassistant/components/oralb/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import OralBConfigEntry @@ -108,7 +108,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: OralBConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OralB BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/osoenergy/binary_sensor.py b/homeassistant/components/osoenergy/binary_sensor.py index 0cf0ac74d36..a2ba61ccbe4 100644 --- a/homeassistant/components/osoenergy/binary_sensor.py +++ b/homeassistant/components/osoenergy/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import OSOEnergyEntity @@ -45,7 +45,9 @@ SENSOR_TYPES: dict[str, OSOEnergyBinarySensorEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OSO Energy binary sensor.""" osoenergy: OSOEnergy = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/osoenergy/sensor.py b/homeassistant/components/osoenergy/sensor.py index 40ec33e3e02..18859627952 100644 --- a/homeassistant/components/osoenergy/sensor.py +++ b/homeassistant/components/osoenergy/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -138,7 +138,9 @@ SENSOR_TYPES: dict[str, OSOEnergySensorEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OSO Energy sensor.""" osoenergy = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/osoenergy/strings.json b/homeassistant/components/osoenergy/strings.json index ca23265048f..7e10168d941 100644 --- a/homeassistant/components/osoenergy/strings.json +++ b/homeassistant/components/osoenergy/strings.json @@ -215,7 +215,7 @@ "fields": { "until_temp_limit": { "name": "Until temperature limit", - "description": "Choose if heating should be off until min temperature (True) is reached or for one hour (False)" + "description": "Whether heating should be off until the minimum temperature is reached instead of for one hour." } } }, @@ -225,7 +225,7 @@ "fields": { "until_temp_limit": { "name": "Until temperature limit", - "description": "Choose if heating should be on until max temperature (True) is reached or for one hour (False)" + "description": "Whether heating should be on until the maximum temperature is reached instead of for one hour." } } } diff --git a/homeassistant/components/osoenergy/water_heater.py b/homeassistant/components/osoenergy/water_heater.py index b3281193da3..07820ee97d5 100644 --- a/homeassistant/components/osoenergy/water_heater.py +++ b/homeassistant/components/osoenergy/water_heater.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from homeassistant.util.json import JsonValueType @@ -49,7 +49,9 @@ SERVICE_TURN_ON = "turn_on" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OSO Energy heater based on a config entry.""" osoenergy = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/otp/sensor.py b/homeassistant/components/otp/sensor.py index 255bc0ded34..af508d2e915 100644 --- a/homeassistant/components/otp/sensor.py +++ b/homeassistant/components/otp/sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_TOKEN from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -20,7 +20,9 @@ TIME_STEP = 30 # Default time step assumed by Google Authenticator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OTP sensor.""" diff --git a/homeassistant/components/ourgroceries/__init__.py b/homeassistant/components/ourgroceries/__init__.py index 5086a5cfc9b..a83430b3531 100644 --- a/homeassistant/components/ourgroceries/__init__.py +++ b/homeassistant/components/ourgroceries/__init__.py @@ -30,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except InvalidLoginException: return False - coordinator = OurGroceriesDataUpdateCoordinator(hass, og) + coordinator = OurGroceriesDataUpdateCoordinator(hass, entry, og) await coordinator.async_config_entry_first_refresh() hass.data[DOMAIN][entry.entry_id] = coordinator diff --git a/homeassistant/components/ourgroceries/coordinator.py b/homeassistant/components/ourgroceries/coordinator.py index bc645b2bdb3..a822931e88c 100644 --- a/homeassistant/components/ourgroceries/coordinator.py +++ b/homeassistant/components/ourgroceries/coordinator.py @@ -8,6 +8,7 @@ import logging from ourgroceries import OurGroceries +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -21,7 +22,11 @@ _LOGGER = logging.getLogger(__name__) class OurGroceriesDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict]]): """Class to manage fetching OurGroceries data.""" - def __init__(self, hass: HomeAssistant, og: OurGroceries) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, og: OurGroceries + ) -> None: """Initialize global OurGroceries data updater.""" self.og = og self.lists: list[dict] = [] @@ -30,6 +35,7 @@ class OurGroceriesDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=interval, ) diff --git a/homeassistant/components/ourgroceries/todo.py b/homeassistant/components/ourgroceries/todo.py index 5b8d19e5aa1..f257ef481c7 100644 --- a/homeassistant/components/ourgroceries/todo.py +++ b/homeassistant/components/ourgroceries/todo.py @@ -11,7 +11,7 @@ from homeassistant.components.todo import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -19,7 +19,9 @@ from .coordinator import OurGroceriesDataUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the OurGroceries todo platform config entry.""" coordinator: OurGroceriesDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/overkiz/__init__.py b/homeassistant/components/overkiz/__init__.py index 51efb52e55d..8aa1ed0e4fe 100644 --- a/homeassistant/components/overkiz/__init__.py +++ b/homeassistant/components/overkiz/__init__.py @@ -39,7 +39,6 @@ from .const import ( LOGGER, OVERKIZ_DEVICE_TO_PLATFORM, PLATFORMS, - UPDATE_INTERVAL, UPDATE_INTERVAL_ALL_ASSUMED_STATE, UPDATE_INTERVAL_LOCAL, ) @@ -104,13 +103,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: OverkizDataConfigEntry) coordinator = OverkizDataUpdateCoordinator( hass, + entry, LOGGER, - name="device events", client=client, devices=setup.devices, places=setup.root_place, - update_interval=UPDATE_INTERVAL, - config_entry_id=entry.entry_id, ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/overkiz/alarm_control_panel.py b/homeassistant/components/overkiz/alarm_control_panel.py index 90c135291c3..1a5490dd329 100644 --- a/homeassistant/components/overkiz/alarm_control_panel.py +++ b/homeassistant/components/overkiz/alarm_control_panel.py @@ -19,7 +19,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .coordinator import OverkizDataUpdateCoordinator @@ -209,7 +209,7 @@ SUPPORTED_DEVICES = {description.key: description for description in ALARM_DESCR async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz alarm control panel from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/binary_sensor.py b/homeassistant/components/overkiz/binary_sensor.py index 3a75cd77c2f..09319d59932 100644 --- a/homeassistant/components/overkiz/binary_sensor.py +++ b/homeassistant/components/overkiz/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .const import IGNORED_OVERKIZ_DEVICES @@ -143,7 +143,7 @@ SUPPORTED_STATES = { async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz binary sensors from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/button.py b/homeassistant/components/overkiz/button.py index 92711ac8ca8..f4e051ef9ca 100644 --- a/homeassistant/components/overkiz/button.py +++ b/homeassistant/components/overkiz/button.py @@ -14,7 +14,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .const import IGNORED_OVERKIZ_DEVICES @@ -100,7 +100,7 @@ SUPPORTED_COMMANDS = { async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz button from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/climate/__init__.py b/homeassistant/components/overkiz/climate/__init__.py index 3276a1979cc..058c3aefdb7 100644 --- a/homeassistant/components/overkiz/climate/__init__.py +++ b/homeassistant/components/overkiz/climate/__init__.py @@ -10,7 +10,7 @@ from pyoverkiz.enums.ui import UIWidget from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .. import OverkizDataConfigEntry from .atlantic_electrical_heater import AtlanticElectricalHeater @@ -82,7 +82,7 @@ WIDGET_AND_PROTOCOL_TO_CLIMATE_ENTITY = { async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz climate from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/coordinator.py b/homeassistant/components/overkiz/coordinator.py index 484ef138cf7..4b79cfc9c06 100644 --- a/homeassistant/components/overkiz/coordinator.py +++ b/homeassistant/components/overkiz/coordinator.py @@ -5,7 +5,7 @@ from __future__ import annotations from collections.abc import Callable, Coroutine from datetime import timedelta import logging -from typing import Any +from typing import TYPE_CHECKING, Any from aiohttp import ClientConnectorError, ServerDisconnectedError from pyoverkiz.client import OverkizClient @@ -26,7 +26,10 @@ from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util.decorator import Registry -from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES, LOGGER +if TYPE_CHECKING: + from . import OverkizDataConfigEntry + +from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES, LOGGER, UPDATE_INTERVAL EVENT_HANDLERS: Registry[ str, Callable[[OverkizDataUpdateCoordinator, Event], Coroutine[Any, Any, None]] @@ -36,26 +39,26 @@ EVENT_HANDLERS: Registry[ class OverkizDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Device]]): """Class to manage fetching data from Overkiz platform.""" + config_entry: OverkizDataConfigEntry _default_update_interval: timedelta def __init__( self, hass: HomeAssistant, + config_entry: OverkizDataConfigEntry, logger: logging.Logger, *, - name: str, client: OverkizClient, devices: list[Device], places: Place | None, - update_interval: timedelta, - config_entry_id: str, ) -> None: """Initialize global data updater.""" super().__init__( hass, logger, - name=name, - update_interval=update_interval, + config_entry=config_entry, + name="device events", + update_interval=UPDATE_INTERVAL, ) self.data = {} @@ -63,8 +66,7 @@ class OverkizDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Device]]): self.devices: dict[str, Device] = {d.device_url: d for d in devices} self.executions: dict[str, dict[str, str]] = {} self.areas = self._places_to_area(places) if places else None - self.config_entry_id = config_entry_id - self._default_update_interval = update_interval + self._default_update_interval = UPDATE_INTERVAL self.is_stateless = all( device.protocol in (Protocol.RTS, Protocol.INTERNAL) @@ -164,7 +166,7 @@ async def on_device_created_updated( ) -> None: """Handle device unavailable / disabled event.""" coordinator.hass.async_create_task( - coordinator.hass.config_entries.async_reload(coordinator.config_entry_id) + coordinator.hass.config_entries.async_reload(coordinator.config_entry.entry_id) ) diff --git a/homeassistant/components/overkiz/cover/__init__.py b/homeassistant/components/overkiz/cover/__init__.py index 38c02eba1bb..dd3216f9c10 100644 --- a/homeassistant/components/overkiz/cover/__init__.py +++ b/homeassistant/components/overkiz/cover/__init__.py @@ -4,7 +4,7 @@ from pyoverkiz.enums import OverkizCommand, UIClass from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .. import OverkizDataConfigEntry from .awning import Awning @@ -15,7 +15,7 @@ from .vertical_cover import LowSpeedCover, VerticalCover async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz covers from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/light.py b/homeassistant/components/overkiz/light.py index 933d4cf695b..acd63140196 100644 --- a/homeassistant/components/overkiz/light.py +++ b/homeassistant/components/overkiz/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .coordinator import OverkizDataUpdateCoordinator @@ -24,7 +24,7 @@ from .entity import OverkizEntity async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz lights from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/lock.py b/homeassistant/components/overkiz/lock.py index 1c073d2f9aa..16ec32b0667 100644 --- a/homeassistant/components/overkiz/lock.py +++ b/homeassistant/components/overkiz/lock.py @@ -9,7 +9,7 @@ from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState from homeassistant.components.lock import LockEntity from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .entity import OverkizEntity @@ -18,7 +18,7 @@ from .entity import OverkizEntity async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz locks from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/number.py b/homeassistant/components/overkiz/number.py index 0e03e822424..83c0e7cf7a8 100644 --- a/homeassistant/components/overkiz/number.py +++ b/homeassistant/components/overkiz/number.py @@ -16,7 +16,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .const import IGNORED_OVERKIZ_DEVICES @@ -191,7 +191,7 @@ SUPPORTED_STATES = {description.key: description for description in NUMBER_DESCR async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz number from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/scene.py b/homeassistant/components/overkiz/scene.py index 4533ed3245c..bd362b4b372 100644 --- a/homeassistant/components/overkiz/scene.py +++ b/homeassistant/components/overkiz/scene.py @@ -9,7 +9,7 @@ from pyoverkiz.models import Scenario from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry @@ -17,7 +17,7 @@ from . import OverkizDataConfigEntry async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz scenes from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/select.py b/homeassistant/components/overkiz/select.py index ac467eaaa7a..e23dafdaab8 100644 --- a/homeassistant/components/overkiz/select.py +++ b/homeassistant/components/overkiz/select.py @@ -10,7 +10,7 @@ from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .const import IGNORED_OVERKIZ_DEVICES @@ -129,7 +129,7 @@ SUPPORTED_STATES = {description.key: description for description in SELECT_DESCR async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz select from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/sensor.py b/homeassistant/components/overkiz/sensor.py index 81a9ab41d2d..9214398a37b 100644 --- a/homeassistant/components/overkiz/sensor.py +++ b/homeassistant/components/overkiz/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import OverkizDataConfigEntry @@ -483,7 +483,7 @@ SUPPORTED_STATES = {description.key: description for description in SENSOR_DESCR async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz sensors from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/siren.py b/homeassistant/components/overkiz/siren.py index f7246e50ec0..af761611444 100644 --- a/homeassistant/components/overkiz/siren.py +++ b/homeassistant/components/overkiz/siren.py @@ -12,7 +12,7 @@ from homeassistant.components.siren import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .entity import OverkizEntity @@ -21,7 +21,7 @@ from .entity import OverkizEntity async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz sirens from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/switch.py b/homeassistant/components/overkiz/switch.py index c921dbab776..d14b2792947 100644 --- a/homeassistant/components/overkiz/switch.py +++ b/homeassistant/components/overkiz/switch.py @@ -17,7 +17,7 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OverkizDataConfigEntry from .entity import OverkizDescriptiveEntity @@ -110,7 +110,7 @@ SUPPORTED_DEVICES = { async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz switch from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overkiz/water_heater/__init__.py b/homeassistant/components/overkiz/water_heater/__init__.py index 1dd1d596a33..9895ea84c2c 100644 --- a/homeassistant/components/overkiz/water_heater/__init__.py +++ b/homeassistant/components/overkiz/water_heater/__init__.py @@ -6,7 +6,7 @@ from pyoverkiz.enums.ui import UIWidget from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .. import OverkizDataConfigEntry from ..entity import OverkizEntity @@ -21,7 +21,7 @@ from .hitachi_dhw import HitachiDHW async def async_setup_entry( hass: HomeAssistant, entry: OverkizDataConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Overkiz DHW from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/overseerr/event.py b/homeassistant/components/overseerr/event.py index 589a80c5404..1ffb1e71771 100644 --- a/homeassistant/components/overseerr/event.py +++ b/homeassistant/components/overseerr/event.py @@ -8,7 +8,7 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, EVENT_KEY from .coordinator import OverseerrConfigEntry, OverseerrCoordinator @@ -44,7 +44,7 @@ EVENTS: tuple[OverseerrEventEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: OverseerrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Overseerr sensor entities based on a config entry.""" diff --git a/homeassistant/components/overseerr/sensor.py b/homeassistant/components/overseerr/sensor.py index 2daaa3de0cb..510e6f52c59 100644 --- a/homeassistant/components/overseerr/sensor.py +++ b/homeassistant/components/overseerr/sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import REQUESTS from .coordinator import OverseerrConfigEntry, OverseerrCoordinator @@ -76,7 +76,7 @@ SENSORS: tuple[OverseerrSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: OverseerrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Overseerr sensor entities based on a config entry.""" diff --git a/homeassistant/components/ovo_energy/sensor.py b/homeassistant/components/ovo_energy/sensor.py index 8cada86da34..1dc12c7f008 100644 --- a/homeassistant/components/ovo_energy/sensor.py +++ b/homeassistant/components/ovo_energy/sensor.py @@ -19,7 +19,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util @@ -111,7 +111,9 @@ SENSOR_TYPES_GAS: tuple[OVOEnergySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OVO Energy sensor based on a config entry.""" coordinator: DataUpdateCoordinator[OVODailyUsage] = hass.data[DOMAIN][ diff --git a/homeassistant/components/owntracks/device_tracker.py b/homeassistant/components/owntracks/device_tracker.py index 6a6f0f078b1..7ccbbb69aa1 100644 --- a/homeassistant/components/owntracks/device_tracker.py +++ b/homeassistant/components/owntracks/device_tracker.py @@ -16,14 +16,16 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import DOMAIN as OT_DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up OwnTracks based off an entry.""" # Restore previously loaded devices diff --git a/homeassistant/components/p1_monitor/__init__.py b/homeassistant/components/p1_monitor/__init__.py index d2ccc83972a..e12c092453c 100644 --- a/homeassistant/components/p1_monitor/__init__.py +++ b/homeassistant/components/p1_monitor/__init__.py @@ -2,23 +2,20 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from .const import LOGGER -from .coordinator import P1MonitorDataUpdateCoordinator +from .coordinator import P1MonitorConfigEntry, P1MonitorDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -type P1MonitorConfigEntry = ConfigEntry[P1MonitorDataUpdateCoordinator] - -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: P1MonitorConfigEntry) -> bool: """Set up P1 Monitor from a config entry.""" - coordinator = P1MonitorDataUpdateCoordinator(hass) + coordinator = P1MonitorDataUpdateCoordinator(hass, entry) try: await coordinator.async_config_entry_first_refresh() except ConfigEntryNotReady: @@ -31,7 +28,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return True -async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_migrate_entry( + hass: HomeAssistant, config_entry: P1MonitorConfigEntry +) -> bool: """Migrate old entry.""" LOGGER.debug("Migrating from version %s", config_entry.version) @@ -54,6 +53,6 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: P1MonitorConfigEntry) -> bool: """Unload P1 Monitor config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/p1_monitor/coordinator.py b/homeassistant/components/p1_monitor/coordinator.py index 5459f88c388..3be78f8efd5 100644 --- a/homeassistant/components/p1_monitor/coordinator.py +++ b/homeassistant/components/p1_monitor/coordinator.py @@ -30,6 +30,8 @@ from .const import ( SERVICE_WATERMETER, ) +type P1MonitorConfigEntry = ConfigEntry[P1MonitorDataUpdateCoordinator] + class P1MonitorData(TypedDict): """Class for defining data in dict.""" @@ -43,17 +45,19 @@ class P1MonitorData(TypedDict): class P1MonitorDataUpdateCoordinator(DataUpdateCoordinator[P1MonitorData]): """Class to manage fetching P1 Monitor data from single endpoint.""" - config_entry: ConfigEntry + config_entry: P1MonitorConfigEntry has_water_meter: bool | None = None def __init__( self, hass: HomeAssistant, + config_entry: P1MonitorConfigEntry, ) -> None: """Initialize global P1 Monitor data updater.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/p1_monitor/diagnostics.py b/homeassistant/components/p1_monitor/diagnostics.py index d2e2ec5c24e..ac670486e79 100644 --- a/homeassistant/components/p1_monitor/diagnostics.py +++ b/homeassistant/components/p1_monitor/diagnostics.py @@ -6,7 +6,6 @@ from dataclasses import asdict from typing import TYPE_CHECKING, Any, cast from homeassistant.components.diagnostics import async_redact_data -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.core import HomeAssistant @@ -16,6 +15,7 @@ from .const import ( SERVICE_SMARTMETER, SERVICE_WATERMETER, ) +from .coordinator import P1MonitorConfigEntry if TYPE_CHECKING: from _typeshed import DataclassInstance @@ -24,7 +24,7 @@ TO_REDACT = {CONF_HOST, CONF_PORT} async def async_get_config_entry_diagnostics( - hass: HomeAssistant, entry: ConfigEntry + hass: HomeAssistant, entry: P1MonitorConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" data = { diff --git a/homeassistant/components/p1_monitor/sensor.py b/homeassistant/components/p1_monitor/sensor.py index 771ef0e19af..15a8f510fd7 100644 --- a/homeassistant/components/p1_monitor/sensor.py +++ b/homeassistant/components/p1_monitor/sensor.py @@ -10,7 +10,6 @@ from homeassistant.components.sensor import ( SensorEntityDescription, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CURRENCY_EURO, @@ -22,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -33,7 +32,7 @@ from .const import ( SERVICE_SMARTMETER, SERVICE_WATERMETER, ) -from .coordinator import P1MonitorDataUpdateCoordinator +from .coordinator import P1MonitorConfigEntry, P1MonitorDataUpdateCoordinator SENSORS_SMARTMETER: tuple[SensorEntityDescription, ...] = ( SensorEntityDescription( @@ -236,7 +235,9 @@ SENSORS_WATERMETER: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: P1MonitorConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up P1 Monitor Sensors based on a config entry.""" entities: list[P1MonitorSensorEntity] = [] @@ -290,7 +291,7 @@ class P1MonitorSensorEntity( def __init__( self, *, - entry: ConfigEntry, + entry: P1MonitorConfigEntry, description: SensorEntityDescription, name: str, service: Literal["smartmeter", "watermeter", "phases", "settings"], diff --git a/homeassistant/components/palazzetti/__init__.py b/homeassistant/components/palazzetti/__init__.py index dbf1baa0c28..a698cdcd8b7 100644 --- a/homeassistant/components/palazzetti/__init__.py +++ b/homeassistant/components/palazzetti/__init__.py @@ -18,7 +18,7 @@ PLATFORMS: list[Platform] = [ async def async_setup_entry(hass: HomeAssistant, entry: PalazzettiConfigEntry) -> bool: """Set up Palazzetti from a config entry.""" - coordinator = PalazzettiDataUpdateCoordinator(hass) + coordinator = PalazzettiDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/palazzetti/button.py b/homeassistant/components/palazzetti/button.py index cd4765576ed..319a1174542 100644 --- a/homeassistant/components/palazzetti/button.py +++ b/homeassistant/components/palazzetti/button.py @@ -7,18 +7,17 @@ from pypalazzetti.exceptions import CommunicationError from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PalazzettiConfigEntry from .const import DOMAIN -from .coordinator import PalazzettiDataUpdateCoordinator +from .coordinator import PalazzettiConfigEntry, PalazzettiDataUpdateCoordinator from .entity import PalazzettiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: PalazzettiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Palazzetti button platform.""" diff --git a/homeassistant/components/palazzetti/climate.py b/homeassistant/components/palazzetti/climate.py index 0722b97e4b7..5a4097e083a 100644 --- a/homeassistant/components/palazzetti/climate.py +++ b/homeassistant/components/palazzetti/climate.py @@ -13,18 +13,17 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PalazzettiConfigEntry from .const import DOMAIN, FAN_AUTO, FAN_HIGH, FAN_MODES -from .coordinator import PalazzettiDataUpdateCoordinator +from .coordinator import PalazzettiConfigEntry, PalazzettiDataUpdateCoordinator from .entity import PalazzettiEntity async def async_setup_entry( hass: HomeAssistant, entry: PalazzettiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Palazzetti climates based on a config entry.""" async_add_entities([PalazzettiClimateEntity(entry.runtime_data)]) diff --git a/homeassistant/components/palazzetti/coordinator.py b/homeassistant/components/palazzetti/coordinator.py index d992bd3fb62..1e4069e58ea 100644 --- a/homeassistant/components/palazzetti/coordinator.py +++ b/homeassistant/components/palazzetti/coordinator.py @@ -22,11 +22,13 @@ class PalazzettiDataUpdateCoordinator(DataUpdateCoordinator[None]): def __init__( self, hass: HomeAssistant, + config_entry: PalazzettiConfigEntry, ) -> None: """Initialize global Palazzetti data updater.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/palazzetti/diagnostics.py b/homeassistant/components/palazzetti/diagnostics.py index 3843f0ec111..e386ffc7833 100644 --- a/homeassistant/components/palazzetti/diagnostics.py +++ b/homeassistant/components/palazzetti/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import PalazzettiConfigEntry +from .coordinator import PalazzettiConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/palazzetti/number.py b/homeassistant/components/palazzetti/number.py index 2b303f71fd6..63c1ed16f0c 100644 --- a/homeassistant/components/palazzetti/number.py +++ b/homeassistant/components/palazzetti/number.py @@ -8,18 +8,17 @@ from pypalazzetti.fan import FanType from homeassistant.components.number import NumberDeviceClass, NumberEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PalazzettiConfigEntry from .const import DOMAIN -from .coordinator import PalazzettiDataUpdateCoordinator +from .coordinator import PalazzettiConfigEntry, PalazzettiDataUpdateCoordinator from .entity import PalazzettiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: PalazzettiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Palazzetti number platform.""" diff --git a/homeassistant/components/palazzetti/sensor.py b/homeassistant/components/palazzetti/sensor.py index 11462201f4e..57d5ca861a2 100644 --- a/homeassistant/components/palazzetti/sensor.py +++ b/homeassistant/components/palazzetti/sensor.py @@ -10,12 +10,11 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfLength, UnitOfMass, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import PalazzettiConfigEntry from .const import STATUS_TO_HA -from .coordinator import PalazzettiDataUpdateCoordinator +from .coordinator import PalazzettiConfigEntry, PalazzettiDataUpdateCoordinator from .entity import PalazzettiEntity @@ -60,7 +59,7 @@ PROPERTY_SENSOR_DESCRIPTIONS: list[PropertySensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: PalazzettiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Palazzetti sensor entities based on a config entry.""" diff --git a/homeassistant/components/panasonic_viera/media_player.py b/homeassistant/components/panasonic_viera/media_player.py index 8738b897d29..a78920f33a5 100644 --- a/homeassistant/components/panasonic_viera/media_player.py +++ b/homeassistant/components/panasonic_viera/media_player.py @@ -21,7 +21,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_DEVICE_INFO, @@ -40,7 +40,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Panasonic Viera TV from a config entry.""" diff --git a/homeassistant/components/panasonic_viera/remote.py b/homeassistant/components/panasonic_viera/remote.py index ad40a97f700..5fa4be9ca2b 100644 --- a/homeassistant/components/panasonic_viera/remote.py +++ b/homeassistant/components/panasonic_viera/remote.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, STATE_ON from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Remote from .const import ( @@ -28,7 +28,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Panasonic Viera TV Remote from a config entry.""" diff --git a/homeassistant/components/peblar/binary_sensor.py b/homeassistant/components/peblar/binary_sensor.py index e8e5095f050..8834a2ba2a0 100644 --- a/homeassistant/components/peblar/binary_sensor.py +++ b/homeassistant/components/peblar/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PeblarConfigEntry, PeblarData, PeblarDataUpdateCoordinator from .entity import PeblarEntity @@ -50,7 +50,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar binary sensor based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/button.py b/homeassistant/components/peblar/button.py index 22150c82649..8c60c8d84d3 100644 --- a/homeassistant/components/peblar/button.py +++ b/homeassistant/components/peblar/button.py @@ -15,7 +15,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PeblarConfigEntry, PeblarUserConfigurationDataUpdateCoordinator from .entity import PeblarEntity @@ -52,7 +52,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar buttons based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/number.py b/homeassistant/components/peblar/number.py index 0e929a63523..bff1bb26db4 100644 --- a/homeassistant/components/peblar/number.py +++ b/homeassistant/components/peblar/number.py @@ -14,7 +14,7 @@ from homeassistant.const import ( UnitOfElectricCurrent, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PeblarConfigEntry, PeblarDataUpdateCoordinator from .entity import PeblarEntity @@ -26,7 +26,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar number based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/select.py b/homeassistant/components/peblar/select.py index a2a0997a797..17503951ccd 100644 --- a/homeassistant/components/peblar/select.py +++ b/homeassistant/components/peblar/select.py @@ -11,7 +11,7 @@ from peblar import Peblar, PeblarUserConfiguration, SmartChargingMode from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PeblarConfigEntry, PeblarUserConfigurationDataUpdateCoordinator from .entity import PeblarEntity @@ -49,7 +49,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar select based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/sensor.py b/homeassistant/components/peblar/sensor.py index e655253d75c..81476eef9aa 100644 --- a/homeassistant/components/peblar/sensor.py +++ b/homeassistant/components/peblar/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .const import ( @@ -231,7 +231,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar sensors based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/switch.py b/homeassistant/components/peblar/switch.py index 74a42ddc47d..f2e1ae13ae2 100644 --- a/homeassistant/components/peblar/switch.py +++ b/homeassistant/components/peblar/switch.py @@ -11,7 +11,7 @@ from peblar import PeblarEVInterface from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ( PeblarConfigEntry, @@ -71,7 +71,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar switch based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peblar/update.py b/homeassistant/components/peblar/update.py index 58c2fbdc899..88966916069 100644 --- a/homeassistant/components/peblar/update.py +++ b/homeassistant/components/peblar/update.py @@ -11,7 +11,7 @@ from homeassistant.components.update import ( UpdateEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ( PeblarConfigEntry, @@ -53,7 +53,7 @@ DESCRIPTIONS: tuple[PeblarUpdateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PeblarConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Peblar update based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/peco/binary_sensor.py b/homeassistant/components/peco/binary_sensor.py index a55f0fcc731..a4d59a8c9a2 100644 --- a/homeassistant/components/peco/binary_sensor.py +++ b/homeassistant/components/peco/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -24,7 +24,7 @@ PARALLEL_UPDATES: Final = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor for PECO.""" if "smart_meter" not in hass.data[DOMAIN][config_entry.entry_id]: diff --git a/homeassistant/components/peco/sensor.py b/homeassistant/components/peco/sensor.py index d08947eb0ec..eafa36c98e9 100644 --- a/homeassistant/components/peco/sensor.py +++ b/homeassistant/components/peco/sensor.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -76,7 +76,7 @@ SENSOR_LIST: tuple[PECOSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" county: str = config_entry.data[CONF_COUNTY] diff --git a/homeassistant/components/pegel_online/sensor.py b/homeassistant/components/pegel_online/sensor.py index 181c0f5dc6d..fd90683a9b2 100644 --- a/homeassistant/components/pegel_online/sensor.py +++ b/homeassistant/components/pegel_online/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import PegelOnlineConfigEntry, PegelOnlineDataUpdateCoordinator from .entity import PegelOnlineEntity @@ -92,7 +92,7 @@ SENSORS: tuple[PegelOnlineSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PegelOnlineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the PEGELONLINE sensor.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/permobil/__init__.py b/homeassistant/components/permobil/__init__.py index 675a803ce91..441c6a2646e 100644 --- a/homeassistant/components/permobil/__init__.py +++ b/homeassistant/components/permobil/__init__.py @@ -48,7 +48,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: raise ConfigEntryAuthFailed(f"Config error for {p_api.email}") from err # create the coordinator with the API object - coordinator = MyPermobilCoordinator(hass, p_api) + coordinator = MyPermobilCoordinator(hass, entry, p_api) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/permobil/binary_sensor.py b/homeassistant/components/permobil/binary_sensor.py index 4b768cf5af5..c2d51067e19 100644 --- a/homeassistant/components/permobil/binary_sensor.py +++ b/homeassistant/components/permobil/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MyPermobilCoordinator @@ -42,7 +42,7 @@ BINARY_SENSOR_DESCRIPTIONS: tuple[PermobilBinarySensorEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create and setup the binary sensor.""" diff --git a/homeassistant/components/permobil/coordinator.py b/homeassistant/components/permobil/coordinator.py index 6efde26d341..ea7ddadff9f 100644 --- a/homeassistant/components/permobil/coordinator.py +++ b/homeassistant/components/permobil/coordinator.py @@ -7,6 +7,7 @@ import logging from mypermobil import MyPermobil, MyPermobilAPIException +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -25,11 +26,16 @@ class MyPermobilData: class MyPermobilCoordinator(DataUpdateCoordinator[MyPermobilData]): """MyPermobil coordinator.""" - def __init__(self, hass: HomeAssistant, p_api: MyPermobil) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, p_api: MyPermobil + ) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="permobil", update_interval=timedelta(minutes=5), ) diff --git a/homeassistant/components/permobil/sensor.py b/homeassistant/components/permobil/sensor.py index 54d3a61c519..5f8cb88290a 100644 --- a/homeassistant/components/permobil/sensor.py +++ b/homeassistant/components/permobil/sensor.py @@ -32,7 +32,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfLength, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import BATTERY_ASSUMED_VOLTAGE, DOMAIN, KM, MILES from .coordinator import MyPermobilCoordinator @@ -175,7 +175,7 @@ DISTANCE_UNITS: dict[Any, UnitOfLength] = { async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create sensors from a config entry created in the integrations UI.""" diff --git a/homeassistant/components/pglab/__init__.py b/homeassistant/components/pglab/__init__.py new file mode 100644 index 00000000000..7307ac2f801 --- /dev/null +++ b/homeassistant/components/pglab/__init__.py @@ -0,0 +1,85 @@ +"""PG LAB Electronics integration.""" + +from __future__ import annotations + +from pypglab.mqtt import ( + Client as PyPGLabMqttClient, + Sub_State as PyPGLabSubState, + Subcribe_CallBack as PyPGLabSubscribeCallBack, +) + +from homeassistant.components import mqtt +from homeassistant.components.mqtt import ( + ReceiveMessage, + async_prepare_subscribe_topics, + async_subscribe_topics, + async_unsubscribe_topics, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.helpers import config_validation as cv + +from .const import DOMAIN, LOGGER +from .discovery import PGLabDiscovery + +type PGLABConfigEntry = ConfigEntry[PGLabDiscovery] + +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) + + +async def async_setup_entry(hass: HomeAssistant, entry: PGLABConfigEntry) -> bool: + """Set up PG LAB Electronics integration from a config entry.""" + + async def mqtt_publish(topic: str, payload: str, qos: int, retain: bool) -> None: + """Publish an MQTT message using the Home Assistant MQTT client.""" + await mqtt.async_publish(hass, topic, payload, qos, retain) + + async def mqtt_subscribe( + sub_state: PyPGLabSubState, topic: str, callback_func: PyPGLabSubscribeCallBack + ) -> PyPGLabSubState: + """Subscribe to MQTT topics using the Home Assistant MQTT client.""" + + @callback + def mqtt_message_received(msg: ReceiveMessage) -> None: + """Handle PGLab mqtt messages.""" + callback_func(msg.topic, msg.payload) + + topics = { + "pglab_subscribe_topic": { + "topic": topic, + "msg_callback": mqtt_message_received, + } + } + + sub_state = async_prepare_subscribe_topics(hass, sub_state, topics) + await async_subscribe_topics(hass, sub_state) + return sub_state + + async def mqtt_unsubscribe(sub_state: PyPGLabSubState) -> None: + async_unsubscribe_topics(hass, sub_state) + + if not await mqtt.async_wait_for_mqtt_client(hass): + LOGGER.error("MQTT integration not available") + raise ConfigEntryNotReady("MQTT integration not available") + + # Create an MQTT client for PGLab used for PGLab python module. + pglab_mqtt = PyPGLabMqttClient(mqtt_publish, mqtt_subscribe, mqtt_unsubscribe) + + # Setup PGLab device discovery. + entry.runtime_data = PGLabDiscovery() + + # Start to discovery PG Lab devices. + await entry.runtime_data.start(hass, pglab_mqtt, entry) + + return True + + +async def async_unload_entry(hass: HomeAssistant, entry: PGLABConfigEntry) -> bool: + """Unload a config entry.""" + + # Stop PGLab device discovery. + pglab_discovery = entry.runtime_data + await pglab_discovery.stop(hass, entry) + + return True diff --git a/homeassistant/components/pglab/config_flow.py b/homeassistant/components/pglab/config_flow.py new file mode 100644 index 00000000000..606de757622 --- /dev/null +++ b/homeassistant/components/pglab/config_flow.py @@ -0,0 +1,73 @@ +"""Config flow for PG LAB Electronics integration.""" + +from __future__ import annotations + +from typing import Any + +from homeassistant.components import mqtt +from homeassistant.config_entries import ConfigFlow, ConfigFlowResult +from homeassistant.helpers.service_info.mqtt import MqttServiceInfo + +from .const import DISCOVERY_TOPIC, DOMAIN + + +class PGLabFlowHandler(ConfigFlow, domain=DOMAIN): + """Handle a config flow.""" + + VERSION = 1 + + async def async_step_mqtt( + self, discovery_info: MqttServiceInfo + ) -> ConfigFlowResult: + """Handle a flow initialized by MQTT discovery.""" + + await self.async_set_unique_id(DOMAIN) + + # Validate the message, abort if it fails. + if not discovery_info.topic.endswith("/config"): + # Not a PGLab Electronics discovery message. + return self.async_abort(reason="invalid_discovery_info") + if not discovery_info.payload: + # Empty payload, unexpected payload. + return self.async_abort(reason="invalid_discovery_info") + + return await self.async_step_confirm_from_mqtt() + + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle a flow initialized by the user.""" + try: + if not mqtt.is_connected(self.hass): + return self.async_abort(reason="mqtt_not_connected") + except KeyError: + return self.async_abort(reason="mqtt_not_configured") + + return await self.async_step_confirm_from_user() + + def step_confirm( + self, step_id: str, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Confirm the setup.""" + + if user_input is not None: + return self.async_create_entry( + title="PG LAB Electronics", + data={ + "discovery_prefix": DISCOVERY_TOPIC, + }, + ) + + return self.async_show_form(step_id=step_id) + + async def async_step_confirm_from_mqtt( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Confirm the setup from MQTT discovered.""" + return self.step_confirm(step_id="confirm_from_mqtt", user_input=user_input) + + async def async_step_confirm_from_user( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Confirm the setup from user add integration.""" + return self.step_confirm(step_id="confirm_from_user", user_input=user_input) diff --git a/homeassistant/components/pglab/const.py b/homeassistant/components/pglab/const.py new file mode 100644 index 00000000000..de076ac37f0 --- /dev/null +++ b/homeassistant/components/pglab/const.py @@ -0,0 +1,12 @@ +"""Constants used by PG LAB Electronics integration.""" + +import logging + +# The domain of the integration. +DOMAIN = "pglab" + +# The message logger. +LOGGER = logging.getLogger(__package__) + +# The MQTT message used to subscribe to get a new PG LAB device. +DISCOVERY_TOPIC = "pglab/discovery" diff --git a/homeassistant/components/pglab/discovery.py b/homeassistant/components/pglab/discovery.py new file mode 100644 index 00000000000..af6bedc9bf4 --- /dev/null +++ b/homeassistant/components/pglab/discovery.py @@ -0,0 +1,277 @@ +"""Discovery PG LAB Electronics devices.""" + +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass +import json +from typing import TYPE_CHECKING, Any + +from pypglab.device import Device as PyPGLabDevice +from pypglab.mqtt import Client as PyPGLabMqttClient + +from homeassistant.components.mqtt import ( + EntitySubscription, + ReceiveMessage, + async_prepare_subscribe_topics, + async_subscribe_topics, + async_unsubscribe_topics, +) +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC +from homeassistant.helpers.dispatcher import ( + async_dispatcher_connect, + async_dispatcher_send, +) +from homeassistant.helpers.entity import Entity + +from .const import DISCOVERY_TOPIC, DOMAIN, LOGGER + +if TYPE_CHECKING: + from . import PGLABConfigEntry + +# Supported platforms. +PLATFORMS = [ + Platform.SWITCH, +] + +# Used to create a new component entity. +CREATE_NEW_ENTITY = { + Platform.SWITCH: "pglab_create_new_entity_switch", +} + + +class PGLabDiscoveryError(Exception): + """Raised when a discovery has failed.""" + + +def get_device_id_from_discovery_topic(topic: str) -> str | None: + """From the discovery topic get the PG LAB Electronics device id.""" + + # The discovery topic has the following format "pglab/discovery/[Device ID]/config" + split_topic = topic.split("/", 5) + + # Do a sanity check on the string. + if len(split_topic) != 4: + return None + + if split_topic[3] != "config": + return None + + return split_topic[2] + + +class DiscoverDeviceInfo: + """Keeps information of the PGLab discovered device.""" + + def __init__(self, pglab_device: PyPGLabDevice) -> None: + """Initialize the device discovery info.""" + + # Hash string represents the devices actual configuration, + # it depends on the number of available relays and shutters. + # When the hash string changes the devices entities must be rebuilt. + self._hash = pglab_device.hash + self._entities: list[tuple[str, str]] = [] + + def add_entity(self, entity: Entity) -> None: + """Add an entity.""" + + # PGLabEntity always have unique IDs + if TYPE_CHECKING: + assert entity.unique_id is not None + self._entities.append((entity.platform.domain, entity.unique_id)) + + @property + def hash(self) -> int: + """Return the hash for this configuration.""" + return self._hash + + @property + def entities(self) -> list[tuple[str, str]]: + """Return array of entities available.""" + return self._entities + + +@dataclass +class PGLabDiscovery: + """Discovery a PGLab device with the following MQTT topic format pglab/discovery/[device]/config.""" + + def __init__(self) -> None: + """Initialize the discovery class.""" + self._substate: dict[str, EntitySubscription] = {} + self._discovery_topic = DISCOVERY_TOPIC + self._mqtt_client = None + self._discovered: dict[str, DiscoverDeviceInfo] = {} + self._disconnect_platform: list = [] + + async def __build_device( + self, mqtt: PyPGLabMqttClient, msg: ReceiveMessage + ) -> PyPGLabDevice: + """Build a PGLab device.""" + + # Check if the discovery message is in valid json format. + try: + payload = json.loads(msg.payload) + except ValueError as err: + raise PGLabDiscoveryError( + f"Can't decode discovery payload: {msg.payload!r}" + ) from err + + device_id = "id" + + # Check if the key id is present in the payload. It must always be present. + if device_id not in payload: + raise PGLabDiscoveryError( + "Unexpected discovery payload format, id key not present" + ) + + # Do a sanity check: the id must match the discovery topic /pglab/discovery/[id]/config + topic = msg.topic + if not topic.endswith(f"{payload[device_id]}/config"): + raise PGLabDiscoveryError("Unexpected discovery topic format") + + # Build and configure the PGLab device. + pglab_device = PyPGLabDevice() + if not await pglab_device.config(mqtt, payload): + raise PGLabDiscoveryError("Error during setup of a new discovered device") + + return pglab_device + + def __clean_discovered_device(self, hass: HomeAssistant, device_id: str) -> None: + """Destroy the device and any entities connected to the device.""" + + if device_id not in self._discovered: + return + + discovery_info = self._discovered[device_id] + + # Destroy all entities connected to the device. + entity_registry = er.async_get(hass) + for platform, unique_id in discovery_info.entities: + if entity_id := entity_registry.async_get_entity_id( + platform, DOMAIN, unique_id + ): + entity_registry.async_remove(entity_id) + + # Destroy the device. + device_registry = dr.async_get(hass) + if device_entry := device_registry.async_get_device( + identifiers={(DOMAIN, device_id)} + ): + device_registry.async_remove_device(device_entry.id) + + # Clean the discovery info. + del self._discovered[device_id] + + async def start( + self, hass: HomeAssistant, mqtt: PyPGLabMqttClient, entry: PGLABConfigEntry + ) -> None: + """Start discovering a PGLab devices.""" + + async def discovery_message_received(msg: ReceiveMessage) -> None: + """Received a new discovery message.""" + + # Create a PGLab device and add entities. + try: + pglab_device = await self.__build_device(mqtt, msg) + except PGLabDiscoveryError as err: + LOGGER.warning("Can't create PGLabDiscovery instance(%s) ", str(err)) + + # For some reason it's not possible to create the device with the discovery message, + # be sure that any previous device with the same topic is now destroyed. + device_id = get_device_id_from_discovery_topic(msg.topic) + + # If there is a valid topic device_id clean everything relative to the device. + if device_id: + self.__clean_discovered_device(hass, device_id) + + return + + # Create a new device. + device_registry = dr.async_get(hass) + device_registry.async_get_or_create( + config_entry_id=entry.entry_id, + configuration_url=f"http://{pglab_device.ip}/", + connections={(CONNECTION_NETWORK_MAC, pglab_device.mac)}, + identifiers={(DOMAIN, pglab_device.id)}, + manufacturer=pglab_device.manufactor, + model=pglab_device.type, + name=pglab_device.name, + sw_version=pglab_device.firmware_version, + hw_version=pglab_device.hardware_version, + ) + + # Do some checking if previous entities must be updated. + if pglab_device.id in self._discovered: + # The device is already been discovered, + # get the old discovery info data. + discovery_info = self._discovered[pglab_device.id] + + if discovery_info.hash == pglab_device.hash: + # Best case, there is nothing to do. + # The device is still in the same configuration. Same name, same shutters, same relay etc. + return + + LOGGER.warning( + "Changed internal configuration of device(%s). Rebuilding all entities", + pglab_device.id, + ) + + # Something has changed, all previous entities must be destroyed and re-created. + self.__clean_discovered_device(hass, pglab_device.id) + + # Add a new device. + discovery_info = DiscoverDeviceInfo(pglab_device) + self._discovered[pglab_device.id] = discovery_info + + # Create all new relay entities. + for r in pglab_device.relays: + # The HA entity is not yet created, send a message to create it. + async_dispatcher_send( + hass, CREATE_NEW_ENTITY[Platform.SWITCH], pglab_device, r + ) + + topics = { + "discovery_topic": { + "topic": f"{self._discovery_topic}/#", + "msg_callback": discovery_message_received, + } + } + + # Forward setup all HA supported platforms. + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + + self._mqtt_client = mqtt + self._substate = async_prepare_subscribe_topics(hass, self._substate, topics) + await async_subscribe_topics(hass, self._substate) + + async def register_platform( + self, hass: HomeAssistant, platform: Platform, target: Callable[..., Any] + ): + """Register a callback to create entity of a specific HA platform.""" + disconnect_callback = async_dispatcher_connect( + hass, CREATE_NEW_ENTITY[platform], target + ) + self._disconnect_platform.append(disconnect_callback) + + async def stop(self, hass: HomeAssistant, entry: PGLABConfigEntry) -> None: + """Stop to discovery PG LAB devices.""" + await hass.config_entries.async_unload_platforms(entry, PLATFORMS) + + # Disconnect all registered platforms. + for disconnect_callback in self._disconnect_platform: + disconnect_callback() + + async_unsubscribe_topics(hass, self._substate) + + async def add_entity(self, entity: Entity, device_id: str): + """Save a new PG LAB device entity.""" + + # Be sure that the device is been discovered. + if device_id not in self._discovered: + raise PGLabDiscoveryError("Unknown device, device_id not discovered") + + discovery_info = self._discovered[device_id] + discovery_info.add_entity(entity) diff --git a/homeassistant/components/pglab/entity.py b/homeassistant/components/pglab/entity.py new file mode 100644 index 00000000000..1b8975a3bbe --- /dev/null +++ b/homeassistant/components/pglab/entity.py @@ -0,0 +1,70 @@ +"""Entity for PG LAB Electronics.""" + +from __future__ import annotations + +from pypglab.device import Device as PyPGLabDevice +from pypglab.entity import Entity as PyPGLabEntity + +from homeassistant.core import callback +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo +from homeassistant.helpers.entity import Entity + +from .const import DOMAIN +from .discovery import PGLabDiscovery + + +class PGLabEntity(Entity): + """Representation of a PGLab entity in Home Assistant.""" + + _attr_has_entity_name = True + + def __init__( + self, + discovery: PGLabDiscovery, + device: PyPGLabDevice, + entity: PyPGLabEntity, + ) -> None: + """Initialize the class.""" + + self._id = entity.id + self._device_id = device.id + self._entity = entity + self._discovery = discovery + + # Information about the device that is partially visible in the UI. + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, device.id)}, + name=device.name, + sw_version=device.firmware_version, + hw_version=device.hardware_version, + model=device.type, + manufacturer=device.manufactor, + configuration_url=f"http://{device.ip}/", + connections={(CONNECTION_NETWORK_MAC, device.mac)}, + ) + + async def async_added_to_hass(self) -> None: + """Update the device discovery info.""" + + self._entity.set_on_state_callback(self.state_updated) + await self._entity.subscribe_topics() + + await super().async_added_to_hass() + + # Inform PGLab discovery instance that a new entity is available. + # This is important to know in case the device needs to be reconfigured + # and the entity can be potentially destroyed. + await self._discovery.add_entity(self, self._device_id) + + async def async_will_remove_from_hass(self) -> None: + """Unsubscribe when removed.""" + + await super().async_will_remove_from_hass() + + await self._entity.unsubscribe_topics() + self._entity.set_on_state_callback(None) + + @callback + def state_updated(self, payload: str) -> None: + """Handle state updates.""" + self.async_write_ha_state() diff --git a/homeassistant/components/pglab/manifest.json b/homeassistant/components/pglab/manifest.json new file mode 100644 index 00000000000..7f7d596be77 --- /dev/null +++ b/homeassistant/components/pglab/manifest.json @@ -0,0 +1,14 @@ +{ + "domain": "pglab", + "name": "PG LAB Electronics", + "codeowners": ["@pglab-electronics"], + "config_flow": true, + "dependencies": ["mqtt"], + "documentation": "https://www.home-assistant.io/integrations/pglab", + "iot_class": "local_push", + "loggers": ["pglab"], + "mqtt": ["pglab/discovery/#"], + "quality_scale": "bronze", + "requirements": ["pypglab==0.0.3"], + "single_config_entry": true +} diff --git a/homeassistant/components/pglab/quality_scale.yaml b/homeassistant/components/pglab/quality_scale.yaml new file mode 100644 index 00000000000..dda637e5833 --- /dev/null +++ b/homeassistant/components/pglab/quality_scale.yaml @@ -0,0 +1,80 @@ +rules: + # Bronze + action-setup: + status: exempt + comment: The integration does not provide any additional actions. + appropriate-polling: + status: exempt + comment: The integration does not poll. + brands: done + common-modules: done + config-flow-test-coverage: done + config-flow: done + dependency-transparency: done + docs-actions: + status: exempt + comment: The integration does not provide any additional actions. + docs-high-level-description: done + docs-installation-instructions: done + docs-removal-instructions: done + entity-event-setup: done + entity-unique-id: done + has-entity-name: done + runtime-data: done + test-before-configure: + status: exempt + comment: The integration relies solely on auto-discovery. + test-before-setup: done + unique-config-entry: done + + # Silver + action-exceptions: + status: exempt + comment: The integration does not provide any additional actions. + config-entry-unloading: done + docs-configuration-parameters: + status: exempt + comment: No options flow. + docs-installation-parameters: + status: exempt + comment: There are no parameters. + entity-unavailable: todo + integration-owner: done + log-when-unavailable: todo + parallel-updates: done + reauthentication-flow: + status: exempt + comment: The integration does not require authentication. + test-coverage: todo + + # Gold + devices: done + diagnostics: todo + discovery-update-info: done + discovery: done + docs-data-update: todo + docs-examples: todo + docs-known-limitations: todo + docs-supported-devices: todo + docs-supported-functions: done + docs-troubleshooting: todo + docs-use-cases: todo + dynamic-devices: done + entity-category: done + entity-device-class: done + entity-disabled-by-default: done + entity-translations: todo + exception-translations: todo + icon-translations: todo + reconfiguration-flow: + status: exempt + comment: The integration has no settings. + repair-issues: todo + stale-devices: todo + + # Platinum + async-dependency: done + inject-websession: + status: exempt + comment: The integration does not make HTTP requests. + strict-typing: todo diff --git a/homeassistant/components/pglab/strings.json b/homeassistant/components/pglab/strings.json new file mode 100644 index 00000000000..8f9021cdcca --- /dev/null +++ b/homeassistant/components/pglab/strings.json @@ -0,0 +1,24 @@ +{ + "config": { + "step": { + "confirm_from_user": { + "description": "In order to be found PG LAB Electronics devices need to be connected to the same broker as the Home Assistant MQTT integration client. Do you want to continue?" + }, + "confirm_from_mqtt": { + "description": "Do you want to set up PG LAB Electronics?" + } + }, + "abort": { + "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]", + "mqtt_not_connected": "Home Assistant MQTT integration not connected to MQTT broker.", + "mqtt_not_configured": "Home Assistant MQTT integration not configured." + } + }, + "entity": { + "switch": { + "relay": { + "name": "Relay {relay_id}" + } + } + } +} diff --git a/homeassistant/components/pglab/switch.py b/homeassistant/components/pglab/switch.py new file mode 100644 index 00000000000..554b5cf80ca --- /dev/null +++ b/homeassistant/components/pglab/switch.py @@ -0,0 +1,76 @@ +"""Switch for PG LAB Electronics.""" + +from __future__ import annotations + +from typing import Any + +from pypglab.device import Device as PyPGLabDevice +from pypglab.relay import Relay as PyPGLabRelay + +from homeassistant.components.switch import SwitchEntity +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback + +from . import PGLABConfigEntry +from .discovery import PGLabDiscovery +from .entity import PGLabEntity + +PARALLEL_UPDATES = 0 + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: PGLABConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, +) -> None: + """Set up switches for device.""" + + @callback + def async_discover(pglab_device: PyPGLabDevice, pglab_relay: PyPGLabRelay) -> None: + """Discover and add a PGLab Relay.""" + pglab_discovery = config_entry.runtime_data + pglab_switch = PGLabSwitch(pglab_discovery, pglab_device, pglab_relay) + async_add_entities([pglab_switch]) + + # Register the callback to create the switch entity when discovered. + pglab_discovery = config_entry.runtime_data + await pglab_discovery.register_platform(hass, Platform.SWITCH, async_discover) + + +class PGLabSwitch(PGLabEntity, SwitchEntity): + """A PGLab switch.""" + + _attr_translation_key = "relay" + + def __init__( + self, + pglab_discovery: PGLabDiscovery, + pglab_device: PyPGLabDevice, + pglab_relay: PyPGLabRelay, + ) -> None: + """Initialize the Switch class.""" + + super().__init__( + discovery=pglab_discovery, + device=pglab_device, + entity=pglab_relay, + ) + + self._attr_unique_id = f"{pglab_device.id}_relay{pglab_relay.id}" + self._attr_translation_placeholders = {"relay_id": pglab_relay.id} + + self._relay = pglab_relay + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn the device on.""" + await self._relay.turn_on() + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn the device off.""" + await self._relay.turn_off() + + @property + def is_on(self) -> bool: + """Return true if device is on.""" + return self._relay.state diff --git a/homeassistant/components/philips_js/__init__.py b/homeassistant/components/philips_js/__init__.py index 93f869e849d..9ff101915b8 100644 --- a/homeassistant/components/philips_js/__init__.py +++ b/homeassistant/components/philips_js/__init__.py @@ -7,7 +7,6 @@ import logging from haphilipsjs import PhilipsTV from haphilipsjs.typing import SystemType -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_API_VERSION, CONF_HOST, @@ -18,7 +17,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from .const import CONF_SYSTEM -from .coordinator import PhilipsTVDataUpdateCoordinator +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator PLATFORMS = [ Platform.BINARY_SENSOR, @@ -30,8 +29,6 @@ PLATFORMS = [ LOGGER = logging.getLogger(__name__) -PhilipsTVConfigEntry = ConfigEntry[PhilipsTVDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> bool: """Set up Philips TV from a config entry.""" @@ -44,7 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> password=entry.data.get(CONF_PASSWORD), system=system, ) - coordinator = PhilipsTVDataUpdateCoordinator(hass, tvapi, entry.options) + coordinator = PhilipsTVDataUpdateCoordinator(hass, entry, tvapi) await coordinator.async_refresh() diff --git a/homeassistant/components/philips_js/binary_sensor.py b/homeassistant/components/philips_js/binary_sensor.py index 6de814efd97..3667d37dc48 100644 --- a/homeassistant/components/philips_js/binary_sensor.py +++ b/homeassistant/components/philips_js/binary_sensor.py @@ -11,10 +11,9 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PhilipsTVConfigEntry -from .coordinator import PhilipsTVDataUpdateCoordinator +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator from .entity import PhilipsJsEntity @@ -42,7 +41,7 @@ DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: PhilipsTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/philips_js/coordinator.py b/homeassistant/components/philips_js/coordinator.py index cae59fa5123..f450e971093 100644 --- a/homeassistant/components/philips_js/coordinator.py +++ b/homeassistant/components/philips_js/coordinator.py @@ -3,10 +3,8 @@ from __future__ import annotations import asyncio -from collections.abc import Mapping from datetime import timedelta import logging -from typing import Any from haphilipsjs import ( AutenticationFailure, @@ -27,23 +25,28 @@ from .const import CONF_ALLOW_NOTIFY, CONF_SYSTEM, DOMAIN _LOGGER = logging.getLogger(__name__) +type PhilipsTVConfigEntry = ConfigEntry[PhilipsTVDataUpdateCoordinator] + class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): """Coordinator to update data.""" - config_entry: ConfigEntry + config_entry: PhilipsTVConfigEntry def __init__( - self, hass: HomeAssistant, api: PhilipsTV, options: Mapping[str, Any] + self, + hass: HomeAssistant, + config_entry: PhilipsTVConfigEntry, + api: PhilipsTV, ) -> None: """Set up the coordinator.""" self.api = api - self.options = options self._notify_future: asyncio.Task | None = None super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), request_refresh_debouncer=Debouncer( @@ -91,7 +94,7 @@ class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): self.api.on and self.api.powerstate == "On" and self.api.notify_change_supported - and self.options.get(CONF_ALLOW_NOTIFY, False) + and self.config_entry.options.get(CONF_ALLOW_NOTIFY, False) ) async def _notify_task(self): diff --git a/homeassistant/components/philips_js/diagnostics.py b/homeassistant/components/philips_js/diagnostics.py index 625b77f6c25..99b27b2c85a 100644 --- a/homeassistant/components/philips_js/diagnostics.py +++ b/homeassistant/components/philips_js/diagnostics.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.diagnostics import async_redact_data from homeassistant.core import HomeAssistant -from . import PhilipsTVConfigEntry +from .coordinator import PhilipsTVConfigEntry TO_REDACT = { "serialnumber_encrypted", diff --git a/homeassistant/components/philips_js/light.py b/homeassistant/components/philips_js/light.py index 1d63b2062e6..bf15292335e 100644 --- a/homeassistant/components/philips_js/light.py +++ b/homeassistant/components/philips_js/light.py @@ -18,11 +18,10 @@ from homeassistant.components.light import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.color import color_hsv_to_RGB, color_RGB_to_hsv -from . import PhilipsTVConfigEntry -from .coordinator import PhilipsTVDataUpdateCoordinator +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator from .entity import PhilipsJsEntity EFFECT_PARTITION = ": " @@ -35,7 +34,7 @@ EFFECT_EXPERT_STYLES = {"FOLLOW_AUDIO", "FOLLOW_COLOR", "Lounge light"} async def async_setup_entry( hass: HomeAssistant, config_entry: PhilipsTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/philips_js/media_player.py b/homeassistant/components/philips_js/media_player.py index bd8727ae9c1..a433a63f31f 100644 --- a/homeassistant/components/philips_js/media_player.py +++ b/homeassistant/components/philips_js/media_player.py @@ -18,11 +18,11 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.trigger import PluggableAction -from . import LOGGER as _LOGGER, PhilipsTVConfigEntry -from .coordinator import PhilipsTVDataUpdateCoordinator +from . import LOGGER as _LOGGER +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator from .entity import PhilipsJsEntity from .helpers import async_get_turn_on_trigger @@ -49,7 +49,7 @@ def _inverted(data): async def async_setup_entry( hass: HomeAssistant, config_entry: PhilipsTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/philips_js/remote.py b/homeassistant/components/philips_js/remote.py index f8d9cb0885d..b026b33a857 100644 --- a/homeassistant/components/philips_js/remote.py +++ b/homeassistant/components/philips_js/remote.py @@ -13,11 +13,11 @@ from homeassistant.components.remote import ( RemoteEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.trigger import PluggableAction -from . import LOGGER, PhilipsTVConfigEntry -from .coordinator import PhilipsTVDataUpdateCoordinator +from . import LOGGER +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator from .entity import PhilipsJsEntity from .helpers import async_get_turn_on_trigger @@ -25,7 +25,7 @@ from .helpers import async_get_turn_on_trigger async def async_setup_entry( hass: HomeAssistant, config_entry: PhilipsTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/philips_js/switch.py b/homeassistant/components/philips_js/switch.py index b35b2ad4ff1..45963432665 100644 --- a/homeassistant/components/philips_js/switch.py +++ b/homeassistant/components/philips_js/switch.py @@ -6,10 +6,9 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PhilipsTVConfigEntry -from .coordinator import PhilipsTVDataUpdateCoordinator +from .coordinator import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator from .entity import PhilipsJsEntity HUE_POWER_OFF = "Off" @@ -19,7 +18,7 @@ HUE_POWER_ON = "On" async def async_setup_entry( hass: HomeAssistant, config_entry: PhilipsTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the configuration entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/pi_hole/binary_sensor.py b/homeassistant/components/pi_hole/binary_sensor.py index 5e3ce560ab4..1d12307b6e5 100644 --- a/homeassistant/components/pi_hole/binary_sensor.py +++ b/homeassistant/components/pi_hole/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import PiHoleConfigEntry @@ -41,7 +41,7 @@ BINARY_SENSOR_TYPES: tuple[PiHoleBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PiHoleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Pi-hole binary sensor.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/pi_hole/sensor.py b/homeassistant/components/pi_hole/sensor.py index 4cf5133e700..54a9cb23d02 100644 --- a/homeassistant/components/pi_hole/sensor.py +++ b/homeassistant/components/pi_hole/sensor.py @@ -7,7 +7,7 @@ from hole import Hole from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import CONF_NAME, PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -47,7 +47,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PiHoleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Pi-hole sensor.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/pi_hole/switch.py b/homeassistant/components/pi_hole/switch.py index 805ba479a9e..84ffe7e51a4 100644 --- a/homeassistant/components/pi_hole/switch.py +++ b/homeassistant/components/pi_hole/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import PiHoleConfigEntry from .const import SERVICE_DISABLE, SERVICE_DISABLE_ATTR_DURATION @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: PiHoleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Pi-hole switch.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/pi_hole/update.py b/homeassistant/components/pi_hole/update.py index 510f5d1dc19..56e92b47289 100644 --- a/homeassistant/components/pi_hole/update.py +++ b/homeassistant/components/pi_hole/update.py @@ -10,7 +10,7 @@ from hole import Hole from homeassistant.components.update import UpdateEntity, UpdateEntityDescription from homeassistant.const import CONF_NAME, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import PiHoleConfigEntry @@ -65,7 +65,7 @@ UPDATE_ENTITY_TYPES: tuple[PiHoleUpdateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PiHoleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Pi-hole update entities.""" name = entry.data[CONF_NAME] diff --git a/homeassistant/components/picnic/sensor.py b/homeassistant/components/picnic/sensor.py index 866bd6b56c1..dcfd9086491 100644 --- a/homeassistant/components/picnic/sensor.py +++ b/homeassistant/components/picnic/sensor.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CURRENCY_EURO from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -203,7 +203,7 @@ SENSOR_TYPES: tuple[PicnicSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Picnic sensor entries.""" picnic_coordinator = hass.data[DOMAIN][config_entry.entry_id][CONF_COORDINATOR] diff --git a/homeassistant/components/picnic/todo.py b/homeassistant/components/picnic/todo.py index 7fa2bbccd3e..383c236de3c 100644 --- a/homeassistant/components/picnic/todo.py +++ b/homeassistant/components/picnic/todo.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_COORDINATOR, DOMAIN @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Picnic shopping cart todo platform config entry.""" picnic_coordinator = hass.data[DOMAIN][config_entry.entry_id][CONF_COORDINATOR] diff --git a/homeassistant/components/ping/__init__.py b/homeassistant/components/ping/__init__.py index 4b03e5e4407..14203541359 100644 --- a/homeassistant/components/ping/__init__.py +++ b/homeassistant/components/ping/__init__.py @@ -6,7 +6,6 @@ import logging from icmplib import SocketPermissionError, async_ping -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv @@ -14,7 +13,7 @@ from homeassistant.helpers.typing import ConfigType from homeassistant.util.hass_dict import HassKey from .const import CONF_PING_COUNT, DOMAIN -from .coordinator import PingUpdateCoordinator +from .coordinator import PingConfigEntry, PingUpdateCoordinator from .helpers import PingDataICMPLib, PingDataSubProcess _LOGGER = logging.getLogger(__name__) @@ -24,9 +23,6 @@ PLATFORMS = [Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER, Platform.SENSOR] DATA_PRIVILEGED_KEY: HassKey[bool | None] = HassKey(DOMAIN) -type PingConfigEntry = ConfigEntry[PingUpdateCoordinator] - - async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the ping integration.""" hass.data[DATA_PRIVILEGED_KEY] = await _can_use_icmp_lib_with_privilege() @@ -47,7 +43,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PingConfigEntry) -> bool ping_cls = PingDataICMPLib coordinator = PingUpdateCoordinator( - hass=hass, ping=ping_cls(hass, host, count, privileged) + hass=hass, config_entry=entry, ping=ping_cls(hass, host, count, privileged) ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/ping/binary_sensor.py b/homeassistant/components/ping/binary_sensor.py index 5c50e4335f9..35bf2707694 100644 --- a/homeassistant/components/ping/binary_sensor.py +++ b/homeassistant/components/ping/binary_sensor.py @@ -6,18 +6,18 @@ from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PingConfigEntry from .const import CONF_IMPORTED_BY -from .coordinator import PingUpdateCoordinator +from .coordinator import PingConfigEntry, PingUpdateCoordinator from .entity import PingEntity async def async_setup_entry( - hass: HomeAssistant, entry: PingConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: PingConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Ping config entry.""" async_add_entities([PingBinarySensor(entry, entry.runtime_data)]) @@ -31,7 +31,7 @@ class PingBinarySensor(PingEntity, BinarySensorEntity): _attr_name = None def __init__( - self, config_entry: ConfigEntry, coordinator: PingUpdateCoordinator + self, config_entry: PingConfigEntry, coordinator: PingUpdateCoordinator ) -> None: """Initialize the Ping Binary sensor.""" super().__init__(config_entry, coordinator, config_entry.entry_id) diff --git a/homeassistant/components/ping/coordinator.py b/homeassistant/components/ping/coordinator.py index 38ab2e79ffc..afb7de4dce3 100644 --- a/homeassistant/components/ping/coordinator.py +++ b/homeassistant/components/ping/coordinator.py @@ -7,6 +7,7 @@ from datetime import timedelta import logging from typing import Any +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -14,6 +15,8 @@ from .helpers import PingDataICMPLib, PingDataSubProcess _LOGGER = logging.getLogger(__name__) +type PingConfigEntry = ConfigEntry[PingUpdateCoordinator] + @dataclass(slots=True, frozen=True) class PingResult: @@ -27,11 +30,13 @@ class PingResult: class PingUpdateCoordinator(DataUpdateCoordinator[PingResult]): """The Ping update coordinator.""" + config_entry: PingConfigEntry ping: PingDataSubProcess | PingDataICMPLib def __init__( self, hass: HomeAssistant, + config_entry: PingConfigEntry, ping: PingDataSubProcess | PingDataICMPLib, ) -> None: """Initialize the Ping coordinator.""" @@ -40,6 +45,7 @@ class PingUpdateCoordinator(DataUpdateCoordinator[PingResult]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"Ping {ping.ip_address}", update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/ping/device_tracker.py b/homeassistant/components/ping/device_tracker.py index 29a4e922234..9d093da262d 100644 --- a/homeassistant/components/ping/device_tracker.py +++ b/homeassistant/components/ping/device_tracker.py @@ -9,19 +9,19 @@ from homeassistant.components.device_tracker import ( DEFAULT_CONSIDER_HOME, ScannerEntity, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util -from . import PingConfigEntry from .const import CONF_IMPORTED_BY -from .coordinator import PingUpdateCoordinator +from .coordinator import PingConfigEntry, PingUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: PingConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: PingConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Ping config entry.""" async_add_entities([PingDeviceTracker(entry, entry.runtime_data)]) @@ -33,7 +33,7 @@ class PingDeviceTracker(CoordinatorEntity[PingUpdateCoordinator], ScannerEntity) _last_seen: datetime | None = None def __init__( - self, config_entry: ConfigEntry, coordinator: PingUpdateCoordinator + self, config_entry: PingConfigEntry, coordinator: PingUpdateCoordinator ) -> None: """Initialize the Ping device tracker.""" super().__init__(coordinator) diff --git a/homeassistant/components/ping/entity.py b/homeassistant/components/ping/entity.py index a1f84f6ef32..d592ef6b549 100644 --- a/homeassistant/components/ping/entity.py +++ b/homeassistant/components/ping/entity.py @@ -1,11 +1,10 @@ """Base entity for the Ping component.""" -from homeassistant.config_entries import ConfigEntry from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .coordinator import PingUpdateCoordinator +from .coordinator import PingConfigEntry, PingUpdateCoordinator class PingEntity(CoordinatorEntity[PingUpdateCoordinator]): @@ -15,7 +14,7 @@ class PingEntity(CoordinatorEntity[PingUpdateCoordinator]): def __init__( self, - config_entry: ConfigEntry, + config_entry: PingConfigEntry, coordinator: PingUpdateCoordinator, unique_id: str, ) -> None: diff --git a/homeassistant/components/ping/sensor.py b/homeassistant/components/ping/sensor.py index 6e6c4cf2cde..82d88064e02 100644 --- a/homeassistant/components/ping/sensor.py +++ b/homeassistant/components/ping/sensor.py @@ -12,10 +12,9 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PingConfigEntry -from .coordinator import PingResult, PingUpdateCoordinator +from .coordinator import PingConfigEntry, PingResult, PingUpdateCoordinator from .entity import PingEntity @@ -76,7 +75,9 @@ SENSORS: tuple[PingSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: PingConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: PingConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ping sensors from config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plaato/__init__.py b/homeassistant/components/plaato/__init__.py index 6001a243a2d..14e757d4623 100644 --- a/homeassistant/components/plaato/__init__.py +++ b/homeassistant/components/plaato/__init__.py @@ -121,7 +121,9 @@ async def async_setup_coordinator(hass: HomeAssistant, entry: ConfigEntry): else: update_interval = timedelta(minutes=DEFAULT_SCAN_INTERVAL) - coordinator = PlaatoCoordinator(hass, auth_token, device_type, update_interval) + coordinator = PlaatoCoordinator( + hass, entry, auth_token, device_type, update_interval + ) await coordinator.async_config_entry_first_refresh() _set_entry_data(entry, hass, coordinator, auth_token) diff --git a/homeassistant/components/plaato/binary_sensor.py b/homeassistant/components/plaato/binary_sensor.py index 42019bbec9b..b71673aa1fd 100644 --- a/homeassistant/components/plaato/binary_sensor.py +++ b/homeassistant/components/plaato/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_USE_WEBHOOK, COORDINATOR, DOMAIN from .entity import PlaatoEntity @@ -19,7 +19,7 @@ from .entity import PlaatoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plaato from a config entry.""" diff --git a/homeassistant/components/plaato/coordinator.py b/homeassistant/components/plaato/coordinator.py index 8d21f17880a..df360d50068 100644 --- a/homeassistant/components/plaato/coordinator.py +++ b/homeassistant/components/plaato/coordinator.py @@ -5,6 +5,7 @@ import logging from pyplaato.plaato import Plaato, PlaatoDeviceType +from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import aiohttp_client @@ -18,9 +19,12 @@ _LOGGER = logging.getLogger(__name__) class PlaatoCoordinator(DataUpdateCoordinator): """Class to manage fetching data from the API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, auth_token: str, device_type: PlaatoDeviceType, update_interval: timedelta, @@ -34,6 +38,7 @@ class PlaatoCoordinator(DataUpdateCoordinator): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=update_interval, ) diff --git a/homeassistant/components/plaato/sensor.py b/homeassistant/components/plaato/sensor.py index b11bac40144..7a98c8a1ced 100644 --- a/homeassistant/components/plaato/sensor.py +++ b/homeassistant/components/plaato/sensor.py @@ -12,7 +12,10 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import ATTR_TEMP, SENSOR_UPDATE @@ -38,7 +41,9 @@ async def async_setup_platform( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plaato from a config entry.""" entry_data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/plex/button.py b/homeassistant/components/plex/button.py index 8bb34be38ce..5ed34eac6b2 100644 --- a/homeassistant/components/plex/button.py +++ b/homeassistant/components/plex/button.py @@ -8,7 +8,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_send -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import PlexServer from .const import CONF_SERVER_IDENTIFIER, DOMAIN, PLEX_UPDATE_PLATFORMS_SIGNAL @@ -18,7 +18,7 @@ from .helpers import get_plex_server async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plex button from config entry.""" server_id: str = config_entry.data[CONF_SERVER_IDENTIFIER] diff --git a/homeassistant/components/plex/media_player.py b/homeassistant/components/plex/media_player.py index 1dd79ad27a5..4a1654959f6 100644 --- a/homeassistant/components/plex/media_player.py +++ b/homeassistant/components/plex/media_player.py @@ -27,7 +27,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.network import is_internal_request from .const import ( @@ -68,7 +68,7 @@ def needs_session[_PlexMediaPlayerT: PlexMediaPlayer, **_P, _R]( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plex media_player from a config entry.""" server_id = config_entry.data[CONF_SERVER_IDENTIFIER] diff --git a/homeassistant/components/plex/sensor.py b/homeassistant/components/plex/sensor.py index eb27f465a7e..66e513dd83a 100644 --- a/homeassistant/components/plex/sensor.py +++ b/homeassistant/components/plex/sensor.py @@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_SERVER_IDENTIFIER, @@ -52,7 +52,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plex sensor from a config entry.""" server_id = config_entry.data[CONF_SERVER_IDENTIFIER] diff --git a/homeassistant/components/plex/update.py b/homeassistant/components/plex/update.py index 7acf4551f33..9b7645cd078 100644 --- a/homeassistant/components/plex/update.py +++ b/homeassistant/components/plex/update.py @@ -11,7 +11,7 @@ from homeassistant.components.update import UpdateEntity, UpdateEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_SERVER_IDENTIFIER from .helpers import get_plex_server @@ -22,7 +22,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plex update entities from a config entry.""" server_id = config_entry.data[CONF_SERVER_IDENTIFIER] diff --git a/homeassistant/components/plugwise/__init__.py b/homeassistant/components/plugwise/__init__.py index f1cc7c6c11d..e97493a78a7 100644 --- a/homeassistant/components/plugwise/__init__.py +++ b/homeassistant/components/plugwise/__init__.py @@ -4,22 +4,19 @@ from __future__ import annotations from typing import Any -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from .const import DOMAIN, LOGGER, PLATFORMS -from .coordinator import PlugwiseDataUpdateCoordinator - -type PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator] +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: PlugwiseConfigEntry) -> bool: """Set up Plugwise components from a config entry.""" await er.async_migrate_entries(hass, entry.entry_id, async_migrate_entity_entry) - coordinator = PlugwiseDataUpdateCoordinator(hass) + coordinator = PlugwiseDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() migrate_sensor_entities(hass, coordinator) diff --git a/homeassistant/components/plugwise/binary_sensor.py b/homeassistant/components/plugwise/binary_sensor.py index a4c6e051c78..f2c2fd6ed68 100644 --- a/homeassistant/components/plugwise/binary_sensor.py +++ b/homeassistant/components/plugwise/binary_sensor.py @@ -15,10 +15,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity SEVERITIES = ["other", "info", "warning", "error"] @@ -86,7 +85,7 @@ BINARY_SENSORS: tuple[PlugwiseBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smile binary_sensors from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/button.py b/homeassistant/components/plugwise/button.py index 139b358162c..c0896b602f0 100644 --- a/homeassistant/components/plugwise/button.py +++ b/homeassistant/components/plugwise/button.py @@ -5,11 +5,10 @@ from __future__ import annotations from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry from .const import REBOOT -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity from .util import plugwise_command @@ -19,7 +18,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Plugwise buttons from a ConfigEntry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/climate.py b/homeassistant/components/plugwise/climate.py index 7abdfcfde54..c7fac07f1cb 100644 --- a/homeassistant/components/plugwise/climate.py +++ b/homeassistant/components/plugwise/climate.py @@ -16,11 +16,10 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry from .const import DOMAIN, MASTER_THERMOSTATS -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity from .util import plugwise_command @@ -30,7 +29,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smile Thermostats from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/coordinator.py b/homeassistant/components/plugwise/coordinator.py index 9a85ae2a5df..b346f26492c 100644 --- a/homeassistant/components/plugwise/coordinator.py +++ b/homeassistant/components/plugwise/coordinator.py @@ -24,19 +24,22 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DEFAULT_PORT, DEFAULT_USERNAME, DOMAIN, LOGGER +type PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator] + class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[dict[str, GwEntityData]]): """Class to manage fetching Plugwise data from single endpoint.""" _connected: bool = False - config_entry: ConfigEntry + config_entry: PlugwiseConfigEntry - def __init__(self, hass: HomeAssistant) -> None: + def __init__(self, hass: HomeAssistant, config_entry: PlugwiseConfigEntry) -> None: """Initialize the coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=60), # Don't refresh immediately, give the device time to process diff --git a/homeassistant/components/plugwise/diagnostics.py b/homeassistant/components/plugwise/diagnostics.py index a576e60dbe1..e97405f6279 100644 --- a/homeassistant/components/plugwise/diagnostics.py +++ b/homeassistant/components/plugwise/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import PlugwiseConfigEntry +from .coordinator import PlugwiseConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/plugwise/number.py b/homeassistant/components/plugwise/number.py index 2de49f17d4a..1dbb0506748 100644 --- a/homeassistant/components/plugwise/number.py +++ b/homeassistant/components/plugwise/number.py @@ -12,11 +12,10 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry from .const import NumberType -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity from .util import plugwise_command @@ -58,7 +57,7 @@ NUMBER_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plugwise number platform.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/select.py b/homeassistant/components/plugwise/select.py index 307091f0ff9..6ca1d4ce7a2 100644 --- a/homeassistant/components/plugwise/select.py +++ b/homeassistant/components/plugwise/select.py @@ -7,11 +7,10 @@ from dataclasses import dataclass from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry from .const import SelectOptionsType, SelectType -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity from .util import plugwise_command @@ -56,7 +55,7 @@ SELECT_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smile selector from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/sensor.py b/homeassistant/components/plugwise/sensor.py index 8b630c39878..7bd93e2ff84 100644 --- a/homeassistant/components/plugwise/sensor.py +++ b/homeassistant/components/plugwise/sensor.py @@ -25,10 +25,9 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity # Coordinator is used to centralize the data updates @@ -406,7 +405,7 @@ SENSORS: tuple[PlugwiseSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smile sensors from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plugwise/switch.py b/homeassistant/components/plugwise/switch.py index 86496a4311e..8179fb546b4 100644 --- a/homeassistant/components/plugwise/switch.py +++ b/homeassistant/components/plugwise/switch.py @@ -14,10 +14,9 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PlugwiseConfigEntry -from .coordinator import PlugwiseDataUpdateCoordinator +from .coordinator import PlugwiseConfigEntry, PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity from .util import plugwise_command @@ -58,7 +57,7 @@ SWITCHES: tuple[PlugwiseSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PlugwiseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smile switches from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/plum_lightpad/light.py b/homeassistant/components/plum_lightpad/light.py index 08a3d0ab0b9..78743c12808 100644 --- a/homeassistant/components/plum_lightpad/light.py +++ b/homeassistant/components/plum_lightpad/light.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import DOMAIN @@ -25,7 +25,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Plum Lightpad dimmer lights and glow rings.""" diff --git a/homeassistant/components/point/alarm_control_panel.py b/homeassistant/components/point/alarm_control_panel.py index 4e4e4238176..0f501d2ee09 100644 --- a/homeassistant/components/point/alarm_control_panel.py +++ b/homeassistant/components/point/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MinutPointClient from .const import DOMAIN as POINT_DOMAIN, POINT_DISCOVERY_NEW, SIGNAL_WEBHOOK @@ -33,7 +33,7 @@ EVENT_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Point's alarm_control_panel based on a config entry.""" diff --git a/homeassistant/components/point/binary_sensor.py b/homeassistant/components/point/binary_sensor.py index 546c7d9cb0f..c9338cb63f2 100644 --- a/homeassistant/components/point/binary_sensor.py +++ b/homeassistant/components/point/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN as POINT_DOMAIN, POINT_DISCOVERY_NEW, SIGNAL_WEBHOOK from .entity import MinutPointEntity @@ -43,7 +43,7 @@ DEVICES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Point's binary sensors based on a config entry.""" diff --git a/homeassistant/components/point/sensor.py b/homeassistant/components/point/sensor.py index d864c8bb18c..c959d09d606 100644 --- a/homeassistant/components/point/sensor.py +++ b/homeassistant/components/point/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfSoundPressure, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import parse_datetime from .const import DOMAIN as POINT_DOMAIN, POINT_DISCOVERY_NEW @@ -48,7 +48,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Point's sensors based on a config entry.""" diff --git a/homeassistant/components/poolsense/__init__.py b/homeassistant/components/poolsense/__init__.py index a4b6f7b60d8..a2e54712566 100644 --- a/homeassistant/components/poolsense/__init__.py +++ b/homeassistant/components/poolsense/__init__.py @@ -4,14 +4,11 @@ import logging from poolsense import PoolSense -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import aiohttp_client -from .coordinator import PoolSenseDataUpdateCoordinator - -type PoolSenseConfigEntry = ConfigEntry[PoolSenseDataUpdateCoordinator] +from .coordinator import PoolSenseConfigEntry, PoolSenseDataUpdateCoordinator PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR] @@ -33,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PoolSenseConfigEntry) -> _LOGGER.error("Invalid authentication") return False - coordinator = PoolSenseDataUpdateCoordinator(hass, poolsense) + coordinator = PoolSenseDataUpdateCoordinator(hass, entry, poolsense) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/poolsense/binary_sensor.py b/homeassistant/components/poolsense/binary_sensor.py index 7668845f318..b93f017501d 100644 --- a/homeassistant/components/poolsense/binary_sensor.py +++ b/homeassistant/components/poolsense/binary_sensor.py @@ -8,9 +8,9 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PoolSenseConfigEntry +from .coordinator import PoolSenseConfigEntry from .entity import PoolSenseEntity BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( @@ -30,7 +30,7 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: PoolSenseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/poolsense/coordinator.py b/homeassistant/components/poolsense/coordinator.py index d9e7e8468ff..557686f9145 100644 --- a/homeassistant/components/poolsense/coordinator.py +++ b/homeassistant/components/poolsense/coordinator.py @@ -5,11 +5,11 @@ from __future__ import annotations import asyncio from datetime import timedelta import logging -from typing import TYPE_CHECKING from poolsense import PoolSense from poolsense.exceptions import PoolSenseError +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL from homeassistant.core import HomeAssistant from homeassistant.helpers.typing import StateType @@ -17,20 +17,30 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN -if TYPE_CHECKING: - from . import PoolSenseConfigEntry - _LOGGER = logging.getLogger(__name__) +type PoolSenseConfigEntry = ConfigEntry[PoolSenseDataUpdateCoordinator] + class PoolSenseDataUpdateCoordinator(DataUpdateCoordinator[dict[str, StateType]]): """Define an object to hold PoolSense data.""" config_entry: PoolSenseConfigEntry - def __init__(self, hass: HomeAssistant, poolsense: PoolSense) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: PoolSenseConfigEntry, + poolsense: PoolSense, + ) -> None: """Initialize.""" - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=timedelta(hours=1)) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=timedelta(hours=1), + ) self.poolsense = poolsense self.email = self.config_entry.data[CONF_EMAIL] diff --git a/homeassistant/components/poolsense/sensor.py b/homeassistant/components/poolsense/sensor.py index 8cfb982d33b..b0ac4404237 100644 --- a/homeassistant/components/poolsense/sensor.py +++ b/homeassistant/components/poolsense/sensor.py @@ -9,10 +9,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfElectricPotential, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import PoolSenseConfigEntry +from .coordinator import PoolSenseConfigEntry from .entity import PoolSenseEntity SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( @@ -65,7 +65,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: PoolSenseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Defer sensor setup to the shared sensor module.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/powerfox/__init__.py b/homeassistant/components/powerfox/__init__.py index 243f3aacc4f..8e51985211d 100644 --- a/homeassistant/components/powerfox/__init__.py +++ b/homeassistant/components/powerfox/__init__.py @@ -6,18 +6,15 @@ import asyncio from powerfox import Powerfox, PowerfoxConnectionError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .coordinator import PowerfoxDataUpdateCoordinator +from .coordinator import PowerfoxConfigEntry, PowerfoxDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -type PowerfoxConfigEntry = ConfigEntry[list[PowerfoxDataUpdateCoordinator]] - async def async_setup_entry(hass: HomeAssistant, entry: PowerfoxConfigEntry) -> bool: """Set up Powerfox from a config entry.""" @@ -34,7 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PowerfoxConfigEntry) -> raise ConfigEntryNotReady from err coordinators: list[PowerfoxDataUpdateCoordinator] = [ - PowerfoxDataUpdateCoordinator(hass, client, device) for device in devices + PowerfoxDataUpdateCoordinator(hass, entry, client, device) for device in devices ] await asyncio.gather( diff --git a/homeassistant/components/powerfox/coordinator.py b/homeassistant/components/powerfox/coordinator.py index a4a26759b69..bd76b7cc166 100644 --- a/homeassistant/components/powerfox/coordinator.py +++ b/homeassistant/components/powerfox/coordinator.py @@ -18,15 +18,18 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN, LOGGER, SCAN_INTERVAL +type PowerfoxConfigEntry = ConfigEntry[list[PowerfoxDataUpdateCoordinator]] + class PowerfoxDataUpdateCoordinator(DataUpdateCoordinator[Poweropti]): """Class to manage fetching Powerfox data from the API.""" - config_entry: ConfigEntry + config_entry: PowerfoxConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: PowerfoxConfigEntry, client: Powerfox, device: Device, ) -> None: @@ -34,6 +37,7 @@ class PowerfoxDataUpdateCoordinator(DataUpdateCoordinator[Poweropti]): super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/powerfox/diagnostics.py b/homeassistant/components/powerfox/diagnostics.py index 4c6b0f8c6eb..8514e42537e 100644 --- a/homeassistant/components/powerfox/diagnostics.py +++ b/homeassistant/components/powerfox/diagnostics.py @@ -9,7 +9,7 @@ from powerfox import HeatMeter, PowerMeter, WaterMeter from homeassistant.core import HomeAssistant -from . import PowerfoxConfigEntry, PowerfoxDataUpdateCoordinator +from .coordinator import PowerfoxConfigEntry, PowerfoxDataUpdateCoordinator async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/powerfox/sensor.py b/homeassistant/components/powerfox/sensor.py index 6505139fcd9..ab60c99a58b 100644 --- a/homeassistant/components/powerfox/sensor.py +++ b/homeassistant/components/powerfox/sensor.py @@ -15,10 +15,9 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfEnergy, UnitOfPower, UnitOfVolume from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PowerfoxConfigEntry -from .coordinator import PowerfoxDataUpdateCoordinator +from .coordinator import PowerfoxConfigEntry, PowerfoxDataUpdateCoordinator from .entity import PowerfoxEntity @@ -131,7 +130,7 @@ SENSORS_HEAT: tuple[PowerfoxSensorEntityDescription[HeatMeter], ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PowerfoxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Powerfox sensors based on a config entry.""" entities: list[SensorEntity] = [] diff --git a/homeassistant/components/powerwall/binary_sensor.py b/homeassistant/components/powerwall/binary_sensor.py index c50876e22fb..100e31b1c21 100644 --- a/homeassistant/components/powerwall/binary_sensor.py +++ b/homeassistant/components/powerwall/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import PowerWallEntity from .models import PowerwallConfigEntry @@ -23,7 +23,7 @@ CONNECTED_GRID_STATUSES = { async def async_setup_entry( hass: HomeAssistant, entry: PowerwallConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the powerwall sensors.""" powerwall_data = entry.runtime_data diff --git a/homeassistant/components/powerwall/sensor.py b/homeassistant/components/powerwall/sensor.py index 28506e2a60c..b4988133727 100644 --- a/homeassistant/components/powerwall/sensor.py +++ b/homeassistant/components/powerwall/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import POWERWALL_COORDINATOR from .entity import BatteryEntity, PowerWallEntity @@ -213,7 +213,7 @@ BATTERY_INSTANT_SENSORS: list[PowerwallSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: PowerwallConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the powerwall sensors.""" powerwall_data = entry.runtime_data diff --git a/homeassistant/components/powerwall/switch.py b/homeassistant/components/powerwall/switch.py index 214ca01fb63..a874161de5b 100644 --- a/homeassistant/components/powerwall/switch.py +++ b/homeassistant/components/powerwall/switch.py @@ -8,7 +8,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import PowerWallEntity from .models import PowerwallConfigEntry, PowerwallRuntimeData @@ -22,7 +22,7 @@ OFF_GRID_STATUSES = { async def async_setup_entry( hass: HomeAssistant, entry: PowerwallConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Powerwall switch platform from Powerwall resources.""" async_add_entities([PowerwallOffGridEnabledEntity(entry.runtime_data)]) diff --git a/homeassistant/components/private_ble_device/device_tracker.py b/homeassistant/components/private_ble_device/device_tracker.py index fbaf0d44751..eaccbd6c785 100644 --- a/homeassistant/components/private_ble_device/device_tracker.py +++ b/homeassistant/components/private_ble_device/device_tracker.py @@ -11,7 +11,7 @@ from homeassistant.components.device_tracker.config_entry import BaseTrackerEnti from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_HOME, STATE_NOT_HOME from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import BasePrivateDeviceEntity @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Device Tracker entities for a config entry.""" async_add_entities([BasePrivateDeviceTracker(config_entry)]) diff --git a/homeassistant/components/private_ble_device/sensor.py b/homeassistant/components/private_ble_device/sensor.py index e2c4fb0c7da..d8c09500332 100644 --- a/homeassistant/components/private_ble_device/sensor.py +++ b/homeassistant/components/private_ble_device/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import BasePrivateDeviceEntity @@ -92,7 +92,9 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for Private BLE component.""" async_add_entities( diff --git a/homeassistant/components/progettihwsw/binary_sensor.py b/homeassistant/components/progettihwsw/binary_sensor.py index a89b8b3c3f1..40296dcac90 100644 --- a/homeassistant/components/progettihwsw/binary_sensor.py +++ b/homeassistant/components/progettihwsw/binary_sensor.py @@ -9,7 +9,7 @@ from ProgettiHWSW.input import Input from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(DOMAIN) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensors from a config entry.""" board_api = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/progettihwsw/switch.py b/homeassistant/components/progettihwsw/switch.py index 983a2383e99..256d90ae5b7 100644 --- a/homeassistant/components/progettihwsw/switch.py +++ b/homeassistant/components/progettihwsw/switch.py @@ -10,7 +10,7 @@ from ProgettiHWSW.relay import Relay from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(DOMAIN) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switches from a config entry.""" board_api = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/prosegur/alarm_control_panel.py b/homeassistant/components/prosegur/alarm_control_panel.py index 1c58b64cf55..1f0f89c5f04 100644 --- a/homeassistant/components/prosegur/alarm_control_panel.py +++ b/homeassistant/components/prosegur/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN @@ -30,7 +30,9 @@ STATE_MAPPING = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Prosegur alarm control panel platform.""" async_add_entities( diff --git a/homeassistant/components/prosegur/camera.py b/homeassistant/components/prosegur/camera.py index 2df6ff62038..3e1c91713e1 100644 --- a/homeassistant/components/prosegur/camera.py +++ b/homeassistant/components/prosegur/camera.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -24,7 +24,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Prosegur camera platform.""" diff --git a/homeassistant/components/proximity/sensor.py b/homeassistant/components/proximity/sensor.py index 55d4ca02b9b..72203a2dff4 100644 --- a/homeassistant/components/proximity/sensor.py +++ b/homeassistant/components/proximity/sensor.py @@ -13,7 +13,7 @@ from homeassistant.const import UnitOfLength from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -82,7 +82,7 @@ def _device_info(coordinator: ProximityDataUpdateCoordinator) -> DeviceInfo: async def async_setup_entry( hass: HomeAssistant, entry: ProximityConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the proximity sensors.""" diff --git a/homeassistant/components/prusalink/__init__.py b/homeassistant/components/prusalink/__init__.py index 1415e3dd0a6..4bb7dee411d 100644 --- a/homeassistant/components/prusalink/__init__.py +++ b/homeassistant/components/prusalink/__init__.py @@ -24,6 +24,7 @@ from .coordinator import ( InfoUpdateCoordinator, JobUpdateCoordinator, LegacyStatusCoordinator, + PrusaLinkUpdateCoordinator, StatusCoordinator, ) @@ -47,11 +48,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry.data[CONF_PASSWORD], ) - coordinators = { - "legacy_status": LegacyStatusCoordinator(hass, api), - "status": StatusCoordinator(hass, api), - "job": JobUpdateCoordinator(hass, api), - "info": InfoUpdateCoordinator(hass, api), + coordinators: dict[str, PrusaLinkUpdateCoordinator] = { + "legacy_status": LegacyStatusCoordinator(hass, entry, api), + "status": StatusCoordinator(hass, entry, api), + "job": JobUpdateCoordinator(hass, entry, api), + "info": InfoUpdateCoordinator(hass, entry, api), } for coordinator in coordinators.values(): await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/prusalink/binary_sensor.py b/homeassistant/components/prusalink/binary_sensor.py index d40ac8a4cfa..56be36c3e9d 100644 --- a/homeassistant/components/prusalink/binary_sensor.py +++ b/homeassistant/components/prusalink/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import PrusaLinkUpdateCoordinator @@ -57,7 +57,7 @@ BINARY_SENSORS: dict[str, tuple[PrusaLinkBinarySensorEntityDescription, ...]] = async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PrusaLink sensor based on a config entry.""" coordinators: dict[str, PrusaLinkUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/prusalink/button.py b/homeassistant/components/prusalink/button.py index 06d356b2ca6..59a63d874ee 100644 --- a/homeassistant/components/prusalink/button.py +++ b/homeassistant/components/prusalink/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import PrusaLinkUpdateCoordinator @@ -72,7 +72,7 @@ BUTTONS: dict[str, tuple[PrusaLinkButtonEntityDescription, ...]] = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PrusaLink buttons based on a config entry.""" coordinators: dict[str, PrusaLinkUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/prusalink/camera.py b/homeassistant/components/prusalink/camera.py index eee655447cc..6aac03ca179 100644 --- a/homeassistant/components/prusalink/camera.py +++ b/homeassistant/components/prusalink/camera.py @@ -7,7 +7,7 @@ from pyprusalink.types import PrinterState from homeassistant.components.camera import Camera from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import JobUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import PrusaLinkEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PrusaLink camera.""" coordinator: JobUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]["job"] diff --git a/homeassistant/components/prusalink/coordinator.py b/homeassistant/components/prusalink/coordinator.py index 1d887983931..e6f54bc6fa5 100644 --- a/homeassistant/components/prusalink/coordinator.py +++ b/homeassistant/components/prusalink/coordinator.py @@ -37,12 +37,18 @@ class PrusaLinkUpdateCoordinator(DataUpdateCoordinator[T], ABC): config_entry: ConfigEntry expect_change_until = 0.0 - def __init__(self, hass: HomeAssistant, api: PrusaLink) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: PrusaLink + ) -> None: """Initialize the update coordinator.""" self.api = api super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=self._get_update_interval(None) + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=self._get_update_interval(None), ) async def _async_update_data(self) -> T: diff --git a/homeassistant/components/prusalink/sensor.py b/homeassistant/components/prusalink/sensor.py index 0c746adbe2e..b9588f72a3c 100644 --- a/homeassistant/components/prusalink/sensor.py +++ b/homeassistant/components/prusalink/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow from homeassistant.util.variance import ignore_variance @@ -205,7 +205,7 @@ SENSORS: dict[str, tuple[PrusaLinkSensorEntityDescription, ...]] = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PrusaLink sensor based on a config entry.""" coordinators: dict[str, PrusaLinkUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/ps4/media_player.py b/homeassistant/components/ps4/media_player.py index 8db24beae20..4de7cbeb463 100644 --- a/homeassistant/components/ps4/media_player.py +++ b/homeassistant/components/ps4/media_player.py @@ -27,7 +27,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.json import JsonObjectType from . import format_unique_id, load_games, save_games @@ -48,7 +48,7 @@ DEFAULT_RETRIES = 2 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PS4 from a config entry.""" config = config_entry diff --git a/homeassistant/components/pure_energie/__init__.py b/homeassistant/components/pure_energie/__init__.py index 4de1ce02810..4ece35a3f1c 100644 --- a/homeassistant/components/pure_energie/__init__.py +++ b/homeassistant/components/pure_energie/__init__.py @@ -2,22 +2,19 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from .coordinator import PureEnergieDataUpdateCoordinator +from .coordinator import PureEnergieConfigEntry, PureEnergieDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -type PureEnergieConfigEntry = ConfigEntry[PureEnergieDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: PureEnergieConfigEntry) -> bool: """Set up Pure Energie from a config entry.""" - coordinator = PureEnergieDataUpdateCoordinator(hass) + coordinator = PureEnergieDataUpdateCoordinator(hass, entry) try: await coordinator.async_config_entry_first_refresh() except ConfigEntryNotReady: diff --git a/homeassistant/components/pure_energie/coordinator.py b/homeassistant/components/pure_energie/coordinator.py index fdd848eb4c6..cd66ab060eb 100644 --- a/homeassistant/components/pure_energie/coordinator.py +++ b/homeassistant/components/pure_energie/coordinator.py @@ -14,6 +14,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, LOGGER, SCAN_INTERVAL +type PureEnergieConfigEntry = ConfigEntry[PureEnergieDataUpdateCoordinator] + class PureEnergieData(NamedTuple): """Class for defining data in dict.""" @@ -25,16 +27,18 @@ class PureEnergieData(NamedTuple): class PureEnergieDataUpdateCoordinator(DataUpdateCoordinator[PureEnergieData]): """Class to manage fetching Pure Energie data from single eindpoint.""" - config_entry: ConfigEntry + config_entry: PureEnergieConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: PureEnergieConfigEntry, ) -> None: """Initialize global Pure Energie data updater.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/pure_energie/diagnostics.py b/homeassistant/components/pure_energie/diagnostics.py index de9134129ed..5098a298e85 100644 --- a/homeassistant/components/pure_energie/diagnostics.py +++ b/homeassistant/components/pure_energie/diagnostics.py @@ -9,7 +9,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant -from . import PureEnergieConfigEntry +from .coordinator import PureEnergieConfigEntry TO_REDACT = { CONF_HOST, diff --git a/homeassistant/components/pure_energie/sensor.py b/homeassistant/components/pure_energie/sensor.py index 468858f117f..ad57206adeb 100644 --- a/homeassistant/components/pure_energie/sensor.py +++ b/homeassistant/components/pure_energie/sensor.py @@ -15,12 +15,15 @@ from homeassistant.components.sensor import ( from homeassistant.const import CONF_HOST, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import PureEnergieConfigEntry from .const import DOMAIN -from .coordinator import PureEnergieData, PureEnergieDataUpdateCoordinator +from .coordinator import ( + PureEnergieConfigEntry, + PureEnergieData, + PureEnergieDataUpdateCoordinator, +) @dataclass(frozen=True, kw_only=True) @@ -61,7 +64,7 @@ SENSORS: tuple[PureEnergieSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PureEnergieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Pure Energie Sensors based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/purpleair/coordinator.py b/homeassistant/components/purpleair/coordinator.py index 7bf0770c6fc..f1511733cfa 100644 --- a/homeassistant/components/purpleair/coordinator.py +++ b/homeassistant/components/purpleair/coordinator.py @@ -49,16 +49,21 @@ UPDATE_INTERVAL = timedelta(minutes=2) class PurpleAirDataUpdateCoordinator(DataUpdateCoordinator[GetSensorsResponse]): """Define a PurpleAir-specific coordinator.""" + config_entry: ConfigEntry + def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize.""" - self._entry = entry self._api = API( entry.data[CONF_API_KEY], session=aiohttp_client.async_get_clientsession(hass), ) super().__init__( - hass, LOGGER, name=entry.title, update_interval=UPDATE_INTERVAL + hass, + LOGGER, + config_entry=entry, + name=entry.title, + update_interval=UPDATE_INTERVAL, ) async def _async_update_data(self) -> GetSensorsResponse: @@ -66,7 +71,7 @@ class PurpleAirDataUpdateCoordinator(DataUpdateCoordinator[GetSensorsResponse]): try: return await self._api.sensors.async_get_sensors( SENSOR_FIELDS_TO_RETRIEVE, - sensor_indices=self._entry.options[CONF_SENSOR_INDICES], + sensor_indices=self.config_entry.options[CONF_SENSOR_INDICES], ) except InvalidApiKeyError as err: raise ConfigEntryAuthFailed("Invalid API key") from err diff --git a/homeassistant/components/purpleair/sensor.py b/homeassistant/components/purpleair/sensor.py index 9fb0249a360..bed1d878557 100644 --- a/homeassistant/components/purpleair/sensor.py +++ b/homeassistant/components/purpleair/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_SENSOR_INDICES, DOMAIN from .coordinator import PurpleAirDataUpdateCoordinator @@ -166,7 +166,7 @@ SENSOR_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up PurpleAir sensors based on a config entry.""" coordinator: PurpleAirDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/pushbullet/sensor.py b/homeassistant/components/pushbullet/sensor.py index 4989fc91d5e..2dbaa8fc713 100644 --- a/homeassistant/components/pushbullet/sensor.py +++ b/homeassistant/components/pushbullet/sensor.py @@ -8,7 +8,7 @@ from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .api import PushBulletNotificationProvider from .const import DATA_UPDATED, DOMAIN @@ -68,7 +68,9 @@ SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Pushbullet sensors from config entry.""" diff --git a/homeassistant/components/pvoutput/coordinator.py b/homeassistant/components/pvoutput/coordinator.py index 5c38792c553..ce3642421bf 100644 --- a/homeassistant/components/pvoutput/coordinator.py +++ b/homeassistant/components/pvoutput/coordinator.py @@ -21,14 +21,15 @@ class PVOutputDataUpdateCoordinator(DataUpdateCoordinator[Status]): def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize the PVOutput coordinator.""" - self.config_entry = entry self.pvoutput = PVOutput( api_key=entry.data[CONF_API_KEY], system_id=entry.data[CONF_SYSTEM_ID], session=async_get_clientsession(hass), ) - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, LOGGER, config_entry=entry, name=DOMAIN, update_interval=SCAN_INTERVAL + ) async def _async_update_data(self) -> Status: """Fetch system status from PVOutput.""" diff --git a/homeassistant/components/pvoutput/sensor.py b/homeassistant/components/pvoutput/sensor.py index ef2bb3eb660..b4ed3f93945 100644 --- a/homeassistant/components/pvoutput/sensor.py +++ b/homeassistant/components/pvoutput/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_SYSTEM_ID, DOMAIN @@ -98,7 +98,7 @@ SENSORS: tuple[PVOutputSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a PVOutput sensors based on a config entry.""" coordinator: PVOutputDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/pvpc_hourly_pricing/coordinator.py b/homeassistant/components/pvpc_hourly_pricing/coordinator.py index 171e516abdc..28e676d37ed 100644 --- a/homeassistant/components/pvpc_hourly_pricing/coordinator.py +++ b/homeassistant/components/pvpc_hourly_pricing/coordinator.py @@ -21,6 +21,8 @@ _LOGGER = logging.getLogger(__name__) class ElecPricesDataUpdateCoordinator(DataUpdateCoordinator[EsiosApiData]): """Class to manage fetching Electricity prices data from API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, entry: ConfigEntry, sensor_keys: set[str] ) -> None: @@ -35,14 +37,17 @@ class ElecPricesDataUpdateCoordinator(DataUpdateCoordinator[EsiosApiData]): sensor_keys=tuple(sensor_keys), ) super().__init__( - hass, _LOGGER, name=DOMAIN, update_interval=timedelta(minutes=30) + hass, + _LOGGER, + config_entry=entry, + name=DOMAIN, + update_interval=timedelta(minutes=30), ) - self._entry = entry @property def entry_id(self) -> str: """Return entry ID.""" - return self._entry.entry_id + return self.config_entry.entry_id async def _async_update_data(self) -> EsiosApiData: """Update electricity prices from the ESIOS API.""" diff --git a/homeassistant/components/pvpc_hourly_pricing/sensor.py b/homeassistant/components/pvpc_hourly_pricing/sensor.py index 9d9fe5b9661..1b92cfc533d 100644 --- a/homeassistant/components/pvpc_hourly_pricing/sensor.py +++ b/homeassistant/components/pvpc_hourly_pricing/sensor.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CURRENCY_EURO, UnitOfEnergy from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_change from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -148,7 +148,9 @@ _PRICE_SENSOR_ATTRIBUTES_MAP = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the electricity price sensor from config_entry.""" coordinator: ElecPricesDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/pyload/__init__.py b/homeassistant/components/pyload/__init__.py index f07db509630..3dd2fd9b2ba 100644 --- a/homeassistant/components/pyload/__init__.py +++ b/homeassistant/components/pyload/__init__.py @@ -6,7 +6,6 @@ from aiohttp import CookieJar from pyloadapi.api import PyLoadAPI from pyloadapi.exceptions import CannotConnect, InvalidAuth, ParserError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, @@ -21,12 +20,10 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_create_clientsession from .const import DOMAIN -from .coordinator import PyLoadCoordinator +from .coordinator import PyLoadConfigEntry, PyLoadCoordinator PLATFORMS: list[Platform] = [Platform.BUTTON, Platform.SENSOR, Platform.SWITCH] -type PyLoadConfigEntry = ConfigEntry[PyLoadCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: PyLoadConfigEntry) -> bool: """Set up pyLoad from a config entry.""" @@ -66,7 +63,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PyLoadConfigEntry) -> bo translation_key="setup_authentication_exception", translation_placeholders={CONF_USERNAME: entry.data[CONF_USERNAME]}, ) from e - coordinator = PyLoadCoordinator(hass, pyloadapi) + coordinator = PyLoadCoordinator(hass, entry, pyloadapi) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/pyload/button.py b/homeassistant/components/pyload/button.py index 386fe6968de..9fcba7e723a 100644 --- a/homeassistant/components/pyload/button.py +++ b/homeassistant/components/pyload/button.py @@ -12,10 +12,10 @@ from pyloadapi.api import CannotConnect, InvalidAuth, PyLoadAPI from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PyLoadConfigEntry from .const import DOMAIN +from .coordinator import PyLoadConfigEntry from .entity import BasePyLoadEntity @@ -63,7 +63,7 @@ SENSOR_DESCRIPTIONS: tuple[PyLoadButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PyLoadConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons from a config entry.""" diff --git a/homeassistant/components/pyload/coordinator.py b/homeassistant/components/pyload/coordinator.py index 7eadefcd260..8b2db605c94 100644 --- a/homeassistant/components/pyload/coordinator.py +++ b/homeassistant/components/pyload/coordinator.py @@ -34,16 +34,22 @@ class PyLoadData: free_space: int +type PyLoadConfigEntry = ConfigEntry[PyLoadCoordinator] + + class PyLoadCoordinator(DataUpdateCoordinator[PyLoadData]): """pyLoad coordinator.""" - config_entry: ConfigEntry + config_entry: PyLoadConfigEntry - def __init__(self, hass: HomeAssistant, pyload: PyLoadAPI) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: PyLoadConfigEntry, pyload: PyLoadAPI + ) -> None: """Initialize pyLoad coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/pyload/diagnostics.py b/homeassistant/components/pyload/diagnostics.py index e9688a3369b..105a9a953e2 100644 --- a/homeassistant/components/pyload/diagnostics.py +++ b/homeassistant/components/pyload/diagnostics.py @@ -9,8 +9,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant -from . import PyLoadConfigEntry -from .coordinator import PyLoadData +from .coordinator import PyLoadConfigEntry, PyLoadData TO_REDACT = {CONF_USERNAME, CONF_PASSWORD, CONF_HOST} diff --git a/homeassistant/components/pyload/sensor.py b/homeassistant/components/pyload/sensor.py index 38f681d30d5..edf7c6a756c 100644 --- a/homeassistant/components/pyload/sensor.py +++ b/homeassistant/components/pyload/sensor.py @@ -14,12 +14,11 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfDataRate, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import PyLoadConfigEntry from .const import UNIT_DOWNLOADS -from .coordinator import PyLoadData +from .coordinator import PyLoadConfigEntry, PyLoadData from .entity import BasePyLoadEntity @@ -86,7 +85,7 @@ SENSOR_DESCRIPTIONS: tuple[PyLoadSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PyLoadConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the pyLoad sensors.""" diff --git a/homeassistant/components/pyload/switch.py b/homeassistant/components/pyload/switch.py index ea189ed9a8f..d4416666d93 100644 --- a/homeassistant/components/pyload/switch.py +++ b/homeassistant/components/pyload/switch.py @@ -16,11 +16,10 @@ from homeassistant.components.switch import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import PyLoadConfigEntry from .const import DOMAIN -from .coordinator import PyLoadData +from .coordinator import PyLoadConfigEntry, PyLoadData from .entity import BasePyLoadEntity @@ -66,7 +65,7 @@ SENSOR_DESCRIPTIONS: tuple[PyLoadSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: PyLoadConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the pyLoad sensors.""" diff --git a/homeassistant/components/qbittorrent/__init__.py b/homeassistant/components/qbittorrent/__init__.py index d95136965f8..513b49d3561 100644 --- a/homeassistant/components/qbittorrent/__init__.py +++ b/homeassistant/components/qbittorrent/__init__.py @@ -124,7 +124,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b except APIConnectionError as exc: raise ConfigEntryNotReady("Fail to connect to qBittorrent") from exc - coordinator = QBittorrentDataCoordinator(hass, client) + coordinator = QBittorrentDataCoordinator(hass, config_entry, client) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = coordinator diff --git a/homeassistant/components/qbittorrent/coordinator.py b/homeassistant/components/qbittorrent/coordinator.py index c590bb9d81a..8fd23fb3b5b 100644 --- a/homeassistant/components/qbittorrent/coordinator.py +++ b/homeassistant/components/qbittorrent/coordinator.py @@ -15,6 +15,7 @@ from qbittorrentapi import ( ) from qbittorrentapi.torrents import TorrentStatusesT +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -27,7 +28,11 @@ _LOGGER = logging.getLogger(__name__) class QBittorrentDataCoordinator(DataUpdateCoordinator[SyncMainDataDictionary]): """Coordinator for updating QBittorrent data.""" - def __init__(self, hass: HomeAssistant, client: Client) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, client: Client + ) -> None: """Initialize coordinator.""" self.client = client self._is_alternative_mode_enabled = False @@ -42,6 +47,7 @@ class QBittorrentDataCoordinator(DataUpdateCoordinator[SyncMainDataDictionary]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/qbittorrent/sensor.py b/homeassistant/components/qbittorrent/sensor.py index 67eb856bb83..9f4610cff64 100644 --- a/homeassistant/components/qbittorrent/sensor.py +++ b/homeassistant/components/qbittorrent/sensor.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_IDLE, UnitOfDataRate from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -129,7 +129,7 @@ SENSOR_TYPES: tuple[QBittorrentSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up qBittorrent sensor entries.""" diff --git a/homeassistant/components/qbittorrent/switch.py b/homeassistant/components/qbittorrent/switch.py index f12118e5233..dd61f130ca1 100644 --- a/homeassistant/components/qbittorrent/switch.py +++ b/homeassistant/components/qbittorrent/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -43,7 +43,7 @@ SWITCH_TYPES: tuple[QBittorrentSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up qBittorrent switch entries.""" diff --git a/homeassistant/components/qbus/switch.py b/homeassistant/components/qbus/switch.py index 2413b8f152f..8a932e1e414 100644 --- a/homeassistant/components/qbus/switch.py +++ b/homeassistant/components/qbus/switch.py @@ -8,7 +8,7 @@ from qbusmqttapi.state import QbusMqttOnOffState, StateType from homeassistant.components.mqtt import ReceiveMessage from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import QbusConfigEntry from .entity import QbusEntity @@ -17,7 +17,9 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( - hass: HomeAssistant, entry: QbusConfigEntry, add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: QbusConfigEntry, + add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch entities.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/qingping/binary_sensor.py b/homeassistant/components/qingping/binary_sensor.py index 5f1367fbce8..3431204595a 100644 --- a/homeassistant/components/qingping/binary_sensor.py +++ b/homeassistant/components/qingping/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothProcessorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import QingpingConfigEntry @@ -74,7 +74,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: QingpingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Qingping BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/qingping/sensor.py b/homeassistant/components/qingping/sensor.py index 3d5f30c61fc..ee2a63b169a 100644 --- a/homeassistant/components/qingping/sensor.py +++ b/homeassistant/components/qingping/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import QingpingConfigEntry @@ -142,7 +142,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: QingpingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Qingping BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/qnap/coordinator.py b/homeassistant/components/qnap/coordinator.py index 8c2bf81a47f..297f6569d2b 100644 --- a/homeassistant/components/qnap/coordinator.py +++ b/homeassistant/components/qnap/coordinator.py @@ -33,7 +33,13 @@ class QnapCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]): def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize the qnap coordinator.""" - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=UPDATE_INTERVAL, + ) protocol = "https" if config_entry.data[CONF_SSL] else "http" self._api = QNAPStats( diff --git a/homeassistant/components/qnap/sensor.py b/homeassistant/components/qnap/sensor.py index 383a4e5f572..381455cb7e1 100644 --- a/homeassistant/components/qnap/sensor.py +++ b/homeassistant/components/qnap/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -248,7 +248,7 @@ SENSOR_KEYS: list[str] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" coordinator = QnapCoordinator(hass, config_entry) diff --git a/homeassistant/components/qnap_qsw/__init__.py b/homeassistant/components/qnap_qsw/__init__.py index d7352435b07..f9faca025a5 100644 --- a/homeassistant/components/qnap_qsw/__init__.py +++ b/homeassistant/components/qnap_qsw/__init__.py @@ -35,10 +35,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: qsw = QnapQswApi(aiohttp_client.async_get_clientsession(hass), options) - coord_data = QswDataCoordinator(hass, qsw) + coord_data = QswDataCoordinator(hass, entry, qsw) await coord_data.async_config_entry_first_refresh() - coord_fw = QswFirmwareCoordinator(hass, qsw) + coord_fw = QswFirmwareCoordinator(hass, entry, qsw) try: await coord_fw.async_config_entry_first_refresh() except ConfigEntryNotReady as error: diff --git a/homeassistant/components/qnap_qsw/binary_sensor.py b/homeassistant/components/qnap_qsw/binary_sensor.py index a9c025b86ce..c1f77d068df 100644 --- a/homeassistant/components/qnap_qsw/binary_sensor.py +++ b/homeassistant/components/qnap_qsw/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED from .const import ATTR_MESSAGE, DOMAIN, QSW_COORD_DATA @@ -78,7 +78,9 @@ PORT_BINARY_SENSOR_TYPES: Final[tuple[QswBinarySensorEntityDescription, ...]] = async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add QNAP QSW binary sensors from a config_entry.""" coordinator: QswDataCoordinator = hass.data[DOMAIN][entry.entry_id][QSW_COORD_DATA] diff --git a/homeassistant/components/qnap_qsw/button.py b/homeassistant/components/qnap_qsw/button.py index 091c6786a92..02cf96766f2 100644 --- a/homeassistant/components/qnap_qsw/button.py +++ b/homeassistant/components/qnap_qsw/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, QSW_COORD_DATA, QSW_REBOOT from .coordinator import QswDataCoordinator @@ -41,7 +41,9 @@ BUTTON_TYPES: Final[tuple[QswButtonDescription, ...]] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add QNAP QSW buttons from a config_entry.""" coordinator: QswDataCoordinator = hass.data[DOMAIN][entry.entry_id][QSW_COORD_DATA] diff --git a/homeassistant/components/qnap_qsw/coordinator.py b/homeassistant/components/qnap_qsw/coordinator.py index c873f2a773d..b72bed7105c 100644 --- a/homeassistant/components/qnap_qsw/coordinator.py +++ b/homeassistant/components/qnap_qsw/coordinator.py @@ -10,6 +10,7 @@ from typing import Any from aioqsw.exceptions import QswError from aioqsw.localapi import QnapQswApi +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -24,13 +25,18 @@ _LOGGER = logging.getLogger(__name__) class QswDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching data from the QNAP QSW device.""" - def __init__(self, hass: HomeAssistant, qsw: QnapQswApi) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, qsw: QnapQswApi + ) -> None: """Initialize.""" self.qsw = qsw super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=DATA_SCAN_INTERVAL, ) @@ -48,13 +54,18 @@ class QswDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): class QswFirmwareCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching firmware data from the QNAP QSW device.""" - def __init__(self, hass: HomeAssistant, qsw: QnapQswApi) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, qsw: QnapQswApi + ) -> None: """Initialize.""" self.qsw = qsw super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=FW_SCAN_INTERVAL, ) diff --git a/homeassistant/components/qnap_qsw/sensor.py b/homeassistant/components/qnap_qsw/sensor.py index e7f2c18638f..af02c121656 100644 --- a/homeassistant/components/qnap_qsw/sensor.py +++ b/homeassistant/components/qnap_qsw/sensor.py @@ -44,7 +44,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED, StateType from homeassistant.util import dt as dt_util @@ -286,7 +286,9 @@ PORT_SENSOR_TYPES: Final[tuple[QswSensorEntityDescription, ...]] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add QNAP QSW sensors from a config_entry.""" coordinator: QswDataCoordinator = hass.data[DOMAIN][entry.entry_id][QSW_COORD_DATA] diff --git a/homeassistant/components/qnap_qsw/update.py b/homeassistant/components/qnap_qsw/update.py index ac789235271..c5cef729849 100644 --- a/homeassistant/components/qnap_qsw/update.py +++ b/homeassistant/components/qnap_qsw/update.py @@ -20,7 +20,7 @@ from homeassistant.components.update import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, QSW_COORD_FW, QSW_UPDATE from .coordinator import QswFirmwareCoordinator @@ -36,7 +36,9 @@ UPDATE_TYPES: Final[tuple[UpdateEntityDescription, ...]] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add QNAP QSW updates from a config_entry.""" coordinator: QswFirmwareCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/rabbitair/__init__.py b/homeassistant/components/rabbitair/__init__.py index e4eb67a67f5..d6530b322b0 100644 --- a/homeassistant/components/rabbitair/__init__.py +++ b/homeassistant/components/rabbitair/__init__.py @@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: zeroconf_instance = await zeroconf.async_get_async_instance(hass) device: Client = UdpClient(host, token, zeroconf=zeroconf_instance) - coordinator = RabbitAirDataUpdateCoordinator(hass, device) + coordinator = RabbitAirDataUpdateCoordinator(hass, entry, device) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/rabbitair/coordinator.py b/homeassistant/components/rabbitair/coordinator.py index 3c7db126c7d..75453fe4d24 100644 --- a/homeassistant/components/rabbitair/coordinator.py +++ b/homeassistant/components/rabbitair/coordinator.py @@ -7,6 +7,7 @@ from typing import Any, cast from rabbitair import Client, State +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -42,12 +43,17 @@ class RabbitAirDebouncer(Debouncer[Coroutine[Any, Any, None]]): class RabbitAirDataUpdateCoordinator(DataUpdateCoordinator[State]): """Class to manage fetching data from single endpoint.""" - def __init__(self, hass: HomeAssistant, device: Client) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, device: Client + ) -> None: """Initialize global data updater.""" self.device = device super().__init__( hass, _LOGGER, + config_entry=config_entry, name="rabbitair", update_interval=timedelta(seconds=10), request_refresh_debouncer=RabbitAirDebouncer(hass), diff --git a/homeassistant/components/rabbitair/fan.py b/homeassistant/components/rabbitair/fan.py index cfbee0be67c..4c13f3a8b02 100644 --- a/homeassistant/components/rabbitair/fan.py +++ b/homeassistant/components/rabbitair/fan.py @@ -9,7 +9,7 @@ from rabbitair import Mode, Model, Speed from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -39,7 +39,9 @@ PRESET_MODES = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator: RabbitAirDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/rachio/binary_sensor.py b/homeassistant/components/rachio/binary_sensor.py index 189a08e998d..3bf0f716c6d 100644 --- a/homeassistant/components/rachio/binary_sensor.py +++ b/homeassistant/components/rachio/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN as DOMAIN_RACHIO, @@ -46,7 +46,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Rachio binary sensors.""" entities = await hass.async_add_executor_job(_create_entities, hass, config_entry) diff --git a/homeassistant/components/rachio/calendar.py b/homeassistant/components/rachio/calendar.py index 5c7e13c748a..91ad29fac9f 100644 --- a/homeassistant/components/rachio/calendar.py +++ b/homeassistant/components/rachio/calendar.py @@ -12,7 +12,7 @@ from homeassistant.components.calendar import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -41,7 +41,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for Rachio smart hose timer calendar.""" person: RachioPerson = hass.data[DOMAIN_RACHIO][config_entry.entry_id] diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 92e7c0ea2ba..25cdeac62f7 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -16,7 +16,7 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.util.dt import as_timestamp, now, parse_datetime, utc_from_timestamp @@ -102,7 +102,7 @@ START_MULTIPLE_ZONES_SCHEMA = vol.Schema( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Rachio switches.""" zone_entities = [] diff --git a/homeassistant/components/radarr/__init__.py b/homeassistant/components/radarr/__init__.py index 5c225697f98..11a9b6b4dc0 100644 --- a/homeassistant/components/radarr/__init__.py +++ b/homeassistant/components/radarr/__init__.py @@ -2,12 +2,11 @@ from __future__ import annotations -from dataclasses import dataclass, fields +from dataclasses import fields from aiopyarr.models.host_configuration import PyArrHostConfiguration from aiopyarr.radarr_client import RadarrClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_URL, CONF_VERIFY_SSL, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -18,24 +17,13 @@ from .coordinator import ( HealthDataUpdateCoordinator, MoviesDataUpdateCoordinator, QueueDataUpdateCoordinator, + RadarrConfigEntry, + RadarrData, RadarrDataUpdateCoordinator, StatusDataUpdateCoordinator, ) PLATFORMS = [Platform.BINARY_SENSOR, Platform.CALENDAR, Platform.SENSOR] -type RadarrConfigEntry = ConfigEntry[RadarrData] - - -@dataclass(kw_only=True, slots=True) -class RadarrData: - """Radarr data type.""" - - calendar: CalendarUpdateCoordinator - disk_space: DiskSpaceDataUpdateCoordinator - health: HealthDataUpdateCoordinator - movie: MoviesDataUpdateCoordinator - queue: QueueDataUpdateCoordinator - status: StatusDataUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: RadarrConfigEntry) -> bool: @@ -50,12 +38,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: RadarrConfigEntry) -> bo session=async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL]), ) data = RadarrData( - calendar=CalendarUpdateCoordinator(hass, host_configuration, radarr), - disk_space=DiskSpaceDataUpdateCoordinator(hass, host_configuration, radarr), - health=HealthDataUpdateCoordinator(hass, host_configuration, radarr), - movie=MoviesDataUpdateCoordinator(hass, host_configuration, radarr), - queue=QueueDataUpdateCoordinator(hass, host_configuration, radarr), - status=StatusDataUpdateCoordinator(hass, host_configuration, radarr), + calendar=CalendarUpdateCoordinator(hass, entry, host_configuration, radarr), + disk_space=DiskSpaceDataUpdateCoordinator( + hass, entry, host_configuration, radarr + ), + health=HealthDataUpdateCoordinator(hass, entry, host_configuration, radarr), + movie=MoviesDataUpdateCoordinator(hass, entry, host_configuration, radarr), + queue=QueueDataUpdateCoordinator(hass, entry, host_configuration, radarr), + status=StatusDataUpdateCoordinator(hass, entry, host_configuration, radarr), ) for field in fields(data): coordinator: RadarrDataUpdateCoordinator = getattr(data, field.name) diff --git a/homeassistant/components/radarr/binary_sensor.py b/homeassistant/components/radarr/binary_sensor.py index 953c7dead18..f09e6015b53 100644 --- a/homeassistant/components/radarr/binary_sensor.py +++ b/homeassistant/components/radarr/binary_sensor.py @@ -11,10 +11,10 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RadarrConfigEntry from .const import HEALTH_ISSUES +from .coordinator import RadarrConfigEntry from .entity import RadarrEntity BINARY_SENSOR_TYPE = BinarySensorEntityDescription( @@ -28,7 +28,7 @@ BINARY_SENSOR_TYPE = BinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: RadarrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Radarr sensors based on a config entry.""" coordinator = entry.runtime_data.health diff --git a/homeassistant/components/radarr/calendar.py b/homeassistant/components/radarr/calendar.py index c741c178862..00df27f21bd 100644 --- a/homeassistant/components/radarr/calendar.py +++ b/homeassistant/components/radarr/calendar.py @@ -7,10 +7,9 @@ from datetime import datetime from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RadarrConfigEntry -from .coordinator import CalendarUpdateCoordinator, RadarrEvent +from .coordinator import CalendarUpdateCoordinator, RadarrConfigEntry, RadarrEvent from .entity import RadarrEntity CALENDAR_TYPE = EntityDescription( @@ -22,7 +21,7 @@ CALENDAR_TYPE = EntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: RadarrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Radarr calendar entity.""" coordinator = entry.runtime_data.calendar diff --git a/homeassistant/components/radarr/coordinator.py b/homeassistant/components/radarr/coordinator.py index 6e8a3d55d3e..d343675d7ea 100644 --- a/homeassistant/components/radarr/coordinator.py +++ b/homeassistant/components/radarr/coordinator.py @@ -6,7 +6,7 @@ from abc import ABC, abstractmethod import asyncio from dataclasses import dataclass from datetime import date, datetime, timedelta -from typing import TYPE_CHECKING, Generic, TypeVar, cast +from typing import Generic, TypeVar, cast from aiopyarr import ( Health, @@ -20,14 +20,27 @@ from aiopyarr.models.host_configuration import PyArrHostConfiguration from aiopyarr.radarr_client import RadarrClient from homeassistant.components.calendar import CalendarEvent +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DEFAULT_MAX_RECORDS, DOMAIN, LOGGER -if TYPE_CHECKING: - from . import RadarrConfigEntry + +@dataclass(kw_only=True, slots=True) +class RadarrData: + """Radarr data type.""" + + calendar: CalendarUpdateCoordinator + disk_space: DiskSpaceDataUpdateCoordinator + health: HealthDataUpdateCoordinator + movie: MoviesDataUpdateCoordinator + queue: QueueDataUpdateCoordinator + status: StatusDataUpdateCoordinator + + +type RadarrConfigEntry = ConfigEntry[RadarrData] T = TypeVar("T", bound=SystemStatus | list[RootFolder] | list[Health] | int | None) @@ -53,6 +66,7 @@ class RadarrDataUpdateCoordinator(DataUpdateCoordinator[T], Generic[T], ABC): def __init__( self, hass: HomeAssistant, + config_entry: RadarrConfigEntry, host_configuration: PyArrHostConfiguration, api_client: RadarrClient, ) -> None: @@ -60,6 +74,7 @@ class RadarrDataUpdateCoordinator(DataUpdateCoordinator[T], Generic[T], ABC): super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=self._update_interval, ) @@ -140,11 +155,12 @@ class CalendarUpdateCoordinator(RadarrDataUpdateCoordinator[None]): def __init__( self, hass: HomeAssistant, + config_entry: RadarrConfigEntry, host_configuration: PyArrHostConfiguration, api_client: RadarrClient, ) -> None: """Initialize.""" - super().__init__(hass, host_configuration, api_client) + super().__init__(hass, config_entry, host_configuration, api_client) self.event: RadarrEvent | None = None self._events: list[RadarrEvent] = [] diff --git a/homeassistant/components/radarr/sensor.py b/homeassistant/components/radarr/sensor.py index df1a0686e00..fa0cb95d549 100644 --- a/homeassistant/components/radarr/sensor.py +++ b/homeassistant/components/radarr/sensor.py @@ -17,10 +17,9 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RadarrConfigEntry -from .coordinator import RadarrDataUpdateCoordinator, T +from .coordinator import RadarrConfigEntry, RadarrDataUpdateCoordinator, T from .entity import RadarrEntity @@ -117,7 +116,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: RadarrConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Radarr sensors based on a config entry.""" entities: list[RadarrSensor[Any]] = [] diff --git a/homeassistant/components/radiotherm/__init__.py b/homeassistant/components/radiotherm/__init__.py index 7b2eaba52c4..80dbcf44bc9 100644 --- a/homeassistant/components/radiotherm/__init__.py +++ b/homeassistant/components/radiotherm/__init__.py @@ -43,7 +43,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: host = entry.data[CONF_HOST] init_coro = async_get_init_data(hass, host) init_data = await _async_call_or_raise_not_ready(init_coro, host) - coordinator = RadioThermUpdateCoordinator(hass, init_data) + coordinator = RadioThermUpdateCoordinator(hass, entry, init_data) await coordinator.async_config_entry_first_refresh() # Only set the time if the thermostat is diff --git a/homeassistant/components/radiotherm/climate.py b/homeassistant/components/radiotherm/climate.py index af52c5fcea3..09ac5b42b60 100644 --- a/homeassistant/components/radiotherm/climate.py +++ b/homeassistant/components/radiotherm/climate.py @@ -20,7 +20,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .coordinator import RadioThermUpdateCoordinator @@ -93,7 +93,7 @@ def round_temp(temperature): async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate for a radiotherm device.""" coordinator: RadioThermUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/radiotherm/coordinator.py b/homeassistant/components/radiotherm/coordinator.py index 06e3554c8d7..7d483426c83 100644 --- a/homeassistant/components/radiotherm/coordinator.py +++ b/homeassistant/components/radiotherm/coordinator.py @@ -8,6 +8,7 @@ from urllib.error import URLError from radiotherm.validate import RadiothermTstatError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -21,13 +22,21 @@ UPDATE_INTERVAL = timedelta(seconds=15) class RadioThermUpdateCoordinator(DataUpdateCoordinator[RadioThermUpdate]): """DataUpdateCoordinator to gather data for radio thermostats.""" - def __init__(self, hass: HomeAssistant, init_data: RadioThermInitData) -> None: + config_entry: ConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + init_data: RadioThermInitData, + ) -> None: """Initialize DataUpdateCoordinator.""" self.init_data = init_data self._description = f"{init_data.name} ({init_data.host})" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"radiotherm {self.init_data.name}", update_interval=UPDATE_INTERVAL, ) diff --git a/homeassistant/components/radiotherm/switch.py b/homeassistant/components/radiotherm/switch.py index e7b463e3def..2952e1e5817 100644 --- a/homeassistant/components/radiotherm/switch.py +++ b/homeassistant/components/radiotherm/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RadioThermUpdateCoordinator @@ -19,7 +19,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for a radiotherm device.""" coordinator: RadioThermUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index d8b71e2df0b..f9cd751a81e 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -101,18 +101,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: RainbirdConfigEntry) -> data = RainbirdData( controller, model_info, - coordinator=RainbirdUpdateCoordinator( - hass, - name=entry.title, - controller=controller, - unique_id=entry.unique_id, - model_info=model_info, - ), - schedule_coordinator=RainbirdScheduleUpdateCoordinator( - hass, - name=f"{entry.title} Schedule", - controller=controller, - ), + coordinator=RainbirdUpdateCoordinator(hass, entry, controller, model_info), + schedule_coordinator=RainbirdScheduleUpdateCoordinator(hass, entry, controller), ) await data.coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 5722b8852dd..0b27c7e33c4 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import RainbirdUpdateCoordinator @@ -27,7 +27,7 @@ RAIN_SENSOR_ENTITY_DESCRIPTION = BinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RainbirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Rain Bird binary_sensor.""" coordinator = config_entry.runtime_data.coordinator diff --git a/homeassistant/components/rainbird/calendar.py b/homeassistant/components/rainbird/calendar.py index 160fe70c61e..c48ca438146 100644 --- a/homeassistant/components/rainbird/calendar.py +++ b/homeassistant/components/rainbird/calendar.py @@ -9,7 +9,7 @@ from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -22,7 +22,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: RainbirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Rain Bird irrigation calendar.""" data = config_entry.runtime_data diff --git a/homeassistant/components/rainbird/coordinator.py b/homeassistant/components/rainbird/coordinator.py index 2ccfa0af62a..426df625697 100644 --- a/homeassistant/components/rainbird/coordinator.py +++ b/homeassistant/components/rainbird/coordinator.py @@ -58,26 +58,28 @@ def async_create_clientsession() -> aiohttp.ClientSession: class RainbirdUpdateCoordinator(DataUpdateCoordinator[RainbirdDeviceState]): """Coordinator for rainbird API calls.""" + config_entry: RainbirdConfigEntry + def __init__( self, hass: HomeAssistant, - name: str, + config_entry: RainbirdConfigEntry, controller: AsyncRainbirdController, - unique_id: str | None, model_info: ModelAndVersion, ) -> None: """Initialize RainbirdUpdateCoordinator.""" super().__init__( hass, _LOGGER, - name=name, + config_entry=config_entry, + name=config_entry.title, update_interval=UPDATE_INTERVAL, request_refresh_debouncer=Debouncer( hass, _LOGGER, cooldown=DEBOUNCER_COOLDOWN, immediate=False ), ) self._controller = controller - self._unique_id = unique_id + self._unique_id = config_entry.unique_id self._zones: set[int] | None = None self._model_info = model_info @@ -145,14 +147,15 @@ class RainbirdScheduleUpdateCoordinator(DataUpdateCoordinator[Schedule]): def __init__( self, hass: HomeAssistant, - name: str, + config_entry: RainbirdConfigEntry, controller: AsyncRainbirdController, ) -> None: """Initialize ZoneStateUpdateCoordinator.""" super().__init__( hass, _LOGGER, - name=name, + config_entry=config_entry, + name=f"{config_entry.title} Schedule", update_method=self._async_update_data, update_interval=CALENDAR_UPDATE_INTERVAL, ) diff --git a/homeassistant/components/rainbird/number.py b/homeassistant/components/rainbird/number.py index d8081a796b9..7f1dfe74752 100644 --- a/homeassistant/components/rainbird/number.py +++ b/homeassistant/components/rainbird/number.py @@ -10,7 +10,7 @@ from homeassistant.components.number import NumberEntity from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import RainbirdUpdateCoordinator @@ -22,7 +22,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: RainbirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Rain Bird number platform.""" async_add_entities( diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 4725a33bc9a..9fab1af0a23 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -6,7 +6,7 @@ import logging from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -25,7 +25,7 @@ RAIN_DELAY_ENTITY_DESCRIPTION = SensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RainbirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Rain Bird sensor.""" async_add_entities( diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index f622a1b9b2c..f188350138e 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -32,7 +32,7 @@ SERVICE_SCHEMA_IRRIGATION: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: RainbirdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Rain Bird irrigation switches.""" coordinator = config_entry.runtime_data.coordinator diff --git a/homeassistant/components/rainforest_eagle/coordinator.py b/homeassistant/components/rainforest_eagle/coordinator.py index 9c714a291ee..11956681638 100644 --- a/homeassistant/components/rainforest_eagle/coordinator.py +++ b/homeassistant/components/rainforest_eagle/coordinator.py @@ -29,13 +29,13 @@ _LOGGER = logging.getLogger(__name__) class EagleDataCoordinator(DataUpdateCoordinator): """Get the latest data from the Eagle device.""" + config_entry: ConfigEntry eagle100_reader: Eagle100Reader | None = None eagle200_meter: aioeagle.ElectricMeter | None = None - def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize the data object.""" - self.entry = entry - if self.type == TYPE_EAGLE_100: + if config_entry.data[CONF_TYPE] == TYPE_EAGLE_100: self.model = "EAGLE-100" update_method = self._async_update_data_100 else: @@ -45,7 +45,8 @@ class EagleDataCoordinator(DataUpdateCoordinator): super().__init__( hass, _LOGGER, - name=entry.data[CONF_CLOUD_ID], + config_entry=config_entry, + name=config_entry.data[CONF_CLOUD_ID], update_interval=timedelta(seconds=30), update_method=update_method, ) @@ -53,17 +54,12 @@ class EagleDataCoordinator(DataUpdateCoordinator): @property def cloud_id(self): """Return the cloud ID.""" - return self.entry.data[CONF_CLOUD_ID] - - @property - def type(self): - """Return entry type.""" - return self.entry.data[CONF_TYPE] + return self.config_entry.data[CONF_CLOUD_ID] @property def hardware_address(self): """Return hardware address of meter.""" - return self.entry.data[CONF_HARDWARE_ADDRESS] + return self.config_entry.data[CONF_HARDWARE_ADDRESS] @property def is_connected(self): @@ -79,8 +75,8 @@ class EagleDataCoordinator(DataUpdateCoordinator): hub = aioeagle.EagleHub( aiohttp_client.async_get_clientsession(self.hass), self.cloud_id, - self.entry.data[CONF_INSTALL_CODE], - host=self.entry.data[CONF_HOST], + self.config_entry.data[CONF_INSTALL_CODE], + host=self.config_entry.data[CONF_HOST], ) eagle200_meter = aioeagle.ElectricMeter.create_instance( hub, self.hardware_address @@ -115,8 +111,8 @@ class EagleDataCoordinator(DataUpdateCoordinator): if self.eagle100_reader is None: self.eagle100_reader = Eagle100Reader( self.cloud_id, - self.entry.data[CONF_INSTALL_CODE], - self.entry.data[CONF_HOST], + self.config_entry.data[CONF_INSTALL_CODE], + self.config_entry.data[CONF_HOST], ) out = {} diff --git a/homeassistant/components/rainforest_eagle/sensor.py b/homeassistant/components/rainforest_eagle/sensor.py index 8c4c5927998..58427b0e5ba 100644 --- a/homeassistant/components/rainforest_eagle/sensor.py +++ b/homeassistant/components/rainforest_eagle/sensor.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -45,7 +45,9 @@ SENSORS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/rainforest_raven/sensor.py b/homeassistant/components/rainforest_raven/sensor.py index 1025e92ef86..3d358322b70 100644 --- a/homeassistant/components/rainforest_raven/sensor.py +++ b/homeassistant/components/rainforest_raven/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -80,7 +80,7 @@ DIAGNOSTICS = ( async def async_setup_entry( hass: HomeAssistant, entry: RAVEnConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/rainmachine/binary_sensor.py b/homeassistant/components/rainmachine/binary_sensor.py index 4ba9b58d596..610505e2b7f 100644 --- a/homeassistant/components/rainmachine/binary_sensor.py +++ b/homeassistant/components/rainmachine/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RainMachineConfigEntry from .const import DATA_PROVISION_SETTINGS, DATA_RESTRICTIONS_CURRENT @@ -94,7 +94,7 @@ BINARY_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RainMachine binary sensors based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/rainmachine/button.py b/homeassistant/components/rainmachine/button.py index 2f68c6a8a9c..e4ed00930dd 100644 --- a/homeassistant/components/rainmachine/button.py +++ b/homeassistant/components/rainmachine/button.py @@ -17,7 +17,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_send -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RainMachineConfigEntry from .const import DATA_PROVISION_SETTINGS @@ -53,7 +53,7 @@ BUTTON_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RainMachine buttons based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/rainmachine/coordinator.py b/homeassistant/components/rainmachine/coordinator.py index df7972ef31d..de43e5a073f 100644 --- a/homeassistant/components/rainmachine/coordinator.py +++ b/homeassistant/components/rainmachine/coordinator.py @@ -41,6 +41,7 @@ class RainMachineDataUpdateCoordinator(DataUpdateCoordinator[dict]): super().__init__( hass, LOGGER, + config_entry=entry, name=name, update_interval=update_interval, update_method=update_method, @@ -49,7 +50,6 @@ class RainMachineDataUpdateCoordinator(DataUpdateCoordinator[dict]): self._rebooting = False self._signal_handler_unsubs: list[Callable[[], None]] = [] - self.config_entry = entry self.signal_reboot_completed = SIGNAL_REBOOT_COMPLETED.format( self.config_entry.entry_id ) diff --git a/homeassistant/components/rainmachine/select.py b/homeassistant/components/rainmachine/select.py index 1d9225a5bb2..5b23a5d79ef 100644 --- a/homeassistant/components/rainmachine/select.py +++ b/homeassistant/components/rainmachine/select.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM, UnitSystem from . import RainMachineConfigEntry, RainMachineData @@ -83,7 +83,7 @@ SELECT_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RainMachine selects based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/rainmachine/sensor.py b/homeassistant/components/rainmachine/sensor.py index 64f9ecf3990..4677a6d8bca 100644 --- a/homeassistant/components/rainmachine/sensor.py +++ b/homeassistant/components/rainmachine/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfVolume from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utc_from_timestamp, utcnow from . import RainMachineConfigEntry, RainMachineData @@ -153,7 +153,7 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RainMachine sensors based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/rainmachine/switch.py b/homeassistant/components/rainmachine/switch.py index 2a065f18976..9b62b15d196 100644 --- a/homeassistant/components/rainmachine/switch.py +++ b/homeassistant/components/rainmachine/switch.py @@ -17,7 +17,7 @@ from homeassistant.const import ATTR_ID, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import RainMachineConfigEntry, RainMachineData, async_update_programs_and_zones @@ -174,7 +174,7 @@ RESTRICTIONS_SWITCH_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RainMachine switches based on a config entry.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/rainmachine/update.py b/homeassistant/components/rainmachine/update.py index 39156b05cd4..312937184e4 100644 --- a/homeassistant/components/rainmachine/update.py +++ b/homeassistant/components/rainmachine/update.py @@ -16,7 +16,7 @@ from homeassistant.components.update import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RainMachineConfigEntry from .const import DATA_MACHINE_FIRMWARE_UPDATE_STATUS @@ -60,7 +60,7 @@ UPDATE_DESCRIPTION = RainMachineUpdateEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: RainMachineConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Rainmachine update based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/random/binary_sensor.py b/homeassistant/components/random/binary_sensor.py index fadc966bc3d..1af85b43486 100644 --- a/homeassistant/components/random/binary_sensor.py +++ b/homeassistant/components/random/binary_sensor.py @@ -17,7 +17,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType DEFAULT_NAME = "Random binary sensor" @@ -44,7 +47,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" async_add_entities( diff --git a/homeassistant/components/random/sensor.py b/homeassistant/components/random/sensor.py index 590b391c3a0..6ea296c791e 100644 --- a/homeassistant/components/random/sensor.py +++ b/homeassistant/components/random/sensor.py @@ -22,7 +22,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import DEFAULT_MAX, DEFAULT_MIN @@ -57,7 +60,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" diff --git a/homeassistant/components/rapt_ble/sensor.py b/homeassistant/components/rapt_ble/sensor.py index fd88cbcb54c..01aeedbd344 100644 --- a/homeassistant/components/rapt_ble/sensor.py +++ b/homeassistant/components/rapt_ble/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -99,7 +99,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the RAPT Pill BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/rdw/binary_sensor.py b/homeassistant/components/rdw/binary_sensor.py index 5360ce4a7fe..58e1c2e8237 100644 --- a/homeassistant/components/rdw/binary_sensor.py +++ b/homeassistant/components/rdw/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -49,7 +49,7 @@ BINARY_SENSORS: tuple[RDWBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RDW binary sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/rdw/sensor.py b/homeassistant/components/rdw/sensor.py index 2c9c9addcfb..4133082bcf4 100644 --- a/homeassistant/components/rdw/sensor.py +++ b/homeassistant/components/rdw/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -51,7 +51,7 @@ SENSORS: tuple[RDWSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up RDW sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/recollect_waste/calendar.py b/homeassistant/components/recollect_waste/calendar.py index 3a76451358e..8145a93a2b7 100644 --- a/homeassistant/components/recollect_waste/calendar.py +++ b/homeassistant/components/recollect_waste/calendar.py @@ -9,7 +9,7 @@ from aiorecollect.client import PickupEvent from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN @@ -35,7 +35,9 @@ def async_get_calendar_event_from_pickup_event( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ReCollect Waste sensors based on a config entry.""" coordinator: DataUpdateCoordinator[list[PickupEvent]] = hass.data[DOMAIN][ diff --git a/homeassistant/components/recollect_waste/sensor.py b/homeassistant/components/recollect_waste/sensor.py index 36658fb5008..69b1772b9fa 100644 --- a/homeassistant/components/recollect_waste/sensor.py +++ b/homeassistant/components/recollect_waste/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, LOGGER @@ -39,7 +39,9 @@ SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ReCollect Waste sensors based on a config entry.""" coordinator: DataUpdateCoordinator[list[PickupEvent]] = hass.data[DOMAIN][ diff --git a/homeassistant/components/refoss/__init__.py b/homeassistant/components/refoss/__init__.py index 0f0c852b043..eb2085efda4 100644 --- a/homeassistant/components/refoss/__init__.py +++ b/homeassistant/components/refoss/__init__.py @@ -24,7 +24,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Refoss from a config entry.""" hass.data.setdefault(DOMAIN, {}) discover = await refoss_discovery_server(hass) - refoss_discovery = DiscoveryService(hass, discover) + refoss_discovery = DiscoveryService(hass, entry, discover) hass.data[DOMAIN][DATA_DISCOVERY_SERVICE] = refoss_discovery await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/refoss/bridge.py b/homeassistant/components/refoss/bridge.py index 11e92620fbb..a3ba9ea663d 100644 --- a/homeassistant/components/refoss/bridge.py +++ b/homeassistant/components/refoss/bridge.py @@ -6,6 +6,7 @@ from refoss_ha.device import DeviceInfo from refoss_ha.device_manager import async_build_base_device from refoss_ha.discovery import Discovery, Listener +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_send @@ -16,9 +17,12 @@ from .coordinator import RefossDataUpdateCoordinator class DiscoveryService(Listener): """Discovery event handler for refoss devices.""" - def __init__(self, hass: HomeAssistant, discovery: Discovery) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, discovery: Discovery + ) -> None: """Init discovery service.""" self.hass = hass + self.config_entry = config_entry self.discovery = discovery self.discovery.add_listener(self) @@ -32,7 +36,7 @@ class DiscoveryService(Listener): if device is None: return - coordo = RefossDataUpdateCoordinator(self.hass, device) + coordo = RefossDataUpdateCoordinator(self.hass, self.config_entry, device) self.hass.data[DOMAIN][COORDINATORS].append(coordo) await coordo.async_refresh() diff --git a/homeassistant/components/refoss/coordinator.py b/homeassistant/components/refoss/coordinator.py index 929d1b3962b..381f64614b5 100644 --- a/homeassistant/components/refoss/coordinator.py +++ b/homeassistant/components/refoss/coordinator.py @@ -7,6 +7,7 @@ from datetime import timedelta from refoss_ha.controller.device import BaseDevice from refoss_ha.exceptions import DeviceTimeoutError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -16,11 +17,16 @@ from .const import _LOGGER, DOMAIN, MAX_ERRORS class RefossDataUpdateCoordinator(DataUpdateCoordinator[None]): """Manages polling for state changes from the device.""" - def __init__(self, hass: HomeAssistant, device: BaseDevice) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, device: BaseDevice + ) -> None: """Initialize the data update coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"{DOMAIN}-{device.device_info.dev_name}", update_interval=timedelta(seconds=15), ) diff --git a/homeassistant/components/refoss/sensor.py b/homeassistant/components/refoss/sensor.py index 7065470657f..82637aae538 100644 --- a/homeassistant/components/refoss/sensor.py +++ b/homeassistant/components/refoss/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .bridge import RefossDataUpdateCoordinator @@ -117,7 +117,7 @@ SENSORS: dict[str, tuple[RefossSensorEntityDescription, ...]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Refoss device from a config entry.""" diff --git a/homeassistant/components/refoss/switch.py b/homeassistant/components/refoss/switch.py index aed132ecc3a..1d465f7f319 100644 --- a/homeassistant/components/refoss/switch.py +++ b/homeassistant/components/refoss/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .bridge import RefossDataUpdateCoordinator from .const import _LOGGER, COORDINATORS, DISPATCH_DEVICE_DISCOVERED, DOMAIN @@ -20,7 +20,7 @@ from .entity import RefossEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Refoss device from a config entry.""" diff --git a/homeassistant/components/renault/binary_sensor.py b/homeassistant/components/renault/binary_sensor.py index a8fdf324f1c..0aebd3bd835 100644 --- a/homeassistant/components/renault/binary_sensor.py +++ b/homeassistant/components/renault/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import RenaultConfigEntry @@ -37,7 +37,7 @@ class RenaultBinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RenaultConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renault entities from config entry.""" entities: list[RenaultBinarySensor] = [ diff --git a/homeassistant/components/renault/button.py b/homeassistant/components/renault/button.py index 6a9f5e05a38..82b811821ea 100644 --- a/homeassistant/components/renault/button.py +++ b/homeassistant/components/renault/button.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RenaultConfigEntry from .entity import RenaultEntity @@ -29,7 +29,7 @@ class RenaultButtonEntityDescription(ButtonEntityDescription): async def async_setup_entry( hass: HomeAssistant, config_entry: RenaultConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renault entities from config entry.""" entities: list[RenaultButtonEntity] = [ diff --git a/homeassistant/components/renault/coordinator.py b/homeassistant/components/renault/coordinator.py index 89e62867130..a90331730bc 100644 --- a/homeassistant/components/renault/coordinator.py +++ b/homeassistant/components/renault/coordinator.py @@ -6,7 +6,7 @@ import asyncio from collections.abc import Awaitable, Callable from datetime import timedelta import logging -from typing import TypeVar +from typing import TYPE_CHECKING, TypeVar from renault_api.kamereon.exceptions import ( AccessDeniedException, @@ -18,6 +18,9 @@ from renault_api.kamereon.models import KamereonVehicleDataAttributes from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import RenaultConfigEntry + T = TypeVar("T", bound=KamereonVehicleDataAttributes) # We have potentially 7 coordinators per vehicle @@ -27,11 +30,13 @@ _PARALLEL_SEMAPHORE = asyncio.Semaphore(1) class RenaultDataUpdateCoordinator(DataUpdateCoordinator[T]): """Handle vehicle communication with Renault servers.""" + config_entry: RenaultConfigEntry update_method: Callable[[], Awaitable[T]] def __init__( self, hass: HomeAssistant, + config_entry: RenaultConfigEntry, logger: logging.Logger, *, name: str, @@ -42,6 +47,7 @@ class RenaultDataUpdateCoordinator(DataUpdateCoordinator[T]): super().__init__( hass, logger, + config_entry=config_entry, name=name, update_interval=update_interval, update_method=update_method, diff --git a/homeassistant/components/renault/device_tracker.py b/homeassistant/components/renault/device_tracker.py index 08a2a698802..c55ddeb2190 100644 --- a/homeassistant/components/renault/device_tracker.py +++ b/homeassistant/components/renault/device_tracker.py @@ -11,7 +11,7 @@ from homeassistant.components.device_tracker import ( TrackerEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RenaultConfigEntry from .entity import RenaultDataEntity, RenaultDataEntityDescription @@ -30,7 +30,7 @@ class RenaultTrackerEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RenaultConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renault entities from config entry.""" entities: list[RenaultDeviceTracker] = [ diff --git a/homeassistant/components/renault/renault_hub.py b/homeassistant/components/renault/renault_hub.py index 76b197b2aaf..b37390526cf 100644 --- a/homeassistant/components/renault/renault_hub.py +++ b/homeassistant/components/renault/renault_hub.py @@ -5,13 +5,13 @@ from __future__ import annotations import asyncio from datetime import timedelta import logging +from typing import TYPE_CHECKING from renault_api.gigya.exceptions import InvalidCredentialsException from renault_api.kamereon.models import KamereonVehiclesLink from renault_api.renault_account import RenaultAccount from renault_api.renault_client import RenaultClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_IDENTIFIERS, ATTR_MANUFACTURER, @@ -24,6 +24,9 @@ from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession +if TYPE_CHECKING: + from . import RenaultConfigEntry + from .const import CONF_KAMEREON_ACCOUNT_ID, DEFAULT_SCAN_INTERVAL from .renault_vehicle import RenaultVehicleProxy @@ -52,7 +55,7 @@ class RenaultHub: return True return False - async def async_initialise(self, config_entry: ConfigEntry) -> None: + async def async_initialise(self, config_entry: RenaultConfigEntry) -> None: """Set up proxy.""" account_id: str = config_entry.data[CONF_KAMEREON_ACCOUNT_ID] scan_interval = timedelta(seconds=DEFAULT_SCAN_INTERVAL) @@ -86,7 +89,7 @@ class RenaultHub: vehicle_link: KamereonVehiclesLink, renault_account: RenaultAccount, scan_interval: timedelta, - config_entry: ConfigEntry, + config_entry: RenaultConfigEntry, device_registry: dr.DeviceRegistry, ) -> None: """Set up proxy.""" @@ -95,6 +98,7 @@ class RenaultHub: # Generate vehicle proxy vehicle = RenaultVehicleProxy( hass=self._hass, + config_entry=config_entry, vehicle=await renault_account.get_api_vehicle(vehicle_link.vin), details=vehicle_link.vehicleDetails, scan_interval=scan_interval, diff --git a/homeassistant/components/renault/renault_vehicle.py b/homeassistant/components/renault/renault_vehicle.py index d8266d75319..1cce0e4459f 100644 --- a/homeassistant/components/renault/renault_vehicle.py +++ b/homeassistant/components/renault/renault_vehicle.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from datetime import datetime, timedelta from functools import wraps import logging -from typing import Any, Concatenate, cast +from typing import TYPE_CHECKING, Any, Concatenate, cast from renault_api.exceptions import RenaultException from renault_api.kamereon import models @@ -18,6 +18,9 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo +if TYPE_CHECKING: + from . import RenaultConfigEntry + from .const import DOMAIN from .coordinator import RenaultDataUpdateCoordinator @@ -64,12 +67,14 @@ class RenaultVehicleProxy: def __init__( self, hass: HomeAssistant, + config_entry: RenaultConfigEntry, vehicle: RenaultVehicle, details: models.KamereonVehicleDetails, scan_interval: timedelta, ) -> None: """Initialise vehicle proxy.""" self.hass = hass + self.config_entry = config_entry self._vehicle = vehicle self._details = details self._device_info = DeviceInfo( @@ -98,11 +103,10 @@ class RenaultVehicleProxy: self.coordinators = { coord.key: RenaultDataUpdateCoordinator( self.hass, + self.config_entry, LOGGER, - # Name of the data. For logging purposes. name=f"{self.details.vin} {coord.key}", update_method=coord.update_method(self._vehicle), - # Polling interval. Will only be polled if there are subscribers. update_interval=self._scan_interval, ) for coord in COORDINATORS diff --git a/homeassistant/components/renault/select.py b/homeassistant/components/renault/select.py index cab1d1f4d8a..cddf83bb860 100644 --- a/homeassistant/components/renault/select.py +++ b/homeassistant/components/renault/select.py @@ -9,7 +9,7 @@ from renault_api.kamereon.models import KamereonVehicleBatteryStatusData from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import RenaultConfigEntry @@ -32,7 +32,7 @@ class RenaultSelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RenaultConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renault entities from config entry.""" entities: list[RenaultSelectEntity] = [ diff --git a/homeassistant/components/renault/sensor.py b/homeassistant/components/renault/sensor.py index 7854d70b1c4..7c513c1b9de 100644 --- a/homeassistant/components/renault/sensor.py +++ b/homeassistant/components/renault/sensor.py @@ -31,7 +31,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import as_utc, parse_datetime @@ -60,7 +60,7 @@ class RenaultSensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: RenaultConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renault entities from config entry.""" entities: list[RenaultSensor[Any]] = [ diff --git a/homeassistant/components/renson/__init__.py b/homeassistant/components/renson/__init__.py index d1eebdf0a5f..b88f9bb036a 100644 --- a/homeassistant/components/renson/__init__.py +++ b/homeassistant/components/renson/__init__.py @@ -37,7 +37,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Renson from a config entry.""" api = RensonVentilation(entry.data[CONF_HOST]) - coordinator = RensonCoordinator("Renson", hass, api) + coordinator = RensonCoordinator(hass, entry, api) if not await hass.async_add_executor_job(api.connect): raise ConfigEntryNotReady("Cannot connect to Renson device") diff --git a/homeassistant/components/renson/binary_sensor.py b/homeassistant/components/renson/binary_sensor.py index 46f832ed15c..60b4f54b85c 100644 --- a/homeassistant/components/renson/binary_sensor.py +++ b/homeassistant/components/renson/binary_sensor.py @@ -24,7 +24,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RensonCoordinator @@ -86,7 +86,7 @@ BINARY_SENSORS: tuple[RensonBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Call the Renson integration to setup.""" diff --git a/homeassistant/components/renson/button.py b/homeassistant/components/renson/button.py index 02278a0d6f6..830e5a03a4a 100644 --- a/homeassistant/components/renson/button.py +++ b/homeassistant/components/renson/button.py @@ -15,7 +15,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RensonCoordinator, RensonData from .const import DOMAIN @@ -54,7 +54,7 @@ ENTITY_DESCRIPTIONS: tuple[RensonButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renson button platform.""" diff --git a/homeassistant/components/renson/coordinator.py b/homeassistant/components/renson/coordinator.py index 8613220eee1..5d0a20e1c29 100644 --- a/homeassistant/components/renson/coordinator.py +++ b/homeassistant/components/renson/coordinator.py @@ -9,30 +9,35 @@ from typing import Any from renson_endura_delta.renson import RensonVentilation +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator +from .const import DOMAIN + _LOGGER = logging.getLogger(__name__) class RensonCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Data update coordinator for Renson.""" + config_entry: ConfigEntry + def __init__( self, - name: str, hass: HomeAssistant, + config_entry: ConfigEntry, api: RensonVentilation, - update_interval=timedelta(seconds=30), ) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, # Name of the data. For logging purposes. - name=name, + name=DOMAIN, # Polling interval. Will only be polled if there are subscribers. - update_interval=update_interval, + update_interval=timedelta(seconds=30), ) self.api = api diff --git a/homeassistant/components/renson/fan.py b/homeassistant/components/renson/fan.py index 00edd4547cb..474ab640943 100644 --- a/homeassistant/components/renson/fan.py +++ b/homeassistant/components/renson/fan.py @@ -19,7 +19,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.util.percentage import ( percentage_to_ranged_value, @@ -85,7 +85,7 @@ SPEED_RANGE: tuple[float, float] = (1, 4) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renson fan platform.""" diff --git a/homeassistant/components/renson/number.py b/homeassistant/components/renson/number.py index fb8ab8fc552..67fde1c56dc 100644 --- a/homeassistant/components/renson/number.py +++ b/homeassistant/components/renson/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RensonCoordinator @@ -40,7 +40,7 @@ RENSON_NUMBER_DESCRIPTION = NumberEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renson number platform.""" diff --git a/homeassistant/components/renson/sensor.py b/homeassistant/components/renson/sensor.py index 1df62e12312..ce7e71b1c0b 100644 --- a/homeassistant/components/renson/sensor.py +++ b/homeassistant/components/renson/sensor.py @@ -43,7 +43,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RensonData from .const import DOMAIN @@ -272,7 +272,7 @@ class RensonSensor(RensonEntity, SensorEntity): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renson sensor platform.""" diff --git a/homeassistant/components/renson/switch.py b/homeassistant/components/renson/switch.py index 2cd44d20a6a..3b73bb3dffe 100644 --- a/homeassistant/components/renson/switch.py +++ b/homeassistant/components/renson/switch.py @@ -11,7 +11,7 @@ from renson_endura_delta.renson import Level, RensonVentilation from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RensonCoordinator from .const import DOMAIN @@ -68,7 +68,7 @@ class RensonBreezeSwitch(RensonEntity, SwitchEntity): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Call the Renson integration to setup.""" diff --git a/homeassistant/components/renson/time.py b/homeassistant/components/renson/time.py index feb47fadf99..0a07fd2ec4f 100644 --- a/homeassistant/components/renson/time.py +++ b/homeassistant/components/renson/time.py @@ -13,7 +13,7 @@ from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RensonData from .const import DOMAIN @@ -50,7 +50,7 @@ ENTITY_DESCRIPTIONS: tuple[RensonTimeEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Renson time platform.""" diff --git a/homeassistant/components/reolink/binary_sensor.py b/homeassistant/components/reolink/binary_sensor.py index 2191dedc9cf..4e90bfc9eef 100644 --- a/homeassistant/components/reolink/binary_sensor.py +++ b/homeassistant/components/reolink/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription from .util import ReolinkConfigEntry, ReolinkData @@ -125,7 +125,7 @@ BINARY_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink IP Camera.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/button.py b/homeassistant/components/reolink/button.py index c1a2aed4119..a67b30a394c 100644 --- a/homeassistant/components/reolink/button.py +++ b/homeassistant/components/reolink/button.py @@ -19,7 +19,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -151,7 +151,7 @@ HOST_BUTTON_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink button entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/camera.py b/homeassistant/components/reolink/camera.py index a597be3ec7a..329ef9028de 100644 --- a/homeassistant/components/reolink/camera.py +++ b/homeassistant/components/reolink/camera.py @@ -13,7 +13,7 @@ from homeassistant.components.camera import ( CameraEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription from .util import ReolinkConfigEntry, ReolinkData, raise_translated_error @@ -89,7 +89,7 @@ CAMERA_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink IP Camera.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/light.py b/homeassistant/components/reolink/light.py index bbb9592dd76..d48790264d1 100644 --- a/homeassistant/components/reolink/light.py +++ b/homeassistant/components/reolink/light.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ( ReolinkChannelCoordinatorEntity, @@ -92,7 +92,7 @@ HOST_LIGHT_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink light entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/number.py b/homeassistant/components/reolink/number.py index d8fabfaa3b8..48382df4cbc 100644 --- a/homeassistant/components/reolink/number.py +++ b/homeassistant/components/reolink/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ( ReolinkChannelCoordinatorEntity, @@ -538,7 +538,7 @@ CHIME_NUMBER_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink number entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/select.py b/homeassistant/components/reolink/select.py index df8c0269957..c0b20da0238 100644 --- a/homeassistant/components/reolink/select.py +++ b/homeassistant/components/reolink/select.py @@ -23,7 +23,7 @@ from reolink_aio.api import ( from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory, UnitOfDataRate, UnitOfFrequency from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ( ReolinkChannelCoordinatorEntity, @@ -295,7 +295,7 @@ CHIME_SELECT_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink select entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/sensor.py b/homeassistant/components/reolink/sensor.py index 36900da99ca..ecad555b481 100644 --- a/homeassistant/components/reolink/sensor.py +++ b/homeassistant/components/reolink/sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .entity import ( @@ -150,7 +150,7 @@ HDD_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink IP Camera.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/siren.py b/homeassistant/components/reolink/siren.py index 74bb227d078..f5d2de977ae 100644 --- a/homeassistant/components/reolink/siren.py +++ b/homeassistant/components/reolink/siren.py @@ -13,7 +13,7 @@ from homeassistant.components.siren import ( SirenEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription from .util import ReolinkConfigEntry, ReolinkData, raise_translated_error @@ -40,7 +40,7 @@ SIREN_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink siren entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/switch.py b/homeassistant/components/reolink/switch.py index a0b8824782a..0f106c0f2cc 100644 --- a/homeassistant/components/reolink/switch.py +++ b/homeassistant/components/reolink/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er, issue_registry as ir -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import ( @@ -330,7 +330,7 @@ DEPRECATED_NVR_SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Reolink switch entities.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/reolink/update.py b/homeassistant/components/reolink/update.py index 5a8c7d7dc08..0744d66fb5b 100644 --- a/homeassistant/components/reolink/update.py +++ b/homeassistant/components/reolink/update.py @@ -16,7 +16,7 @@ from homeassistant.components.update import ( ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -75,7 +75,7 @@ HOST_UPDATE_ENTITIES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ReolinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entities for Reolink component.""" reolink_data: ReolinkData = config_entry.runtime_data diff --git a/homeassistant/components/rfxtrx/binary_sensor.py b/homeassistant/components/rfxtrx/binary_sensor.py index 316cf44ef0d..a86ad5557b4 100644 --- a/homeassistant/components/rfxtrx/binary_sensor.py +++ b/homeassistant/components/rfxtrx/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import CONF_COMMAND_OFF, CONF_COMMAND_ON, STATE_ON from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers import event as evt from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeviceTuple, async_setup_platform_entry, get_pt2262_cmd from .const import ( @@ -91,7 +91,7 @@ def supported(event: rfxtrxmod.RFXtrxEvent) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/cover.py b/homeassistant/components/rfxtrx/cover.py index 473a0d94056..07443afb38b 100644 --- a/homeassistant/components/rfxtrx/cover.py +++ b/homeassistant/components/rfxtrx/cover.py @@ -11,7 +11,7 @@ from homeassistant.components.cover import CoverEntity, CoverEntityFeature, Cove from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeviceTuple, async_setup_platform_entry from .const import ( @@ -34,7 +34,7 @@ def supported(event: rfxtrxmod.RFXtrxEvent) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/event.py b/homeassistant/components/rfxtrx/event.py index 212d93b5019..40d02953aeb 100644 --- a/homeassistant/components/rfxtrx/event.py +++ b/homeassistant/components/rfxtrx/event.py @@ -11,7 +11,7 @@ from homeassistant.components.event import EventEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from . import DeviceTuple, async_setup_platform_entry @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/light.py b/homeassistant/components/rfxtrx/light.py index 0e2f7bef65a..90c0d2eeed7 100644 --- a/homeassistant/components/rfxtrx/light.py +++ b/homeassistant/components/rfxtrx/light.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeviceTuple, async_setup_platform_entry from .const import COMMAND_OFF_LIST, COMMAND_ON_LIST @@ -32,7 +32,7 @@ def supported(event: rfxtrxmod.RFXtrxEvent) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/sensor.py b/homeassistant/components/rfxtrx/sensor.py index 13f3c012af8..4b256279445 100644 --- a/homeassistant/components/rfxtrx/sensor.py +++ b/homeassistant/components/rfxtrx/sensor.py @@ -36,7 +36,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import DeviceTuple, async_setup_platform_entry, get_rfx_object @@ -241,7 +241,7 @@ SENSOR_TYPES_DICT = {desc.key: desc for desc in SENSOR_TYPES} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/siren.py b/homeassistant/components/rfxtrx/siren.py index 1635f1f55a9..1164dafbfce 100644 --- a/homeassistant/components/rfxtrx/siren.py +++ b/homeassistant/components/rfxtrx/siren.py @@ -11,7 +11,7 @@ from homeassistant.components.siren import ATTR_TONE, SirenEntity, SirenEntityFe from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from . import DEFAULT_OFF_DELAY, DeviceTuple, async_setup_platform_entry @@ -47,7 +47,7 @@ def get_first_key(data: dict[int, str], entry: str) -> int: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/rfxtrx/switch.py b/homeassistant/components/rfxtrx/switch.py index cd17e71f4f0..b3eb63fb2b4 100644 --- a/homeassistant/components/rfxtrx/switch.py +++ b/homeassistant/components/rfxtrx/switch.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_COMMAND_OFF, CONF_COMMAND_ON, STATE_ON from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DeviceTuple, async_setup_platform_entry, get_pt2262_cmd from .const import ( @@ -41,7 +41,7 @@ def supported(event: rfxtrxmod.RFXtrxEvent) -> bool: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up config entry.""" diff --git a/homeassistant/components/ridwell/calendar.py b/homeassistant/components/ridwell/calendar.py index ecca0366754..bb7982a5391 100644 --- a/homeassistant/components/ridwell/calendar.py +++ b/homeassistant/components/ridwell/calendar.py @@ -9,7 +9,7 @@ from aioridwell.model import RidwellAccount, RidwellPickupEvent from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RidwellDataUpdateCoordinator @@ -36,7 +36,9 @@ def async_get_calendar_event_from_pickup_event( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ridwell calendars based on a config entry.""" coordinator: RidwellDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/ridwell/sensor.py b/homeassistant/components/ridwell/sensor.py index 7fc7fdb5348..30f97ecaea8 100644 --- a/homeassistant/components/ridwell/sensor.py +++ b/homeassistant/components/ridwell/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, SENSOR_TYPE_NEXT_PICKUP from .coordinator import RidwellDataUpdateCoordinator @@ -34,7 +34,9 @@ SENSOR_DESCRIPTION = SensorEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ridwell sensors based on a config entry.""" coordinator: RidwellDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/ridwell/switch.py b/homeassistant/components/ridwell/switch.py index 04e3e4c5ff9..e3be9ea5368 100644 --- a/homeassistant/components/ridwell/switch.py +++ b/homeassistant/components/ridwell/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RidwellDataUpdateCoordinator @@ -24,7 +24,9 @@ SWITCH_DESCRIPTION = SwitchEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ridwell sensors based on a config entry.""" coordinator: RidwellDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/ring/binary_sensor.py b/homeassistant/components/ring/binary_sensor.py index da0e0cc1d9b..49051ee5e11 100644 --- a/homeassistant/components/ring/binary_sensor.py +++ b/homeassistant/components/ring/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import Platform from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_at from . import RingConfigEntry @@ -67,7 +67,7 @@ BINARY_SENSOR_TYPES: tuple[RingBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ring binary sensors from a config entry.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/button.py b/homeassistant/components/ring/button.py index 30600237847..09e6c0e413a 100644 --- a/homeassistant/components/ring/button.py +++ b/homeassistant/components/ring/button.py @@ -6,7 +6,7 @@ from ring_doorbell import RingOther from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RingConfigEntry from .coordinator import RingDataCoordinator @@ -24,7 +24,7 @@ BUTTON_DESCRIPTION = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the buttons for the Ring devices.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/camera.py b/homeassistant/components/ring/camera.py index e0ae2b52fa0..156d82665d2 100644 --- a/homeassistant/components/ring/camera.py +++ b/homeassistant/components/ring/camera.py @@ -27,7 +27,7 @@ from homeassistant.components.camera import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import RingConfigEntry @@ -76,7 +76,7 @@ CAMERA_DESCRIPTIONS: tuple[RingCameraEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Ring Door Bell and StickUp Camera.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/event.py b/homeassistant/components/ring/event.py index 4d7a6277579..db99a10de74 100644 --- a/homeassistant/components/ring/event.py +++ b/homeassistant/components/ring/event.py @@ -12,7 +12,7 @@ from homeassistant.components.event import ( EventEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RingConfigEntry from .coordinator import RingListenCoordinator @@ -57,7 +57,7 @@ EVENT_DESCRIPTIONS: tuple[RingEventEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up events for a Ring device.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/light.py b/homeassistant/components/ring/light.py index 62c5217a89b..34915dd5133 100644 --- a/homeassistant/components/ring/light.py +++ b/homeassistant/components/ring/light.py @@ -9,7 +9,7 @@ from ring_doorbell import RingStickUpCam from homeassistant.components.light import ColorMode, LightEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import RingConfigEntry @@ -40,7 +40,7 @@ class OnOffState(StrEnum): async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the lights for the Ring devices.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/number.py b/homeassistant/components/ring/number.py index b920ff7edc7..68b41451bd0 100644 --- a/homeassistant/components/ring/number.py +++ b/homeassistant/components/ring/number.py @@ -13,7 +13,7 @@ from homeassistant.components.number import ( NumberMode, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import RingConfigEntry @@ -28,7 +28,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a numbers for a Ring device.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/sensor.py b/homeassistant/components/ring/sensor.py index a2f72b94336..5744ed9a4d8 100644 --- a/homeassistant/components/ring/sensor.py +++ b/homeassistant/components/ring/sensor.py @@ -28,7 +28,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import RingConfigEntry @@ -48,7 +48,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a sensor for a Ring device.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/siren.py b/homeassistant/components/ring/siren.py index 05fa07c39eb..7f096c0e643 100644 --- a/homeassistant/components/ring/siren.py +++ b/homeassistant/components/ring/siren.py @@ -22,7 +22,7 @@ from homeassistant.components.siren import ( ) from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RingConfigEntry from .coordinator import RingDataCoordinator @@ -85,7 +85,7 @@ SIRENS: tuple[RingSirenEntityDescription[Any], ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the sirens for the Ring devices.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/ring/switch.py b/homeassistant/components/ring/switch.py index cab5654fc5a..02d98388edc 100644 --- a/homeassistant/components/ring/switch.py +++ b/homeassistant/components/ring/switch.py @@ -11,7 +11,7 @@ from ring_doorbell.const import DOORBELL_EXISTING_TYPE from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import RingConfigEntry @@ -86,7 +86,7 @@ SWITCHES: Sequence[RingSwitchEntityDescription[Any]] = ( async def async_setup_entry( hass: HomeAssistant, entry: RingConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the switches for the Ring devices.""" ring_data = entry.runtime_data diff --git a/homeassistant/components/risco/__init__.py b/homeassistant/components/risco/__init__.py index 7255c724e3f..56c7a509cca 100644 --- a/homeassistant/components/risco/__init__.py +++ b/homeassistant/components/risco/__init__.py @@ -16,7 +16,6 @@ from homeassistant.const import ( CONF_PASSWORD, CONF_PIN, CONF_PORT, - CONF_SCAN_INTERVAL, CONF_TYPE, CONF_USERNAME, Platform, @@ -30,7 +29,6 @@ from .const import ( CONF_CONCURRENCY, DATA_COORDINATOR, DEFAULT_CONCURRENCY, - DEFAULT_SCAN_INTERVAL, DOMAIN, EVENTS_COORDINATOR, SYSTEM_UPDATE_SIGNAL, @@ -144,12 +142,9 @@ async def _async_setup_cloud_entry(hass: HomeAssistant, entry: ConfigEntry) -> b except UnauthorizedError as error: raise ConfigEntryAuthFailed from error - scan_interval = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL) - coordinator = RiscoDataUpdateCoordinator(hass, risco, scan_interval) + coordinator = RiscoDataUpdateCoordinator(hass, entry, risco) await coordinator.async_config_entry_first_refresh() - events_coordinator = RiscoEventsDataUpdateCoordinator( - hass, risco, entry.entry_id, 60 - ) + events_coordinator = RiscoEventsDataUpdateCoordinator(hass, entry, risco) entry.async_on_unload(entry.add_update_listener(_update_listener)) diff --git a/homeassistant/components/risco/alarm_control_panel.py b/homeassistant/components/risco/alarm_control_panel.py index b1eae8fd917..2472baa932e 100644 --- a/homeassistant/components/risco/alarm_control_panel.py +++ b/homeassistant/components/risco/alarm_control_panel.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PIN from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LocalData, is_local from .const import ( @@ -50,7 +50,7 @@ STATES_TO_SUPPORTED_FEATURES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Risco alarm control panel.""" options = {**DEFAULT_OPTIONS, **config_entry.options} diff --git a/homeassistant/components/risco/binary_sensor.py b/homeassistant/components/risco/binary_sensor.py index a7ca0129b06..ff61985fef3 100644 --- a/homeassistant/components/risco/binary_sensor.py +++ b/homeassistant/components/risco/binary_sensor.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LocalData, is_local from .const import DATA_COORDINATOR, DOMAIN, SYSTEM_UPDATE_SIGNAL @@ -73,7 +73,7 @@ SYSTEM_ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Risco alarm control panel.""" if is_local(config_entry): diff --git a/homeassistant/components/risco/coordinator.py b/homeassistant/components/risco/coordinator.py index 8430b6a6172..e7140eb9616 100644 --- a/homeassistant/components/risco/coordinator.py +++ b/homeassistant/components/risco/coordinator.py @@ -10,11 +10,13 @@ from pyrisco import CannotConnectError, OperationError, RiscoCloud, Unauthorized from pyrisco.cloud.alarm import Alarm from pyrisco.cloud.event import Event +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.core import HomeAssistant from homeassistant.helpers.storage import Store from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import DOMAIN +from .const import DEFAULT_SCAN_INTERVAL, DOMAIN LAST_EVENT_STORAGE_VERSION = 1 LAST_EVENT_TIMESTAMP_KEY = "last_event_timestamp" @@ -24,17 +26,26 @@ _LOGGER = logging.getLogger(__name__) class RiscoDataUpdateCoordinator(DataUpdateCoordinator[Alarm]): """Class to manage fetching risco data.""" + config_entry: ConfigEntry + def __init__( - self, hass: HomeAssistant, risco: RiscoCloud, scan_interval: int + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + risco: RiscoCloud, ) -> None: """Initialize global risco data updater.""" self.risco = risco - interval = timedelta(seconds=scan_interval) super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, - update_interval=interval, + update_interval=timedelta( + seconds=config_entry.options.get( + CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL + ) + ), ) async def _async_update_data(self) -> Alarm: @@ -48,20 +59,27 @@ class RiscoDataUpdateCoordinator(DataUpdateCoordinator[Alarm]): class RiscoEventsDataUpdateCoordinator(DataUpdateCoordinator[list[Event]]): """Class to manage fetching risco data.""" + config_entry: ConfigEntry + def __init__( - self, hass: HomeAssistant, risco: RiscoCloud, eid: str, scan_interval: int + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + risco: RiscoCloud, ) -> None: """Initialize global risco data updater.""" self.risco = risco self._store = Store[dict[str, Any]]( - hass, LAST_EVENT_STORAGE_VERSION, f"risco_{eid}_last_event_timestamp" + hass, + LAST_EVENT_STORAGE_VERSION, + f"risco_{config_entry.entry_id}_last_event_timestamp", ) - interval = timedelta(seconds=scan_interval) super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"{DOMAIN}_events", - update_interval=interval, + update_interval=timedelta(seconds=60), ) async def _async_update_data(self) -> list[Event]: diff --git a/homeassistant/components/risco/sensor.py b/homeassistant/components/risco/sensor.py index c1495512e62..93683f1aa50 100644 --- a/homeassistant/components/risco/sensor.py +++ b/homeassistant/components/risco/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -46,7 +46,7 @@ EVENT_ATTRIBUTES = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" if is_local(config_entry): diff --git a/homeassistant/components/risco/switch.py b/homeassistant/components/risco/switch.py index 8bad2c6c15e..547dedd3933 100644 --- a/homeassistant/components/risco/switch.py +++ b/homeassistant/components/risco/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import LocalData, is_local from .const import DATA_COORDINATOR, DOMAIN @@ -21,7 +21,7 @@ from .entity import RiscoCloudZoneEntity, RiscoLocalZoneEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Risco switch.""" if is_local(config_entry): diff --git a/homeassistant/components/rituals_perfume_genie/__init__.py b/homeassistant/components/rituals_perfume_genie/__init__.py index d0d16ba6324..e920c2426fe 100644 --- a/homeassistant/components/rituals_perfume_genie/__init__.py +++ b/homeassistant/components/rituals_perfume_genie/__init__.py @@ -44,7 +44,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # Create a coordinator for each diffuser coordinators = { - diffuser.hublot: RitualsDataUpdateCoordinator(hass, diffuser, update_interval) + diffuser.hublot: RitualsDataUpdateCoordinator( + hass, entry, diffuser, update_interval + ) for diffuser in account_devices } diff --git a/homeassistant/components/rituals_perfume_genie/binary_sensor.py b/homeassistant/components/rituals_perfume_genie/binary_sensor.py index 63666fc1aca..97e9c8418d1 100644 --- a/homeassistant/components/rituals_perfume_genie/binary_sensor.py +++ b/homeassistant/components/rituals_perfume_genie/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RitualsDataUpdateCoordinator @@ -44,7 +44,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the diffuser binary sensors.""" coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/rituals_perfume_genie/coordinator.py b/homeassistant/components/rituals_perfume_genie/coordinator.py index a83e823bd4e..bbcb24b3e65 100644 --- a/homeassistant/components/rituals_perfume_genie/coordinator.py +++ b/homeassistant/components/rituals_perfume_genie/coordinator.py @@ -5,6 +5,7 @@ import logging from pyrituals import Diffuser +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -16,9 +17,12 @@ _LOGGER = logging.getLogger(__name__) class RitualsDataUpdateCoordinator(DataUpdateCoordinator[None]): """Class to manage fetching Rituals Perfume Genie device data from single endpoint.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, diffuser: Diffuser, update_interval: timedelta, ) -> None: @@ -27,6 +31,7 @@ class RitualsDataUpdateCoordinator(DataUpdateCoordinator[None]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"{DOMAIN}-{diffuser.hublot}", update_interval=update_interval, ) diff --git a/homeassistant/components/rituals_perfume_genie/number.py b/homeassistant/components/rituals_perfume_genie/number.py index 0ac9c30f285..98e833ff9bd 100644 --- a/homeassistant/components/rituals_perfume_genie/number.py +++ b/homeassistant/components/rituals_perfume_genie/number.py @@ -11,7 +11,7 @@ from pyrituals import Diffuser from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RitualsDataUpdateCoordinator @@ -41,7 +41,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the diffuser numbers.""" coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/rituals_perfume_genie/select.py b/homeassistant/components/rituals_perfume_genie/select.py index 27aff70649b..c239627e9c6 100644 --- a/homeassistant/components/rituals_perfume_genie/select.py +++ b/homeassistant/components/rituals_perfume_genie/select.py @@ -11,7 +11,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfArea from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RitualsDataUpdateCoordinator @@ -44,7 +44,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the diffuser select entities.""" coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index 46faa8d73e9..3921fd0b6c2 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RitualsDataUpdateCoordinator @@ -60,7 +60,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the diffuser sensors.""" coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/rituals_perfume_genie/switch.py b/homeassistant/components/rituals_perfume_genie/switch.py index b5828f5ca07..c5331b49078 100644 --- a/homeassistant/components/rituals_perfume_genie/switch.py +++ b/homeassistant/components/rituals_perfume_genie/switch.py @@ -11,7 +11,7 @@ from pyrituals import Diffuser from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RitualsDataUpdateCoordinator @@ -42,7 +42,7 @@ ENTITY_DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the diffuser switch.""" coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][ diff --git a/homeassistant/components/roborock/__init__.py b/homeassistant/components/roborock/__init__.py index b383c1acfd7..1c25d527aa8 100644 --- a/homeassistant/components/roborock/__init__.py +++ b/homeassistant/components/roborock/__init__.py @@ -4,7 +4,6 @@ from __future__ import annotations import asyncio from collections.abc import Coroutine -from dataclasses import dataclass from datetime import timedelta import logging from typing import Any @@ -21,35 +20,23 @@ from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1 from roborock.version_a01_apis import RoborockMqttClientA01 from roborock.web_api import RoborockApiClient -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_USERNAME, EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from .const import CONF_BASE_URL, CONF_USER_DATA, DOMAIN, PLATFORMS -from .coordinator import RoborockDataUpdateCoordinator, RoborockDataUpdateCoordinatorA01 +from .coordinator import ( + RoborockConfigEntry, + RoborockCoordinators, + RoborockDataUpdateCoordinator, + RoborockDataUpdateCoordinatorA01, +) from .roborock_storage import async_remove_map_storage SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) -type RoborockConfigEntry = ConfigEntry[RoborockCoordinators] - - -@dataclass -class RoborockCoordinators: - """Roborock coordinators type.""" - - v1: list[RoborockDataUpdateCoordinator] - a01: list[RoborockDataUpdateCoordinatorA01] - - def values( - self, - ) -> list[RoborockDataUpdateCoordinator | RoborockDataUpdateCoordinatorA01]: - """Return all coordinators.""" - return self.v1 + self.a01 - async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) -> bool: """Set up roborock from a config entry.""" @@ -95,7 +82,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) -> # Get a Coordinator if the device is available or if we have connected to the device before coordinators = await asyncio.gather( *build_setup_functions( - hass, device_map, user_data, product_info, home_data.rooms + hass, + entry, + device_map, + user_data, + product_info, + home_data.rooms, + api_client, ), return_exceptions=True, ) @@ -142,10 +135,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) -> def build_setup_functions( hass: HomeAssistant, + entry: RoborockConfigEntry, device_map: dict[str, HomeDataDevice], user_data: UserData, product_info: dict[str, HomeDataProduct], home_data_rooms: list[HomeDataRoom], + api_client: RoborockApiClient, ) -> list[ Coroutine[ Any, @@ -156,7 +151,13 @@ def build_setup_functions( """Create a list of setup functions that can later be called asynchronously.""" return [ setup_device( - hass, user_data, device, product_info[device.product_id], home_data_rooms + hass, + entry, + user_data, + device, + product_info[device.product_id], + home_data_rooms, + api_client, ) for device in device_map.values() ] @@ -164,18 +165,20 @@ def build_setup_functions( async def setup_device( hass: HomeAssistant, + entry: RoborockConfigEntry, user_data: UserData, device: HomeDataDevice, product_info: HomeDataProduct, home_data_rooms: list[HomeDataRoom], + api_client: RoborockApiClient, ) -> RoborockDataUpdateCoordinator | RoborockDataUpdateCoordinatorA01 | None: """Set up a coordinator for a given device.""" if device.pv == "1.0": return await setup_device_v1( - hass, user_data, device, product_info, home_data_rooms + hass, entry, user_data, device, product_info, home_data_rooms, api_client ) if device.pv == "A01": - return await setup_device_a01(hass, user_data, device, product_info) + return await setup_device_a01(hass, entry, user_data, device, product_info) _LOGGER.warning( "Not adding device %s because its protocol version %s or category %s is not supported", device.duid, @@ -187,10 +190,12 @@ async def setup_device( async def setup_device_v1( hass: HomeAssistant, + entry: RoborockConfigEntry, user_data: UserData, device: HomeDataDevice, product_info: HomeDataProduct, home_data_rooms: list[HomeDataRoom], + api_client: RoborockApiClient, ) -> RoborockDataUpdateCoordinator | None: """Set up a device Coordinator.""" mqtt_client = await hass.async_add_executor_job( @@ -212,7 +217,15 @@ async def setup_device_v1( await mqtt_client.async_release() raise coordinator = RoborockDataUpdateCoordinator( - hass, device, networking, product_info, mqtt_client, home_data_rooms + hass, + entry, + device, + networking, + product_info, + mqtt_client, + home_data_rooms, + api_client, + user_data, ) try: await coordinator.async_config_entry_first_refresh() @@ -246,6 +259,7 @@ async def setup_device_v1( async def setup_device_a01( hass: HomeAssistant, + entry: RoborockConfigEntry, user_data: UserData, device: HomeDataDevice, product_info: HomeDataProduct, @@ -254,7 +268,9 @@ async def setup_device_a01( mqtt_client = RoborockMqttClientA01( user_data, DeviceData(device, product_info.name), product_info.category ) - coord = RoborockDataUpdateCoordinatorA01(hass, device, product_info, mqtt_client) + coord = RoborockDataUpdateCoordinatorA01( + hass, entry, device, product_info, mqtt_client + ) await coord.async_config_entry_first_refresh() return coord diff --git a/homeassistant/components/roborock/binary_sensor.py b/homeassistant/components/roborock/binary_sensor.py index b88556ea857..db557f055dc 100644 --- a/homeassistant/components/roborock/binary_sensor.py +++ b/homeassistant/components/roborock/binary_sensor.py @@ -14,10 +14,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockCoordinatedEntityV1 @@ -70,7 +69,7 @@ BINARY_SENSOR_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Roborock vacuum binary sensors.""" async_add_entities( diff --git a/homeassistant/components/roborock/button.py b/homeassistant/components/roborock/button.py index 2f214c7c51c..33e9502aca1 100644 --- a/homeassistant/components/roborock/button.py +++ b/homeassistant/components/roborock/button.py @@ -9,10 +9,9 @@ from roborock.roborock_typing import RoborockCommand from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockEntityV1 @@ -63,7 +62,7 @@ CONSUMABLE_BUTTON_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock button platform.""" async_add_entities( diff --git a/homeassistant/components/roborock/const.py b/homeassistant/components/roborock/const.py index cc8d34fbadc..fe9091a3ea7 100644 --- a/homeassistant/components/roborock/const.py +++ b/homeassistant/components/roborock/const.py @@ -36,6 +36,7 @@ PLATFORMS = [ Platform.BUTTON, Platform.IMAGE, Platform.NUMBER, + Platform.SCENE, Platform.SELECT, Platform.SENSOR, Platform.SWITCH, diff --git a/homeassistant/components/roborock/coordinator.py b/homeassistant/components/roborock/coordinator.py index 8860a5c1f43..b35f62323e8 100644 --- a/homeassistant/components/roborock/coordinator.py +++ b/homeassistant/components/roborock/coordinator.py @@ -3,23 +3,33 @@ from __future__ import annotations import asyncio +from dataclasses import dataclass from datetime import timedelta import logging from propcache.api import cached_property from roborock import HomeDataRoom from roborock.code_mappings import RoborockCategory -from roborock.containers import DeviceData, HomeDataDevice, HomeDataProduct, NetworkInfo +from roborock.containers import ( + DeviceData, + HomeDataDevice, + HomeDataProduct, + HomeDataScene, + NetworkInfo, + UserData, +) from roborock.exceptions import RoborockException from roborock.roborock_message import RoborockDyadDataProtocol, RoborockZeoProtocol from roborock.roborock_typing import DeviceProp from roborock.version_1_apis.roborock_local_client_v1 import RoborockLocalClientV1 from roborock.version_1_apis.roborock_mqtt_client_v1 import RoborockMqttClientV1 from roborock.version_a01_apis import RoborockClientA01 +from roborock.web_api import RoborockApiClient from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_CONNECTIONS from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.typing import StateType @@ -35,22 +45,48 @@ SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) +@dataclass +class RoborockCoordinators: + """Roborock coordinators type.""" + + v1: list[RoborockDataUpdateCoordinator] + a01: list[RoborockDataUpdateCoordinatorA01] + + def values( + self, + ) -> list[RoborockDataUpdateCoordinator | RoborockDataUpdateCoordinatorA01]: + """Return all coordinators.""" + return self.v1 + self.a01 + + +type RoborockConfigEntry = ConfigEntry[RoborockCoordinators] + + class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]): """Class to manage fetching data from the API.""" - config_entry: ConfigEntry + config_entry: RoborockConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: RoborockConfigEntry, device: HomeDataDevice, device_networking: NetworkInfo, product_info: HomeDataProduct, cloud_api: RoborockMqttClientV1, home_data_rooms: list[HomeDataRoom], + api_client: RoborockApiClient, + user_data: UserData, ) -> None: """Initialize.""" - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) self.roborock_device_info = RoborockHassDeviceInfo( device, device_networking, @@ -64,7 +100,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]): self.cloud_api = cloud_api self.device_info = DeviceInfo( name=self.roborock_device_info.device.name, - identifiers={(DOMAIN, self.roborock_device_info.device.duid)}, + identifiers={(DOMAIN, self.duid)}, manufacturer="Roborock", model=self.roborock_device_info.product.model, model_id=self.roborock_device_info.product.model, @@ -78,8 +114,10 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]): self.maps: dict[int, RoborockMapInfo] = {} self._home_data_rooms = {str(room.id): room.name for room in home_data_rooms} self.map_storage = RoborockMapStorage( - hass, self.config_entry.entry_id, slugify(self.duid) + hass, self.config_entry.entry_id, self.duid_slug ) + self._user_data = user_data + self._api_client = api_client async def _async_setup(self) -> None: """Set up the coordinator.""" @@ -109,7 +147,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]): except RoborockException: _LOGGER.warning( "Using the cloud API for device %s. This is not recommended as it can lead to rate limiting. We recommend making your vacuum accessible by your Home Assistant instance", - self.roborock_device_info.device.duid, + self.duid, ) await self.api.async_disconnect() # We use the cloud api if the local api fails to connect. @@ -168,6 +206,34 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]): for room in room_mapping or () } + async def get_scenes(self) -> list[HomeDataScene]: + """Get scenes.""" + try: + return await self._api_client.get_scenes(self._user_data, self.duid) + except RoborockException as err: + _LOGGER.error("Failed to get scenes %s", err) + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="command_failed", + translation_placeholders={ + "command": "get_scenes", + }, + ) from err + + async def execute_scene(self, scene_id: int) -> None: + """Execute scene.""" + try: + await self._api_client.execute_scene(self._user_data, scene_id) + except RoborockException as err: + _LOGGER.error("Failed to execute scene %s %s", scene_id, err) + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="command_failed", + translation_placeholders={ + "command": "execute_scene", + }, + ) from err + @cached_property def duid(self) -> str: """Get the unique id of the device as specified by Roborock.""" @@ -186,15 +252,24 @@ class RoborockDataUpdateCoordinatorA01( ): """Class to manage fetching data from the API for A01 devices.""" + config_entry: RoborockConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: RoborockConfigEntry, device: HomeDataDevice, product_info: HomeDataProduct, api: RoborockClientA01, ) -> None: """Initialize.""" - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) self.api = api self.device_info = DeviceInfo( name=device.name, diff --git a/homeassistant/components/roborock/diagnostics.py b/homeassistant/components/roborock/diagnostics.py index e784e4ce837..4602b4bd02a 100644 --- a/homeassistant/components/roborock/diagnostics.py +++ b/homeassistant/components/roborock/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_UNIQUE_ID from homeassistant.core import HomeAssistant -from . import RoborockConfigEntry +from .coordinator import RoborockConfigEntry TO_REDACT_CONFIG = ["token", "sn", "rruid", CONF_UNIQUE_ID, "username", "uid"] diff --git a/homeassistant/components/roborock/image.py b/homeassistant/components/roborock/image.py index b4776c27164..6d9e87b0556 100644 --- a/homeassistant/components/roborock/image.py +++ b/homeassistant/components/roborock/image.py @@ -16,10 +16,9 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util -from . import RoborockConfigEntry from .const import ( DEFAULT_DRAWABLES, DOMAIN, @@ -28,14 +27,14 @@ from .const import ( MAP_FILE_FORMAT, MAP_SLEEP, ) -from .coordinator import RoborockDataUpdateCoordinator +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockCoordinatedEntityV1 async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock image platform.""" diff --git a/homeassistant/components/roborock/number.py b/homeassistant/components/roborock/number.py index 7f568ae824b..a710eeefb90 100644 --- a/homeassistant/components/roborock/number.py +++ b/homeassistant/components/roborock/number.py @@ -14,10 +14,10 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import DOMAIN, RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator +from .const import DOMAIN +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockEntityV1 _LOGGER = logging.getLogger(__name__) @@ -50,7 +50,7 @@ NUMBER_DESCRIPTIONS: list[RoborockNumberDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock number platform.""" possible_entities: list[ diff --git a/homeassistant/components/roborock/scene.py b/homeassistant/components/roborock/scene.py new file mode 100644 index 00000000000..ff418a2810c --- /dev/null +++ b/homeassistant/components/roborock/scene.py @@ -0,0 +1,64 @@ +"""Support for Roborock scene.""" + +from __future__ import annotations + +import asyncio +from typing import Any + +from homeassistant.components.scene import Scene as SceneEntity +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import EntityDescription +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback + +from . import RoborockConfigEntry +from .coordinator import RoborockDataUpdateCoordinator +from .entity import RoborockEntity + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: RoborockConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, +) -> None: + """Set up scene platform.""" + scene_lists = await asyncio.gather( + *[coordinator.get_scenes() for coordinator in config_entry.runtime_data.v1], + ) + async_add_entities( + RoborockSceneEntity( + coordinator, + EntityDescription( + key=str(scene.id), + name=scene.name, + ), + ) + for coordinator, scenes in zip( + config_entry.runtime_data.v1, scene_lists, strict=True + ) + for scene in scenes + ) + + +class RoborockSceneEntity(RoborockEntity, SceneEntity): + """A class to define Roborock scene entities.""" + + entity_description: EntityDescription + + def __init__( + self, + coordinator: RoborockDataUpdateCoordinator, + entity_description: EntityDescription, + ) -> None: + """Create a scene entity.""" + super().__init__( + f"{entity_description.key}_{coordinator.duid_slug}", + coordinator.device_info, + coordinator.api, + ) + self._scene_id = int(entity_description.key) + self._coordinator = coordinator + self.entity_description = entity_description + + async def async_activate(self, **kwargs: Any) -> None: + """Activate the scene.""" + await self._coordinator.execute_scene(self._scene_id) diff --git a/homeassistant/components/roborock/select.py b/homeassistant/components/roborock/select.py index 73cb95d2d7c..6133eed0652 100644 --- a/homeassistant/components/roborock/select.py +++ b/homeassistant/components/roborock/select.py @@ -11,11 +11,10 @@ from roborock.roborock_typing import RoborockCommand from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RoborockConfigEntry from .const import MAP_SLEEP -from .coordinator import RoborockDataUpdateCoordinator +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockCoordinatedEntityV1 @@ -65,7 +64,7 @@ SELECT_DESCRIPTIONS: list[RoborockSelectDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock select platform.""" diff --git a/homeassistant/components/roborock/sensor.py b/homeassistant/components/roborock/sensor.py index e01a03d7720..f95dc5fa98f 100644 --- a/homeassistant/components/roborock/sensor.py +++ b/homeassistant/components/roborock/sensor.py @@ -28,11 +28,14 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfArea, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator, RoborockDataUpdateCoordinatorA01 +from .coordinator import ( + RoborockConfigEntry, + RoborockDataUpdateCoordinator, + RoborockDataUpdateCoordinatorA01, +) from .entity import RoborockCoordinatedEntityA01, RoborockCoordinatedEntityV1 @@ -292,7 +295,7 @@ A01_SENSOR_DESCRIPTIONS: list[RoborockSensorDescriptionA01] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Roborock vacuum sensors.""" coordinators = config_entry.runtime_data diff --git a/homeassistant/components/roborock/switch.py b/homeassistant/components/roborock/switch.py index b0c8c880188..0171d59abfd 100644 --- a/homeassistant/components/roborock/switch.py +++ b/homeassistant/components/roborock/switch.py @@ -16,10 +16,10 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import DOMAIN, RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator +from .const import DOMAIN +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockEntityV1 _LOGGER = logging.getLogger(__name__) @@ -99,7 +99,7 @@ SWITCH_DESCRIPTIONS: list[RoborockSwitchDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock switch platform.""" possible_entities: list[ diff --git a/homeassistant/components/roborock/time.py b/homeassistant/components/roborock/time.py index 1dd681dff1f..6aa70e300e5 100644 --- a/homeassistant/components/roborock/time.py +++ b/homeassistant/components/roborock/time.py @@ -16,10 +16,10 @@ from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import DOMAIN, RoborockConfigEntry -from .coordinator import RoborockDataUpdateCoordinator +from .const import DOMAIN +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockEntityV1 _LOGGER = logging.getLogger(__name__) @@ -114,7 +114,7 @@ TIME_DESCRIPTIONS: list[RoborockTimeDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roborock time platform.""" possible_entities: list[ diff --git a/homeassistant/components/roborock/vacuum.py b/homeassistant/components/roborock/vacuum.py index 7582dadad16..59abc888673 100644 --- a/homeassistant/components/roborock/vacuum.py +++ b/homeassistant/components/roborock/vacuum.py @@ -16,16 +16,15 @@ from homeassistant.components.vacuum import ( from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RoborockConfigEntry from .const import ( DOMAIN, GET_MAPS_SERVICE_NAME, GET_VACUUM_CURRENT_POSITION_SERVICE_NAME, SET_VACUUM_GOTO_POSITION_SERVICE_NAME, ) -from .coordinator import RoborockDataUpdateCoordinator +from .coordinator import RoborockConfigEntry, RoborockDataUpdateCoordinator from .entity import RoborockCoordinatedEntityV1 from .image import ColorsPalette, ImageConfig, RoborockMapDataParser, Sizes @@ -59,7 +58,7 @@ STATE_CODE_TO_STATE = { async def async_setup_entry( hass: HomeAssistant, config_entry: RoborockConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Roborock sensor.""" async_add_entities( diff --git a/homeassistant/components/roku/__init__.py b/homeassistant/components/roku/__init__.py index e6b92d91335..be0b20c97fb 100644 --- a/homeassistant/components/roku/__init__.py +++ b/homeassistant/components/roku/__init__.py @@ -2,12 +2,10 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, Platform +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from .const import CONF_PLAY_MEDIA_APP_ID, DEFAULT_PLAY_MEDIA_APP_ID -from .coordinator import RokuDataUpdateCoordinator +from .coordinator import RokuConfigEntry, RokuDataUpdateCoordinator PLATFORMS = [ Platform.BINARY_SENSOR, @@ -17,22 +15,10 @@ PLATFORMS = [ Platform.SENSOR, ] -type RokuConfigEntry = ConfigEntry[RokuDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: RokuConfigEntry) -> bool: """Set up Roku from a config entry.""" - if (device_id := entry.unique_id) is None: - device_id = entry.entry_id - - coordinator = RokuDataUpdateCoordinator( - hass, - host=entry.data[CONF_HOST], - device_id=device_id, - play_media_app_id=entry.options.get( - CONF_PLAY_MEDIA_APP_ID, DEFAULT_PLAY_MEDIA_APP_ID - ), - ) + coordinator = RokuDataUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/roku/binary_sensor.py b/homeassistant/components/roku/binary_sensor.py index 2e7fd12788c..31250898055 100644 --- a/homeassistant/components/roku/binary_sensor.py +++ b/homeassistant/components/roku/binary_sensor.py @@ -13,9 +13,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RokuConfigEntry +from .coordinator import RokuConfigEntry from .entity import RokuEntity # Coordinator is used to centralize the data updates @@ -59,7 +59,7 @@ BINARY_SENSORS: tuple[RokuBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RokuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Roku binary sensors based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/roku/config_flow.py b/homeassistant/components/roku/config_flow.py index 2fb016b5467..47bc86802d2 100644 --- a/homeassistant/components/roku/config_flow.py +++ b/homeassistant/components/roku/config_flow.py @@ -25,8 +25,8 @@ from homeassistant.helpers.service_info.ssdp import ( ) from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo -from . import RokuConfigEntry from .const import CONF_PLAY_MEDIA_APP_ID, DEFAULT_PLAY_MEDIA_APP_ID, DOMAIN +from .coordinator import RokuConfigEntry DATA_SCHEMA = vol.Schema({vol.Required(CONF_HOST): str}) diff --git a/homeassistant/components/roku/coordinator.py b/homeassistant/components/roku/coordinator.py index 7900669d02f..e3c20d8351f 100644 --- a/homeassistant/components/roku/coordinator.py +++ b/homeassistant/components/roku/coordinator.py @@ -8,33 +8,44 @@ import logging from rokuecp import Roku, RokuError from rokuecp.models import Device +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util.dt import utcnow -from .const import DOMAIN +from .const import CONF_PLAY_MEDIA_APP_ID, DEFAULT_PLAY_MEDIA_APP_ID, DOMAIN REQUEST_REFRESH_DELAY = 0.35 SCAN_INTERVAL = timedelta(seconds=10) _LOGGER = logging.getLogger(__name__) +type RokuConfigEntry = ConfigEntry[RokuDataUpdateCoordinator] + class RokuDataUpdateCoordinator(DataUpdateCoordinator[Device]): """Class to manage fetching Roku data.""" + config_entry: RokuConfigEntry last_full_update: datetime | None roku: Roku def __init__( - self, hass: HomeAssistant, *, host: str, device_id: str, play_media_app_id: str + self, + hass: HomeAssistant, + config_entry: RokuConfigEntry, ) -> None: """Initialize global Roku data updater.""" - self.device_id = device_id - self.roku = Roku(host=host, session=async_get_clientsession(hass)) - self.play_media_app_id = play_media_app_id + self.device_id = config_entry.unique_id or config_entry.entry_id + self.roku = Roku( + host=config_entry.data[CONF_HOST], session=async_get_clientsession(hass) + ) + self.play_media_app_id = config_entry.options.get( + CONF_PLAY_MEDIA_APP_ID, DEFAULT_PLAY_MEDIA_APP_ID + ) self.full_update_interval = timedelta(minutes=15) self.last_full_update = None @@ -42,6 +53,7 @@ class RokuDataUpdateCoordinator(DataUpdateCoordinator[Device]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, # We don't want an immediate refresh since the device diff --git a/homeassistant/components/roku/diagnostics.py b/homeassistant/components/roku/diagnostics.py index e98837ca442..86e7a7ac1c9 100644 --- a/homeassistant/components/roku/diagnostics.py +++ b/homeassistant/components/roku/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import RokuConfigEntry +from .coordinator import RokuConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/roku/entity.py b/homeassistant/components/roku/entity.py index 259cb092cb8..1321e3806d1 100644 --- a/homeassistant/components/roku/entity.py +++ b/homeassistant/components/roku/entity.py @@ -6,8 +6,8 @@ from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, Device from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import RokuDataUpdateCoordinator from .const import DOMAIN +from .coordinator import RokuDataUpdateCoordinator class RokuEntity(CoordinatorEntity[RokuDataUpdateCoordinator]): diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index 0c1f92521af..d0e1e3a53c0 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -26,10 +26,9 @@ from homeassistant.components.stream import FORMAT_CONTENT_TYPE, HLS_PROVIDER from homeassistant.const import ATTR_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType -from . import RokuConfigEntry from .browse_media import async_browse_media from .const import ( ATTR_ARTIST_NAME, @@ -40,7 +39,7 @@ from .const import ( ATTR_THUMBNAIL, SERVICE_SEARCH, ) -from .coordinator import RokuDataUpdateCoordinator +from .coordinator import RokuConfigEntry, RokuDataUpdateCoordinator from .entity import RokuEntity from .helpers import format_channel_name, roku_exception_handler @@ -83,7 +82,9 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( - hass: HomeAssistant, entry: RokuConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: RokuConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Roku config entry.""" async_add_entities( diff --git a/homeassistant/components/roku/remote.py b/homeassistant/components/roku/remote.py index f7916fb23a2..cc3689c9df3 100644 --- a/homeassistant/components/roku/remote.py +++ b/homeassistant/components/roku/remote.py @@ -7,9 +7,9 @@ from typing import Any from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RokuConfigEntry +from .coordinator import RokuConfigEntry from .entity import RokuEntity from .helpers import roku_exception_handler @@ -19,7 +19,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: RokuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Roku remote based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/roku/select.py b/homeassistant/components/roku/select.py index 360d4e25415..062e1258ea2 100644 --- a/homeassistant/components/roku/select.py +++ b/homeassistant/components/roku/select.py @@ -10,9 +10,9 @@ from rokuecp.models import Device as RokuDevice from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RokuConfigEntry +from .coordinator import RokuConfigEntry from .entity import RokuEntity from .helpers import format_channel_name, roku_exception_handler @@ -109,7 +109,7 @@ CHANNEL_ENTITY = RokuSelectEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: RokuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roku select based on a config entry.""" device: RokuDevice = entry.runtime_data.data diff --git a/homeassistant/components/roku/sensor.py b/homeassistant/components/roku/sensor.py index 870386945a6..a61a9be6a73 100644 --- a/homeassistant/components/roku/sensor.py +++ b/homeassistant/components/roku/sensor.py @@ -10,9 +10,9 @@ from rokuecp.models import Device as RokuDevice from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import RokuConfigEntry +from .coordinator import RokuConfigEntry from .entity import RokuEntity # Coordinator is used to centralize the data updates @@ -45,7 +45,7 @@ SENSORS: tuple[RokuSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: RokuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roku sensor based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/romy/binary_sensor.py b/homeassistant/components/romy/binary_sensor.py index d8f6216007f..599c0fe023e 100644 --- a/homeassistant/components/romy/binary_sensor.py +++ b/homeassistant/components/romy/binary_sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RomyVacuumCoordinator @@ -39,7 +39,7 @@ BINARY_SENSORS: list[BinarySensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ROMY vacuum cleaner.""" diff --git a/homeassistant/components/romy/sensor.py b/homeassistant/components/romy/sensor.py index 341125b86ba..85bf0df8f64 100644 --- a/homeassistant/components/romy/sensor.py +++ b/homeassistant/components/romy/sensor.py @@ -16,7 +16,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import RomyVacuumCoordinator @@ -77,7 +77,7 @@ SENSORS: list[SensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ROMY vacuum cleaner.""" diff --git a/homeassistant/components/romy/vacuum.py b/homeassistant/components/romy/vacuum.py index 49129daabbd..0e9dd13ffe1 100644 --- a/homeassistant/components/romy/vacuum.py +++ b/homeassistant/components/romy/vacuum.py @@ -13,7 +13,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LOGGER from .coordinator import RomyVacuumCoordinator @@ -51,7 +51,7 @@ SUPPORT_ROMY_ROBOT = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up ROMY vacuum cleaner.""" diff --git a/homeassistant/components/roomba/binary_sensor.py b/homeassistant/components/roomba/binary_sensor.py index baf66375036..d50535c885a 100644 --- a/homeassistant/components/roomba/binary_sensor.py +++ b/homeassistant/components/roomba/binary_sensor.py @@ -3,7 +3,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import roomba_reported_state from .const import DOMAIN @@ -14,7 +14,7 @@ from .models import RoombaData async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the iRobot Roomba vacuum cleaner.""" domain_data: RoombaData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/roomba/sensor.py b/homeassistant/components/roomba/sensor.py index d358dcb428c..3a98bedcd94 100644 --- a/homeassistant/components/roomba/sensor.py +++ b/homeassistant/components/roomba/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfArea, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -125,7 +125,7 @@ SENSORS: list[RoombaSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the iRobot Roomba vacuum cleaner.""" domain_data: RoombaData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/roomba/vacuum.py b/homeassistant/components/roomba/vacuum.py index 92063f74afa..10606814a35 100644 --- a/homeassistant/components/roomba/vacuum.py +++ b/homeassistant/components/roomba/vacuum.py @@ -14,7 +14,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM @@ -89,7 +89,7 @@ SUPPORT_BRAAVA = SUPPORT_IROBOT | VacuumEntityFeature.FAN_SPEED async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the iRobot Roomba vacuum cleaner.""" domain_data: RoombaData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/roon/event.py b/homeassistant/components/roon/event.py index 7bc6ea27dd9..2f2967c5789 100644 --- a/homeassistant/components/roon/event.py +++ b/homeassistant/components/roon/event.py @@ -8,7 +8,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roon Event from Config Entry.""" roon_server = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/roon/media_player.py b/homeassistant/components/roon/media_player.py index 3b1735cd2fc..0460e2cfc6e 100644 --- a/homeassistant/components/roon/media_player.py +++ b/homeassistant/components/roon/media_player.py @@ -25,7 +25,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import convert from homeassistant.util.dt import utcnow @@ -52,7 +52,7 @@ REPEAT_MODE_MAPPING_TO_ROON = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Roon MediaPlayer from Config Entry.""" roon_server = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/rova/sensor.py b/homeassistant/components/rova/sensor.py index 589183eb7a8..59f9f28f8f5 100644 --- a/homeassistant/components/rova/sensor.py +++ b/homeassistant/components/rova/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -43,7 +43,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Rova entry.""" coordinator: RovaCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/rpi_power/binary_sensor.py b/homeassistant/components/rpi_power/binary_sensor.py index 00d7ec0e3f4..1424148f554 100644 --- a/homeassistant/components/rpi_power/binary_sensor.py +++ b/homeassistant/components/rpi_power/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback _LOGGER = logging.getLogger(__name__) @@ -28,7 +28,7 @@ DESCRIPTION_UNDER_VOLTAGE = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up rpi_power binary sensor.""" under_voltage = await hass.async_add_executor_job(new_under_voltage) diff --git a/homeassistant/components/ruckus_unleashed/__init__.py b/homeassistant/components/ruckus_unleashed/__init__.py index 4ee870e8322..8e9219985ce 100644 --- a/homeassistant/components/ruckus_unleashed/__init__.py +++ b/homeassistant/components/ruckus_unleashed/__init__.py @@ -46,7 +46,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await ruckus.close() raise ConfigEntryAuthFailed from autherr - coordinator = RuckusDataUpdateCoordinator(hass, ruckus=ruckus) + coordinator = RuckusDataUpdateCoordinator(hass, entry, ruckus) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/ruckus_unleashed/coordinator.py b/homeassistant/components/ruckus_unleashed/coordinator.py index d9f20883559..7ffaab2e977 100644 --- a/homeassistant/components/ruckus_unleashed/coordinator.py +++ b/homeassistant/components/ruckus_unleashed/coordinator.py @@ -6,6 +6,7 @@ import logging from aioruckus import AjaxSession from aioruckus.exceptions import AuthenticationError, SchemaError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -18,17 +19,20 @@ _LOGGER = logging.getLogger(__package__) class RuckusDataUpdateCoordinator(DataUpdateCoordinator): """Coordinator to manage data from Ruckus client.""" - def __init__(self, hass: HomeAssistant, *, ruckus: AjaxSession) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, ruckus: AjaxSession + ) -> None: """Initialize global Ruckus data updater.""" self.ruckus = ruckus - update_interval = timedelta(seconds=SCAN_INTERVAL) - super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, - update_interval=update_interval, + update_interval=timedelta(seconds=SCAN_INTERVAL), ) async def _fetch_clients(self) -> dict: diff --git a/homeassistant/components/ruckus_unleashed/device_tracker.py b/homeassistant/components/ruckus_unleashed/device_tracker.py index 8a5e8b79294..890148ec25c 100644 --- a/homeassistant/components/ruckus_unleashed/device_tracker.py +++ b/homeassistant/components/ruckus_unleashed/device_tracker.py @@ -8,7 +8,7 @@ from homeassistant.components.device_tracker import ScannerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -25,7 +25,9 @@ _LOGGER = logging.getLogger(__package__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Ruckus component.""" coordinator = hass.data[DOMAIN][entry.entry_id][COORDINATOR] @@ -69,7 +71,7 @@ def restore_entities( registry: er.EntityRegistry, coordinator: RuckusDataUpdateCoordinator, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: set[str], ) -> None: """Restore clients that are not a part of active clients list.""" diff --git a/homeassistant/components/russound_rio/media_player.py b/homeassistant/components/russound_rio/media_player.py index 346f4903f6a..b40b82862f9 100644 --- a/homeassistant/components/russound_rio/media_player.py +++ b/homeassistant/components/russound_rio/media_player.py @@ -20,7 +20,7 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import RussoundConfigEntry from .entity import RussoundBaseEntity, command @@ -33,7 +33,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: RussoundConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Russound RIO platform.""" client = entry.runtime_data diff --git a/homeassistant/components/ruuvi_gateway/__init__.py b/homeassistant/components/ruuvi_gateway/__init__.py index 77b3e9b57de..da93a89a9f3 100644 --- a/homeassistant/components/ruuvi_gateway/__init__.py +++ b/homeassistant/components/ruuvi_gateway/__init__.py @@ -5,11 +5,10 @@ from __future__ import annotations import logging from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, CONF_TOKEN from homeassistant.core import HomeAssistant from .bluetooth import async_connect_scanner -from .const import DOMAIN, SCAN_INTERVAL +from .const import DOMAIN from .coordinator import RuuviGatewayUpdateCoordinator from .models import RuuviGatewayRuntimeData @@ -18,14 +17,7 @@ _LOGGER = logging.getLogger(DOMAIN) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Ruuvi Gateway from a config entry.""" - coordinator = RuuviGatewayUpdateCoordinator( - hass, - logger=_LOGGER, - name=entry.title, - update_interval=SCAN_INTERVAL, - host=entry.data[CONF_HOST], - token=entry.data[CONF_TOKEN], - ) + coordinator = RuuviGatewayUpdateCoordinator(hass, entry, _LOGGER) scanner, unload_scanner = async_connect_scanner(hass, entry, coordinator) hass.data.setdefault(DOMAIN, {})[entry.entry_id] = RuuviGatewayRuntimeData( update_coordinator=coordinator, diff --git a/homeassistant/components/ruuvi_gateway/coordinator.py b/homeassistant/components/ruuvi_gateway/coordinator.py index ba72dfe4cbc..0c42cd0cb38 100644 --- a/homeassistant/components/ruuvi_gateway/coordinator.py +++ b/homeassistant/components/ruuvi_gateway/coordinator.py @@ -2,34 +2,41 @@ from __future__ import annotations -from datetime import timedelta import logging from aioruuvigateway.api import get_gateway_history_data from aioruuvigateway.models import TagData +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST, CONF_TOKEN from homeassistant.core import HomeAssistant from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.update_coordinator import DataUpdateCoordinator +from .const import SCAN_INTERVAL + class RuuviGatewayUpdateCoordinator(DataUpdateCoordinator[list[TagData]]): """Polls the gateway for data and returns a list of TagData objects that have changed since the last poll.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, logger: logging.Logger, - *, - name: str, - update_interval: timedelta | None = None, - host: str, - token: str, ) -> None: """Initialize the coordinator using the given configuration (host, token).""" - super().__init__(hass, logger, name=name, update_interval=update_interval) - self.host = host - self.token = token + super().__init__( + hass, + logger, + config_entry=config_entry, + name=config_entry.title, + update_interval=SCAN_INTERVAL, + ) + self.host = config_entry.data[CONF_HOST] + self.token = config_entry.data[CONF_TOKEN] self.last_tag_datas: dict[str, TagData] = {} async def _async_update_data(self) -> list[TagData]: diff --git a/homeassistant/components/ruuvitag_ble/sensor.py b/homeassistant/components/ruuvitag_ble/sensor.py index ef287753ed4..57248d547ba 100644 --- a/homeassistant/components/ruuvitag_ble/sensor.py +++ b/homeassistant/components/ruuvitag_ble/sensor.py @@ -32,7 +32,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -126,7 +126,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Ruuvitag BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/rympro/sensor.py b/homeassistant/components/rympro/sensor.py index 8bb0af6e9ff..250e942fb4f 100644 --- a/homeassistant/components/rympro/sensor.py +++ b/homeassistant/components/rympro/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfVolume from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -48,7 +48,7 @@ SENSOR_DESCRIPTIONS: tuple[RymProSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" coordinator: RymProDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/sabnzbd/binary_sensor.py b/homeassistant/components/sabnzbd/binary_sensor.py index 1d65bf01211..59ef17237e2 100644 --- a/homeassistant/components/sabnzbd/binary_sensor.py +++ b/homeassistant/components/sabnzbd/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SabnzbdConfigEntry from .entity import SabnzbdEntity @@ -40,7 +40,7 @@ BINARY_SENSORS: tuple[SabnzbdBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SabnzbdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Sabnzbd sensor entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/sabnzbd/button.py b/homeassistant/components/sabnzbd/button.py index 1ff26b41655..25c11f6b2ec 100644 --- a/homeassistant/components/sabnzbd/button.py +++ b/homeassistant/components/sabnzbd/button.py @@ -9,7 +9,7 @@ from pysabnzbd import SabnzbdApiException from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SabnzbdConfigEntry, SabnzbdUpdateCoordinator @@ -40,7 +40,7 @@ BUTTON_DESCRIPTIONS: tuple[SabnzbdButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SabnzbdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/sabnzbd/number.py b/homeassistant/components/sabnzbd/number.py index 53c8d462f11..63b2206ac70 100644 --- a/homeassistant/components/sabnzbd/number.py +++ b/homeassistant/components/sabnzbd/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SabnzbdConfigEntry, SabnzbdUpdateCoordinator @@ -48,7 +48,7 @@ NUMBER_DESCRIPTIONS: tuple[SabnzbdNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SabnzbdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SABnzbd number entity.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/sabnzbd/sensor.py b/homeassistant/components/sabnzbd/sensor.py index 662ae739d15..5e871b4bf40 100644 --- a/homeassistant/components/sabnzbd/sensor.py +++ b/homeassistant/components/sabnzbd/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfDataRate, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import SabnzbdConfigEntry @@ -115,7 +115,7 @@ SENSOR_TYPES: tuple[SabnzbdSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SabnzbdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Sabnzbd sensor entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 9db9916c24a..4e6ecfd3593 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -31,7 +31,7 @@ from homeassistant.components.media_player import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.async_ import create_eager_task from .bridge import SamsungTVWSBridge @@ -63,7 +63,7 @@ APP_LIST_DELAY = 3 async def async_setup_entry( hass: HomeAssistant, entry: SamsungTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Samsung TV from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/samsungtv/remote.py b/homeassistant/components/samsungtv/remote.py index 3d2529153be..d6fef262d91 100644 --- a/homeassistant/components/samsungtv/remote.py +++ b/homeassistant/components/samsungtv/remote.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.remote import ATTR_NUM_REPEATS, RemoteEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER from .coordinator import SamsungTVConfigEntry @@ -17,7 +17,7 @@ from .entity import SamsungTVEntity async def async_setup_entry( hass: HomeAssistant, entry: SamsungTVConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Samsung TV from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/sanix/sensor.py b/homeassistant/components/sanix/sensor.py index 39a1c593433..d2a1aecb099 100644 --- a/homeassistant/components/sanix/sensor.py +++ b/homeassistant/components/sanix/sensor.py @@ -24,7 +24,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfLength from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MANUFACTURER @@ -82,7 +82,9 @@ SENSOR_TYPES: tuple[SanixSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sanix Sensor entities based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/schlage/__init__.py b/homeassistant/components/schlage/__init__.py index 6eae69d9542..509a335aafe 100644 --- a/homeassistant/components/schlage/__init__.py +++ b/homeassistant/components/schlage/__init__.py @@ -5,12 +5,11 @@ from __future__ import annotations from pycognito.exceptions import WarrantException import pyschlage -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed -from .coordinator import SchlageDataUpdateCoordinator +from .coordinator import SchlageConfigEntry, SchlageDataUpdateCoordinator PLATFORMS: list[Platform] = [ Platform.BINARY_SENSOR, @@ -20,8 +19,6 @@ PLATFORMS: list[Platform] = [ Platform.SWITCH, ] -type SchlageConfigEntry = ConfigEntry[SchlageDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: SchlageConfigEntry) -> bool: """Set up Schlage from a config entry.""" @@ -32,7 +29,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: SchlageConfigEntry) -> b except WarrantException as ex: raise ConfigEntryAuthFailed from ex - coordinator = SchlageDataUpdateCoordinator(hass, username, pyschlage.Schlage(auth)) + coordinator = SchlageDataUpdateCoordinator( + hass, entry, username, pyschlage.Schlage(auth) + ) entry.runtime_data = coordinator await coordinator.async_config_entry_first_refresh() await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/schlage/binary_sensor.py b/homeassistant/components/schlage/binary_sensor.py index f928d42b3ee..62e69b5cb4a 100644 --- a/homeassistant/components/schlage/binary_sensor.py +++ b/homeassistant/components/schlage/binary_sensor.py @@ -12,10 +12,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import SchlageConfigEntry -from .coordinator import LockData, SchlageDataUpdateCoordinator +from .coordinator import LockData, SchlageConfigEntry, SchlageDataUpdateCoordinator from .entity import SchlageEntity @@ -40,7 +39,7 @@ _DESCRIPTIONS: tuple[SchlageBinarySensorEntityDescription] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SchlageConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary_sensors based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/schlage/coordinator.py b/homeassistant/components/schlage/coordinator.py index 936ef9ee91e..eec143c574f 100644 --- a/homeassistant/components/schlage/coordinator.py +++ b/homeassistant/components/schlage/coordinator.py @@ -34,15 +34,28 @@ class SchlageData: locks: dict[str, LockData] +type SchlageConfigEntry = ConfigEntry[SchlageDataUpdateCoordinator] + + class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]): """The Schlage data update coordinator.""" - config_entry: ConfigEntry + config_entry: SchlageConfigEntry - def __init__(self, hass: HomeAssistant, username: str, api: Schlage) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: SchlageConfigEntry, + username: str, + api: Schlage, + ) -> None: """Initialize the class.""" super().__init__( - hass, LOGGER, name=f"{DOMAIN} ({username})", update_interval=UPDATE_INTERVAL + hass, + LOGGER, + config_entry=config_entry, + name=f"{DOMAIN} ({username})", + update_interval=UPDATE_INTERVAL, ) self.data = SchlageData(locks={}) self.api = api diff --git a/homeassistant/components/schlage/diagnostics.py b/homeassistant/components/schlage/diagnostics.py index ec4d9c489e3..357f04f00db 100644 --- a/homeassistant/components/schlage/diagnostics.py +++ b/homeassistant/components/schlage/diagnostics.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.core import HomeAssistant -from . import SchlageConfigEntry +from .coordinator import SchlageConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/schlage/lock.py b/homeassistant/components/schlage/lock.py index d203913191d..83abf9214e3 100644 --- a/homeassistant/components/schlage/lock.py +++ b/homeassistant/components/schlage/lock.py @@ -6,17 +6,16 @@ from typing import Any from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import SchlageConfigEntry -from .coordinator import LockData, SchlageDataUpdateCoordinator +from .coordinator import LockData, SchlageConfigEntry, SchlageDataUpdateCoordinator from .entity import SchlageEntity async def async_setup_entry( hass: HomeAssistant, config_entry: SchlageConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Schlage WiFi locks based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/schlage/select.py b/homeassistant/components/schlage/select.py index 6cf0853835f..4648686aaac 100644 --- a/homeassistant/components/schlage/select.py +++ b/homeassistant/components/schlage/select.py @@ -5,10 +5,9 @@ from __future__ import annotations from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import SchlageConfigEntry -from .coordinator import LockData, SchlageDataUpdateCoordinator +from .coordinator import LockData, SchlageConfigEntry, SchlageDataUpdateCoordinator from .entity import SchlageEntity _DESCRIPTIONS = ( @@ -33,7 +32,7 @@ _DESCRIPTIONS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SchlageConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up selects based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/schlage/sensor.py b/homeassistant/components/schlage/sensor.py index a15d1740b91..494efc7585a 100644 --- a/homeassistant/components/schlage/sensor.py +++ b/homeassistant/components/schlage/sensor.py @@ -8,12 +8,11 @@ from homeassistant.components.sensor import ( SensorEntityDescription, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import LockData, SchlageDataUpdateCoordinator +from .coordinator import LockData, SchlageConfigEntry, SchlageDataUpdateCoordinator from .entity import SchlageEntity _SENSOR_DESCRIPTIONS: list[SensorEntityDescription] = [ @@ -29,8 +28,8 @@ _SENSOR_DESCRIPTIONS: list[SensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: SchlageConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/schlage/switch.py b/homeassistant/components/schlage/switch.py index 39fe6dbbc99..c40d0c41e88 100644 --- a/homeassistant/components/schlage/switch.py +++ b/homeassistant/components/schlage/switch.py @@ -14,12 +14,11 @@ from homeassistant.components.switch import ( SwitchEntity, SwitchEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import LockData, SchlageDataUpdateCoordinator +from .coordinator import LockData, SchlageConfigEntry, SchlageDataUpdateCoordinator from .entity import SchlageEntity @@ -56,8 +55,8 @@ SWITCHES: tuple[SchlageSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + config_entry: SchlageConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches based on a config entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/scrape/sensor.py b/homeassistant/components/scrape/sensor.py index 5ee837f32d1..b8ad9cb8a56 100644 --- a/homeassistant/components/scrape/sensor.py +++ b/homeassistant/components/scrape/sensor.py @@ -21,7 +21,10 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.template import Template from homeassistant.helpers.trigger_template_entity import ( CONF_AVAILABILITY, @@ -92,7 +95,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: ScrapeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Scrape sensor entry.""" entities: list = [] diff --git a/homeassistant/components/screenlogic/binary_sensor.py b/homeassistant/components/screenlogic/binary_sensor.py index 4a178c60d81..a846a9fa4e3 100644 --- a/homeassistant/components/screenlogic/binary_sensor.py +++ b/homeassistant/components/screenlogic/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ScreenlogicDataUpdateCoordinator from .entity import ( @@ -195,7 +195,7 @@ SUPPORTED_SCG_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/screenlogic/climate.py b/homeassistant/components/screenlogic/climate.py index e44d9b18ae1..03aebadbba6 100644 --- a/homeassistant/components/screenlogic/climate.py +++ b/homeassistant/components/screenlogic/climate.py @@ -21,7 +21,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .entity import ScreenLogicPushEntity, ScreenLogicPushEntityDescription @@ -42,7 +42,7 @@ SUPPORTED_PRESETS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/screenlogic/light.py b/homeassistant/components/screenlogic/light.py index 412b2df5f81..b0bd154b66d 100644 --- a/homeassistant/components/screenlogic/light.py +++ b/homeassistant/components/screenlogic/light.py @@ -12,7 +12,7 @@ from homeassistant.components.light import ( LightEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LIGHT_CIRCUIT_FUNCTIONS from .entity import ScreenLogicCircuitEntity, ScreenLogicPushEntityDescription @@ -22,7 +22,7 @@ from .types import ScreenLogicConfigEntry async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" entities: list[ScreenLogicLight] = [] diff --git a/homeassistant/components/screenlogic/number.py b/homeassistant/components/screenlogic/number.py index 3634147e509..ea9bf8ac95d 100644 --- a/homeassistant/components/screenlogic/number.py +++ b/homeassistant/components/screenlogic/number.py @@ -17,7 +17,7 @@ from homeassistant.components.number import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ScreenlogicDataUpdateCoordinator from .entity import ( @@ -104,7 +104,7 @@ SUPPORTED_SCG_NUMBERS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" entities: list[ScreenLogicNumber] = [] diff --git a/homeassistant/components/screenlogic/sensor.py b/homeassistant/components/screenlogic/sensor.py index 7a5e910923c..95a7e3a5c75 100644 --- a/homeassistant/components/screenlogic/sensor.py +++ b/homeassistant/components/screenlogic/sensor.py @@ -20,7 +20,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ScreenlogicDataUpdateCoordinator from .entity import ( @@ -272,7 +272,7 @@ SUPPORTED_SCG_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/screenlogic/strings.json b/homeassistant/components/screenlogic/strings.json index 09e64808dfe..97e12277eb6 100644 --- a/homeassistant/components/screenlogic/strings.json +++ b/homeassistant/components/screenlogic/strings.json @@ -3,9 +3,9 @@ "service_config_entry_name": "Config entry", "service_config_entry_description": "The config entry to use for this action.", "climate_preset_solar": "Solar", - "climate_preset_solar_preferred": "Solar Preferred", + "climate_preset_solar_preferred": "Solar preferred", "climate_preset_heater": "Heater", - "climate_preset_dont_change": "Don't Change" + "climate_preset_dont_change": "Don't change" }, "config": { "flow_title": "{name}", @@ -15,7 +15,7 @@ "step": { "gateway_entry": { "title": "ScreenLogic", - "description": "Enter your ScreenLogic Gateway information.", + "description": "Enter your ScreenLogic gateway information.", "data": { "ip_address": "[%key:common::config_flow::data::ip%]", "port": "[%key:common::config_flow::data::port%]" @@ -46,7 +46,7 @@ }, "services": { "set_color_mode": { - "name": "Set Color Mode", + "name": "Set color mode", "description": "Sets the color mode for all color-capable lights attached to this ScreenLogic gateway.", "fields": { "config_entry": { @@ -54,13 +54,13 @@ "description": "[%key:component::screenlogic::common::service_config_entry_description%]" }, "color_mode": { - "name": "Color Mode", + "name": "Color mode", "description": "The ScreenLogic color mode to set." } } }, "start_super_chlorination": { - "name": "Start Super Chlorination", + "name": "Start super chlorination", "description": "Begins super chlorination, running for the specified period or 24 hours if none is specified.", "fields": { "config_entry": { @@ -68,13 +68,13 @@ "description": "[%key:component::screenlogic::common::service_config_entry_description%]" }, "runtime": { - "name": "Run Time", + "name": "Run time", "description": "Number of hours for super chlorination to run." } } }, "stop_super_chlorination": { - "name": "Stop Super Chlorination", + "name": "Stop super chlorination", "description": "Stops super chlorination.", "fields": { "config_entry": { diff --git a/homeassistant/components/screenlogic/switch.py b/homeassistant/components/screenlogic/switch.py index 1d36ee00b94..dfbb1c1781d 100644 --- a/homeassistant/components/screenlogic/switch.py +++ b/homeassistant/components/screenlogic/switch.py @@ -8,7 +8,7 @@ from screenlogicpy.device_const.circuit import GENERIC_CIRCUIT_NAMES, INTERFACE from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LIGHT_CIRCUIT_FUNCTIONS from .entity import ( @@ -29,7 +29,7 @@ class ScreenLogicCircuitSwitchDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ScreenLogicConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" entities: list[ScreenLogicSwitchingEntity] = [] diff --git a/homeassistant/components/season/sensor.py b/homeassistant/components/season/sensor.py index 96744db1d02..bdc24883c90 100644 --- a/homeassistant/components/season/sensor.py +++ b/homeassistant/components/season/sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TYPE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .const import DOMAIN, TYPE_ASTRONOMICAL @@ -37,7 +37,7 @@ HEMISPHERE_SEASON_SWAP = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config entry.""" hemisphere = EQUATOR diff --git a/homeassistant/components/sense/__init__.py b/homeassistant/components/sense/__init__.py index e919d48e96d..a5393181057 100644 --- a/homeassistant/components/sense/__init__.py +++ b/homeassistant/components/sense/__init__.py @@ -89,8 +89,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: SenseConfigEntry) -> boo except SENSE_WEBSOCKET_EXCEPTIONS as err: raise ConfigEntryNotReady(str(err) or "Error during realtime update") from err - trends_coordinator = SenseTrendCoordinator(hass, gateway) - realtime_coordinator = SenseRealtimeCoordinator(hass, gateway) + trends_coordinator = SenseTrendCoordinator(hass, entry, gateway) + realtime_coordinator = SenseRealtimeCoordinator(hass, entry, gateway) # This can take longer than 60s and we already know # sense is online since get_discovered_device_data was diff --git a/homeassistant/components/sense/binary_sensor.py b/homeassistant/components/sense/binary_sensor.py index d06b3a62937..3bb8a32b8e4 100644 --- a/homeassistant/components/sense/binary_sensor.py +++ b/homeassistant/components/sense/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SenseConfigEntry from .const import DOMAIN @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: SenseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sense binary sensor.""" sense_monitor_id = config_entry.runtime_data.data.sense_monitor_id diff --git a/homeassistant/components/sense/coordinator.py b/homeassistant/components/sense/coordinator.py index c0029cd79ea..1957352aea6 100644 --- a/homeassistant/components/sense/coordinator.py +++ b/homeassistant/components/sense/coordinator.py @@ -1,7 +1,10 @@ """Sense Coordinators.""" +from __future__ import annotations + from datetime import timedelta import logging +from typing import TYPE_CHECKING from sense_energy import ( ASyncSenseable, @@ -13,6 +16,9 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import SenseConfigEntry + from .const import ( ACTIVE_UPDATE_RATE, SENSE_CONNECT_EXCEPTIONS, @@ -27,13 +33,21 @@ _LOGGER = logging.getLogger(__name__) class SenseCoordinator(DataUpdateCoordinator[None]): """Sense Trend Coordinator.""" + config_entry: SenseConfigEntry + def __init__( - self, hass: HomeAssistant, gateway: ASyncSenseable, name: str, update: int + self, + hass: HomeAssistant, + config_entry: SenseConfigEntry, + gateway: ASyncSenseable, + name: str, + update: int, ) -> None: """Initialize.""" super().__init__( hass, logger=_LOGGER, + config_entry=config_entry, name=f"Sense {name} {gateway.sense_monitor_id}", update_interval=timedelta(seconds=update), ) @@ -44,9 +58,14 @@ class SenseCoordinator(DataUpdateCoordinator[None]): class SenseTrendCoordinator(SenseCoordinator): """Sense Trend Coordinator.""" - def __init__(self, hass: HomeAssistant, gateway: ASyncSenseable) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: SenseConfigEntry, + gateway: ASyncSenseable, + ) -> None: """Initialize.""" - super().__init__(hass, gateway, "Trends", TREND_UPDATE_RATE) + super().__init__(hass, config_entry, gateway, "Trends", TREND_UPDATE_RATE) async def _async_update_data(self) -> None: """Update the trend data.""" @@ -62,9 +81,14 @@ class SenseTrendCoordinator(SenseCoordinator): class SenseRealtimeCoordinator(SenseCoordinator): """Sense Realtime Coordinator.""" - def __init__(self, hass: HomeAssistant, gateway: ASyncSenseable) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: SenseConfigEntry, + gateway: ASyncSenseable, + ) -> None: """Initialize.""" - super().__init__(hass, gateway, "Realtime", ACTIVE_UPDATE_RATE) + super().__init__(hass, config_entry, gateway, "Realtime", ACTIVE_UPDATE_RATE) async def _async_update_data(self) -> None: """Retrieve latest state.""" diff --git a/homeassistant/components/sense/sensor.py b/homeassistant/components/sense/sensor.py index 2f5c82675d5..8cb4bdd3e56 100644 --- a/homeassistant/components/sense/sensor.py +++ b/homeassistant/components/sense/sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SenseConfigEntry from .const import ( @@ -66,7 +66,7 @@ TREND_SENSOR_VARIANTS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: SenseConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sense sensor.""" data = config_entry.runtime_data.data diff --git a/homeassistant/components/sensibo/binary_sensor.py b/homeassistant/components/sensibo/binary_sensor.py index a66ab46c882..0d6c47ce46c 100644 --- a/homeassistant/components/sensibo/binary_sensor.py +++ b/homeassistant/components/sensibo/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SensiboConfigEntry from .const import LOGGER @@ -118,7 +118,7 @@ DESCRIPTION_BY_MODELS = {"pure": PURE_SENSOR_TYPES} async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo binary sensor platform.""" diff --git a/homeassistant/components/sensibo/button.py b/homeassistant/components/sensibo/button.py index df8d4625840..ed0688d6f2c 100644 --- a/homeassistant/components/sensibo/button.py +++ b/homeassistant/components/sensibo/button.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SensiboConfigEntry from .coordinator import SensiboDataUpdateCoordinator @@ -35,7 +35,7 @@ DEVICE_BUTTON_TYPES = SensiboButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo button platform.""" diff --git a/homeassistant/components/sensibo/climate.py b/homeassistant/components/sensibo/climate.py index 5d1c6ff9e79..2190d121248 100644 --- a/homeassistant/components/sensibo/climate.py +++ b/homeassistant/components/sensibo/climate.py @@ -25,7 +25,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, SupportsResponse from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter from . import SensiboConfigEntry @@ -138,7 +138,7 @@ def _find_valid_target_temp(target: float, valid_targets: list[int]) -> int: async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sensibo climate entry.""" diff --git a/homeassistant/components/sensibo/number.py b/homeassistant/components/sensibo/number.py index aa46c7f8c1e..9d077b308a0 100644 --- a/homeassistant/components/sensibo/number.py +++ b/homeassistant/components/sensibo/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SensiboConfigEntry from .coordinator import SensiboDataUpdateCoordinator @@ -65,7 +65,7 @@ DEVICE_NUMBER_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo number platform.""" diff --git a/homeassistant/components/sensibo/select.py b/homeassistant/components/sensibo/select.py index 51521b59f03..73c0734ef73 100644 --- a/homeassistant/components/sensibo/select.py +++ b/homeassistant/components/sensibo/select.py @@ -17,7 +17,7 @@ from homeassistant.components.select import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import ( IssueSeverity, async_create_issue, @@ -67,7 +67,7 @@ DEVICE_SELECT_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo select platform.""" diff --git a/homeassistant/components/sensibo/sensor.py b/homeassistant/components/sensibo/sensor.py index b242f38febe..4174d4b859b 100644 --- a/homeassistant/components/sensibo/sensor.py +++ b/homeassistant/components/sensibo/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import SensiboConfigEntry @@ -240,7 +240,7 @@ DESCRIPTION_BY_MODELS = { async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo sensor platform.""" diff --git a/homeassistant/components/sensibo/switch.py b/homeassistant/components/sensibo/switch.py index 0bc2c55a706..8c140074e57 100644 --- a/homeassistant/components/sensibo/switch.py +++ b/homeassistant/components/sensibo/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SensiboConfigEntry from .const import DOMAIN @@ -78,7 +78,7 @@ DESCRIPTION_BY_MODELS = {"pure": PURE_SWITCH_TYPES} async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo Switch platform.""" diff --git a/homeassistant/components/sensibo/update.py b/homeassistant/components/sensibo/update.py index 0b02264b3e0..2103bbbf64a 100644 --- a/homeassistant/components/sensibo/update.py +++ b/homeassistant/components/sensibo/update.py @@ -14,7 +14,7 @@ from homeassistant.components.update import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SensiboConfigEntry from .coordinator import SensiboDataUpdateCoordinator @@ -45,7 +45,7 @@ DEVICE_SENSOR_TYPES: tuple[SensiboDeviceUpdateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SensiboConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensibo Update platform.""" diff --git a/homeassistant/components/sensirion_ble/sensor.py b/homeassistant/components/sensirion_ble/sensor.py index a7254fd3609..16f7571f392 100644 --- a/homeassistant/components/sensirion_ble/sensor.py +++ b/homeassistant/components/sensirion_ble/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -106,7 +106,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sensirion BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/sensorpro/sensor.py b/homeassistant/components/sensorpro/sensor.py index b972aac04fb..997fa0db995 100644 --- a/homeassistant/components/sensorpro/sensor.py +++ b/homeassistant/components/sensorpro/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -111,7 +111,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SensorPro BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/sensorpush/sensor.py b/homeassistant/components/sensorpush/sensor.py index 6eea5c10f78..730277350b5 100644 --- a/homeassistant/components/sensorpush/sensor.py +++ b/homeassistant/components/sensorpush/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from . import SensorPushConfigEntry @@ -97,7 +97,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: SensorPushConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SensorPush BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/sensoterra/__init__.py b/homeassistant/components/sensoterra/__init__.py index b1428351f09..1559dc10c43 100644 --- a/homeassistant/components/sensoterra/__init__.py +++ b/homeassistant/components/sensoterra/__init__.py @@ -4,16 +4,13 @@ from __future__ import annotations from sensoterra.customerapi import CustomerApi -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_TOKEN, Platform from homeassistant.core import HomeAssistant -from .coordinator import SensoterraCoordinator +from .coordinator import SensoterraConfigEntry, SensoterraCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -type SensoterraConfigEntry = ConfigEntry[SensoterraCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: SensoterraConfigEntry) -> bool: """Set up Sensoterra platform based on a configuration entry.""" @@ -24,7 +21,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: SensoterraConfigEntry) - api.set_language(hass.config.language) api.set_token(entry.data[CONF_TOKEN]) - coordinator = SensoterraCoordinator(hass, api) + coordinator = SensoterraCoordinator(hass, entry, api) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/sensoterra/coordinator.py b/homeassistant/components/sensoterra/coordinator.py index 2dffdceb443..9020633a2a3 100644 --- a/homeassistant/components/sensoterra/coordinator.py +++ b/homeassistant/components/sensoterra/coordinator.py @@ -10,21 +10,29 @@ from sensoterra.customerapi import ( ) from sensoterra.probe import Probe, Sensor +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import LOGGER, SCAN_INTERVAL_MINUTES +type SensoterraConfigEntry = ConfigEntry[SensoterraCoordinator] + class SensoterraCoordinator(DataUpdateCoordinator[list[Probe]]): """Sensoterra coordinator.""" - def __init__(self, hass: HomeAssistant, api: CustomerApi) -> None: + config_entry: SensoterraConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: SensoterraConfigEntry, api: CustomerApi + ) -> None: """Initialize Sensoterra coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Sensoterra probe", update_interval=timedelta(minutes=SCAN_INTERVAL_MINUTES), ) diff --git a/homeassistant/components/sensoterra/sensor.py b/homeassistant/components/sensoterra/sensor.py index 7e9f4d0840e..56f47ade212 100644 --- a/homeassistant/components/sensoterra/sensor.py +++ b/homeassistant/components/sensoterra/sensor.py @@ -21,13 +21,12 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import SensoterraConfigEntry from .const import CONFIGURATION_URL, DOMAIN, SENSOR_EXPIRATION_DAYS -from .coordinator import SensoterraCoordinator +from .coordinator import SensoterraConfigEntry, SensoterraCoordinator class ProbeSensorType(StrEnum): @@ -85,7 +84,7 @@ SENSORS: dict[ProbeSensorType, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: SensoterraConfigEntry, - async_add_devices: AddEntitiesCallback, + async_add_devices: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sensoterra sensor.""" diff --git a/homeassistant/components/senz/climate.py b/homeassistant/components/senz/climate.py index d5749a3f040..48eeee54974 100644 --- a/homeassistant/components/senz/climate.py +++ b/homeassistant/components/senz/climate.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import SENZDataUpdateCoordinator @@ -26,7 +26,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SENZ climate entities from a config entry.""" coordinator: SENZDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/seventeentrack/sensor.py b/homeassistant/components/seventeentrack/sensor.py index dade9efb67c..b0f9d6cd2bd 100644 --- a/homeassistant/components/seventeentrack/sensor.py +++ b/homeassistant/components/seventeentrack/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_LOCATION from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -28,7 +28,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a 17Track sensor entry.""" diff --git a/homeassistant/components/sfr_box/__init__.py b/homeassistant/components/sfr_box/__init__.py index 927e3cb0ef2..a56d208d515 100644 --- a/homeassistant/components/sfr_box/__init__.py +++ b/homeassistant/components/sfr_box/__init__.py @@ -37,12 +37,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: data = DomainData( box=box, - dsl=SFRDataUpdateCoordinator(hass, box, "dsl", lambda b: b.dsl_get_info()), - ftth=SFRDataUpdateCoordinator(hass, box, "ftth", lambda b: b.ftth_get_info()), - system=SFRDataUpdateCoordinator( - hass, box, "system", lambda b: b.system_get_info() + dsl=SFRDataUpdateCoordinator( + hass, entry, box, "dsl", lambda b: b.dsl_get_info() + ), + ftth=SFRDataUpdateCoordinator( + hass, entry, box, "ftth", lambda b: b.ftth_get_info() + ), + system=SFRDataUpdateCoordinator( + hass, entry, box, "system", lambda b: b.system_get_info() + ), + wan=SFRDataUpdateCoordinator( + hass, entry, box, "wan", lambda b: b.wan_get_info() ), - wan=SFRDataUpdateCoordinator(hass, box, "wan", lambda b: b.wan_get_info()), ) # Preload system information await data.system.async_config_entry_first_refresh() diff --git a/homeassistant/components/sfr_box/binary_sensor.py b/homeassistant/components/sfr_box/binary_sensor.py index 4ef5e87761d..de40291b0b6 100644 --- a/homeassistant/components/sfr_box/binary_sensor.py +++ b/homeassistant/components/sfr_box/binary_sensor.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -62,7 +62,9 @@ WAN_SENSOR_TYPES: tuple[SFRBoxBinarySensorEntityDescription[WanInfo], ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" data: DomainData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sfr_box/button.py b/homeassistant/components/sfr_box/button.py index bddb1e8f926..9798602ef6b 100644 --- a/homeassistant/components/sfr_box/button.py +++ b/homeassistant/components/sfr_box/button.py @@ -21,7 +21,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .models import DomainData @@ -65,7 +65,9 @@ BUTTON_TYPES: tuple[SFRBoxButtonEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the buttons.""" data: DomainData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sfr_box/coordinator.py b/homeassistant/components/sfr_box/coordinator.py index 5877d5a454a..e9cb3c592e1 100644 --- a/homeassistant/components/sfr_box/coordinator.py +++ b/homeassistant/components/sfr_box/coordinator.py @@ -8,6 +8,7 @@ from typing import Any from sfrbox_api.bridge import SFRBox from sfrbox_api.exceptions import SFRBoxError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -18,9 +19,12 @@ _SCAN_INTERVAL = timedelta(minutes=1) class SFRDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT | None]): """Coordinator to manage data updates.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, box: SFRBox, name: str, method: Callable[[SFRBox], Coroutine[Any, Any, _DataT | None]], @@ -28,7 +32,13 @@ class SFRDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT | None]): """Initialize coordinator.""" self.box = box self._method = method - super().__init__(hass, _LOGGER, name=name, update_interval=_SCAN_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=name, + update_interval=_SCAN_INTERVAL, + ) async def _async_update_data(self) -> _DataT | None: """Update data.""" diff --git a/homeassistant/components/sfr_box/sensor.py b/homeassistant/components/sfr_box/sensor.py index ee3285a8f38..8f50b6acd90 100644 --- a/homeassistant/components/sfr_box/sensor.py +++ b/homeassistant/components/sfr_box/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -217,7 +217,9 @@ def _get_temperature(value: float | None) -> float | None: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" data: DomainData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sharkiq/coordinator.py b/homeassistant/components/sharkiq/coordinator.py index 381f6ca1a7d..1a4a819cdf6 100644 --- a/homeassistant/components/sharkiq/coordinator.py +++ b/homeassistant/components/sharkiq/coordinator.py @@ -24,6 +24,8 @@ from .const import API_TIMEOUT, DOMAIN, LOGGER, UPDATE_INTERVAL class SharkIqUpdateCoordinator(DataUpdateCoordinator[bool]): """Define a wrapper class to update Shark IQ data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, @@ -36,10 +38,15 @@ class SharkIqUpdateCoordinator(DataUpdateCoordinator[bool]): self.shark_vacs: dict[str, SharkIqVacuum] = { sharkiq.serial_number: sharkiq for sharkiq in shark_vacs } - self._config_entry = config_entry self._online_dsns: set[str] = set() - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) + super().__init__( + hass, + LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=UPDATE_INTERVAL, + ) @property def online_dsns(self) -> set[str]: diff --git a/homeassistant/components/sharkiq/vacuum.py b/homeassistant/components/sharkiq/vacuum.py index 332d95b0a3e..daea195a770 100644 --- a/homeassistant/components/sharkiq/vacuum.py +++ b/homeassistant/components/sharkiq/vacuum.py @@ -18,7 +18,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, LOGGER, SERVICE_CLEAN_ROOM, SHARK @@ -50,7 +50,7 @@ ATTR_ROOMS = "rooms" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Shark IQ vacuum cleaner.""" coordinator: SharkIqUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/shelly/binary_sensor.py b/homeassistant/components/shelly/binary_sensor.py index fb253c682d8..ed2ac68d264 100644 --- a/homeassistant/components/shelly/binary_sensor.py +++ b/homeassistant/components/shelly/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import CONF_SLEEP_PERIOD @@ -290,7 +290,7 @@ RPC_SENSORS: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/button.py b/homeassistant/components/shelly/button.py index f1e2f8ef885..1f3c555a64b 100644 --- a/homeassistant/components/shelly/button.py +++ b/homeassistant/components/shelly/button.py @@ -18,7 +18,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import slugify @@ -106,7 +106,7 @@ def async_migrate_unique_ids( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set buttons for device.""" entry_data = config_entry.runtime_data diff --git a/homeassistant/components/shelly/climate.py b/homeassistant/components/shelly/climate.py index f1491acdd81..a3ec9be7cb0 100644 --- a/homeassistant/components/shelly/climate.py +++ b/homeassistant/components/shelly/climate.py @@ -27,7 +27,7 @@ from homeassistant.helpers.device_registry import ( CONNECTION_NETWORK_MAC, DeviceInfo, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_registry import RegistryEntry from homeassistant.helpers.restore_state import ExtraStoredData, RestoreEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -56,7 +56,7 @@ from .utils import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: @@ -75,7 +75,7 @@ async def async_setup_entry( @callback def async_setup_climate_entities( - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: ShellyBlockCoordinator, ) -> None: """Set up online climate devices.""" @@ -102,7 +102,7 @@ def async_setup_climate_entities( def async_restore_climate_entities( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: ShellyBlockCoordinator, ) -> None: """Restore sleeping climate devices.""" @@ -124,7 +124,7 @@ def async_restore_climate_entities( def async_setup_rpc_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for RPC device.""" coordinator = config_entry.runtime_data.rpc diff --git a/homeassistant/components/shelly/cover.py b/homeassistant/components/shelly/cover.py index 09e8279bf9b..e9eb5acf161 100644 --- a/homeassistant/components/shelly/cover.py +++ b/homeassistant/components/shelly/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator from .entity import ShellyBlockEntity, ShellyRpcEntity @@ -25,7 +25,7 @@ from .utils import get_device_entry_gen, get_rpc_key_ids async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up covers for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: @@ -38,7 +38,7 @@ async def async_setup_entry( def async_setup_block_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cover for device.""" coordinator = config_entry.runtime_data.block @@ -55,7 +55,7 @@ def async_setup_block_entry( def async_setup_rpc_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for RPC device.""" coordinator = config_entry.runtime_data.rpc diff --git a/homeassistant/components/shelly/event.py b/homeassistant/components/shelly/event.py index 78093bec8aa..bfd705f447a 100644 --- a/homeassistant/components/shelly/event.py +++ b/homeassistant/components/shelly/event.py @@ -18,7 +18,7 @@ from homeassistant.components.event import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -83,7 +83,7 @@ SCRIPT_EVENT: Final = ShellyRpcEventDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" entities: list[ShellyBlockEvent | ShellyRpcEvent] = [] diff --git a/homeassistant/components/shelly/light.py b/homeassistant/components/shelly/light.py index 5d7bad810b4..ce31533b557 100644 --- a/homeassistant/components/shelly/light.py +++ b/homeassistant/components/shelly/light.py @@ -21,7 +21,7 @@ from homeassistant.components.light import ( brightness_supported, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( BLOCK_MAX_TRANSITION_TIME_MS, @@ -53,7 +53,7 @@ from .utils import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lights for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: @@ -66,7 +66,7 @@ async def async_setup_entry( def async_setup_block_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for block device.""" coordinator = config_entry.runtime_data.block @@ -96,7 +96,7 @@ def async_setup_block_entry( def async_setup_rpc_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for RPC device.""" coordinator = config_entry.runtime_data.rpc diff --git a/homeassistant/components/shelly/manifest.json b/homeassistant/components/shelly/manifest.json index 4cfb49b680f..4c9927f515a 100644 --- a/homeassistant/components/shelly/manifest.json +++ b/homeassistant/components/shelly/manifest.json @@ -8,7 +8,7 @@ "integration_type": "device", "iot_class": "local_push", "loggers": ["aioshelly"], - "requirements": ["aioshelly==12.4.1"], + "requirements": ["aioshelly==12.4.2"], "zeroconf": [ { "type": "_http._tcp.local.", diff --git a/homeassistant/components/shelly/number.py b/homeassistant/components/shelly/number.py index 1fc47b23bdb..59716f39c7f 100644 --- a/homeassistant/components/shelly/number.py +++ b/homeassistant/components/shelly/number.py @@ -22,7 +22,7 @@ from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_registry import RegistryEntry from .const import BLU_TRV_TIMEOUT, CONF_SLEEP_PERIOD, LOGGER, VIRTUAL_NUMBER_MODE_MAP @@ -238,7 +238,7 @@ RPC_NUMBERS: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up numbers for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/select.py b/homeassistant/components/shelly/select.py index 0caf4661240..1fb3dfb3447 100644 --- a/homeassistant/components/shelly/select.py +++ b/homeassistant/components/shelly/select.py @@ -13,7 +13,7 @@ from homeassistant.components.select import ( SelectEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ShellyConfigEntry, ShellyRpcCoordinator from .entity import ( @@ -45,7 +45,7 @@ RPC_SELECT_ENTITIES: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up selectors for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index c492fc1de9e..183a1aa06a1 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -35,7 +35,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_registry import RegistryEntry from homeassistant.helpers.typing import StateType @@ -1324,7 +1324,7 @@ RPC_SENSORS: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/switch.py b/homeassistant/components/shelly/switch.py index 8a33dae0938..9b34b2e079b 100644 --- a/homeassistant/components/shelly/switch.py +++ b/homeassistant/components/shelly/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( ) from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant, State, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_registry import RegistryEntry from homeassistant.helpers.restore_state import RestoreEntity @@ -77,7 +77,7 @@ RPC_SCRIPT_SWITCH = RpcSwitchDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: @@ -90,7 +90,7 @@ async def async_setup_entry( def async_setup_block_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for block device.""" coordinator = config_entry.runtime_data.block @@ -142,7 +142,7 @@ def async_setup_block_entry( def async_setup_rpc_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for RPC device.""" coordinator = config_entry.runtime_data.rpc diff --git a/homeassistant/components/shelly/text.py b/homeassistant/components/shelly/text.py index 66e2ee4c715..f64d1252b7e 100644 --- a/homeassistant/components/shelly/text.py +++ b/homeassistant/components/shelly/text.py @@ -13,7 +13,7 @@ from homeassistant.components.text import ( TextEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ShellyConfigEntry from .entity import ( @@ -45,7 +45,7 @@ RPC_TEXT_ENTITIES: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for device.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/update.py b/homeassistant/components/shelly/update.py index f22547acf50..b1aa84b2640 100644 --- a/homeassistant/components/shelly/update.py +++ b/homeassistant/components/shelly/update.py @@ -22,7 +22,7 @@ from homeassistant.components.update import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import CONF_SLEEP_PERIOD, OTA_BEGIN, OTA_ERROR, OTA_PROGRESS, OTA_SUCCESS @@ -104,7 +104,7 @@ RPC_UPDATES: Final = { async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entities for Shelly component.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: diff --git a/homeassistant/components/shelly/valve.py b/homeassistant/components/shelly/valve.py index ea6feaabe69..1829f663b22 100644 --- a/homeassistant/components/shelly/valve.py +++ b/homeassistant/components/shelly/valve.py @@ -15,7 +15,7 @@ from homeassistant.components.valve import ( ValveEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry from .entity import ( @@ -42,7 +42,7 @@ GAS_VALVE = BlockValveDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up valves for device.""" if get_device_entry_gen(config_entry) in BLOCK_GENERATIONS: @@ -53,7 +53,7 @@ async def async_setup_entry( def async_setup_block_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up valve for device.""" coordinator = config_entry.runtime_data.block diff --git a/homeassistant/components/shopping_list/todo.py b/homeassistant/components/shopping_list/todo.py index 82b6cbfc7f5..2952c283082 100644 --- a/homeassistant/components/shopping_list/todo.py +++ b/homeassistant/components/shopping_list/todo.py @@ -11,7 +11,7 @@ from homeassistant.components.todo import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import NoMatchingShoppingListItem, ShoppingData from .const import DOMAIN @@ -20,7 +20,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the shopping_list todo platform.""" shopping_data = hass.data[DOMAIN] diff --git a/homeassistant/components/sia/alarm_control_panel.py b/homeassistant/components/sia/alarm_control_panel.py index 7ea878f538d..bb6a0669a99 100644 --- a/homeassistant/components/sia/alarm_control_panel.py +++ b/homeassistant/components/sia/alarm_control_panel.py @@ -16,7 +16,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_ACCOUNT, CONF_ACCOUNTS, CONF_ZONES, KEY_ALARM, PREVIOUS_STATE from .entity import SIABaseEntity, SIAEntityDescription @@ -69,7 +69,7 @@ ENTITY_DESCRIPTION_ALARM = SIAAlarmControlPanelEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SIA alarm_control_panel(s) from a config entry.""" async_add_entities( diff --git a/homeassistant/components/sia/binary_sensor.py b/homeassistant/components/sia/binary_sensor.py index 4c8e4ca6130..e1b40dc2e55 100644 --- a/homeassistant/components/sia/binary_sensor.py +++ b/homeassistant/components/sia/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, EntityCategory from homeassistant.core import HomeAssistant, State, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_ACCOUNT, @@ -105,7 +105,7 @@ def generate_binary_sensors(entry: ConfigEntry) -> Iterable[SIABinarySensor]: async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SIA binary sensors from a config entry.""" async_add_entities(generate_binary_sensors(entry)) diff --git a/homeassistant/components/simplefin/binary_sensor.py b/homeassistant/components/simplefin/binary_sensor.py index 66d920fb309..af97fe9a394 100644 --- a/homeassistant/components/simplefin/binary_sensor.py +++ b/homeassistant/components/simplefin/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SimpleFinConfigEntry from .entity import SimpleFinEntity @@ -39,7 +39,7 @@ SIMPLEFIN_BINARY_SENSORS: tuple[SimpleFinBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SimpleFinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpleFIN sensors for config entries.""" diff --git a/homeassistant/components/simplefin/sensor.py b/homeassistant/components/simplefin/sensor.py index 51a96bae2be..183a198040b 100644 --- a/homeassistant/components/simplefin/sensor.py +++ b/homeassistant/components/simplefin/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import SimpleFinConfigEntry @@ -55,7 +55,7 @@ SIMPLEFIN_SENSORS: tuple[SimpleFinSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SimpleFinConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpleFIN sensors for config entries.""" diff --git a/homeassistant/components/simplisafe/alarm_control_panel.py b/homeassistant/components/simplisafe/alarm_control_panel.py index 18f2d8ddcd5..c5a1b2bc708 100644 --- a/homeassistant/components/simplisafe/alarm_control_panel.py +++ b/homeassistant/components/simplisafe/alarm_control_panel.py @@ -31,7 +31,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SimpliSafe from .const import ( @@ -103,7 +103,9 @@ WEBSOCKET_EVENTS_TO_LISTEN_FOR = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a SimpliSafe alarm control panel based on a config entry.""" simplisafe = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/simplisafe/binary_sensor.py b/homeassistant/components/simplisafe/binary_sensor.py index 0310e958e6e..e1f69ed8113 100644 --- a/homeassistant/components/simplisafe/binary_sensor.py +++ b/homeassistant/components/simplisafe/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SimpliSafe from .const import DOMAIN, LOGGER @@ -55,7 +55,9 @@ TRIGGERED_SENSOR_TYPES = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpliSafe binary sensors based on a config entry.""" simplisafe = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/simplisafe/button.py b/homeassistant/components/simplisafe/button.py index f0272d09f61..129209354c3 100644 --- a/homeassistant/components/simplisafe/button.py +++ b/homeassistant/components/simplisafe/button.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SimpliSafe from .const import DOMAIN @@ -46,7 +46,9 @@ BUTTON_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpliSafe buttons based on a config entry.""" simplisafe = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/simplisafe/lock.py b/homeassistant/components/simplisafe/lock.py index c610223bff1..9e29bb2051b 100644 --- a/homeassistant/components/simplisafe/lock.py +++ b/homeassistant/components/simplisafe/lock.py @@ -13,7 +13,7 @@ from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SimpliSafe from .const import DOMAIN, LOGGER @@ -31,7 +31,9 @@ WEBSOCKET_EVENTS_TO_LISTEN_FOR = (EVENT_LOCK_LOCKED, EVENT_LOCK_UNLOCKED) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpliSafe locks based on a config entry.""" simplisafe = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/simplisafe/sensor.py b/homeassistant/components/simplisafe/sensor.py index a5f46e87a7c..b82162f0fe7 100644 --- a/homeassistant/components/simplisafe/sensor.py +++ b/homeassistant/components/simplisafe/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SimpliSafe from .const import DOMAIN, LOGGER @@ -22,7 +22,9 @@ from .entity import SimpliSafeEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SimpliSafe freeze sensors based on a config entry.""" simplisafe = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sky_remote/remote.py b/homeassistant/components/sky_remote/remote.py index 05a464f73a6..1ecd6c3716e 100644 --- a/homeassistant/components/sky_remote/remote.py +++ b/homeassistant/components/sky_remote/remote.py @@ -10,7 +10,7 @@ from homeassistant.components.remote import RemoteEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SkyRemoteConfigEntry from .const import DOMAIN @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config: SkyRemoteConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sky remote platform.""" async_add_entities( diff --git a/homeassistant/components/skybell/binary_sensor.py b/homeassistant/components/skybell/binary_sensor.py index 3c2d90b2630..cc42da48b26 100644 --- a/homeassistant/components/skybell/binary_sensor.py +++ b/homeassistant/components/skybell/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .coordinator import SkybellDataUpdateCoordinator @@ -31,7 +31,9 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Skybell binary sensor.""" async_add_entities( diff --git a/homeassistant/components/skybell/camera.py b/homeassistant/components/skybell/camera.py index 683b840debe..4ee873f8350 100644 --- a/homeassistant/components/skybell/camera.py +++ b/homeassistant/components/skybell/camera.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SkybellDataUpdateCoordinator @@ -30,7 +30,9 @@ CAMERA_TYPES: tuple[CameraEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Skybell camera.""" entities = [] diff --git a/homeassistant/components/skybell/light.py b/homeassistant/components/skybell/light.py index cba9e70c848..3f924f68da8 100644 --- a/homeassistant/components/skybell/light.py +++ b/homeassistant/components/skybell/light.py @@ -15,14 +15,16 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import SkybellEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Skybell switch.""" async_add_entities( diff --git a/homeassistant/components/skybell/sensor.py b/homeassistant/components/skybell/sensor.py index 5f0df77ecfa..a67fdae3b35 100644 --- a/homeassistant/components/skybell/sensor.py +++ b/homeassistant/components/skybell/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .entity import DOMAIN, SkybellEntity @@ -88,7 +88,9 @@ SENSOR_TYPES: tuple[SkybellSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Skybell sensor.""" async_add_entities( diff --git a/homeassistant/components/skybell/switch.py b/homeassistant/components/skybell/switch.py index fa4f723573f..858363043ca 100644 --- a/homeassistant/components/skybell/switch.py +++ b/homeassistant/components/skybell/switch.py @@ -7,7 +7,7 @@ from typing import Any, cast from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import SkybellEntity @@ -29,7 +29,9 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SkyBell switch.""" async_add_entities( diff --git a/homeassistant/components/slack/sensor.py b/homeassistant/components/slack/sensor.py index ca8c9830818..042ab00916e 100644 --- a/homeassistant/components/slack/sensor.py +++ b/homeassistant/components/slack/sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import ATTR_SNOOZE, DOMAIN, SLACK_DATA @@ -21,7 +21,7 @@ from .entity import SlackEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Slack select.""" async_add_entities( diff --git a/homeassistant/components/sleepiq/binary_sensor.py b/homeassistant/components/sleepiq/binary_sensor.py index cb56a516b9b..99fff9c49b0 100644 --- a/homeassistant/components/sleepiq/binary_sensor.py +++ b/homeassistant/components/sleepiq/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ICON_EMPTY, ICON_OCCUPIED, IS_IN_BED from .coordinator import SleepIQData, SleepIQDataUpdateCoordinator @@ -18,7 +18,7 @@ from .entity import SleepIQSleeperEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SleepIQ bed binary sensors.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/button.py b/homeassistant/components/sleepiq/button.py index 94b010066c9..74b1bc0789f 100644 --- a/homeassistant/components/sleepiq/button.py +++ b/homeassistant/components/sleepiq/button.py @@ -11,7 +11,7 @@ from asyncsleepiq import SleepIQBed from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SleepIQData @@ -44,7 +44,7 @@ ENTITY_DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sleep number buttons.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/light.py b/homeassistant/components/sleepiq/light.py index 781bd8e600a..542c212df27 100644 --- a/homeassistant/components/sleepiq/light.py +++ b/homeassistant/components/sleepiq/light.py @@ -8,7 +8,7 @@ from asyncsleepiq import SleepIQBed, SleepIQLight from homeassistant.components.light import ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SleepIQData, SleepIQDataUpdateCoordinator @@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SleepIQ bed lights.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/number.py b/homeassistant/components/sleepiq/number.py index 905ceab18bd..53d6c366e46 100644 --- a/homeassistant/components/sleepiq/number.py +++ b/homeassistant/components/sleepiq/number.py @@ -17,7 +17,7 @@ from asyncsleepiq import ( from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ACTUATOR, @@ -138,7 +138,7 @@ NUMBER_DESCRIPTIONS: dict[str, SleepIQNumberEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SleepIQ bed sensors.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/select.py b/homeassistant/components/sleepiq/select.py index 0a09aa4d657..7d059ba6b59 100644 --- a/homeassistant/components/sleepiq/select.py +++ b/homeassistant/components/sleepiq/select.py @@ -13,7 +13,7 @@ from asyncsleepiq import ( from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, FOOT_WARMER from .coordinator import SleepIQData, SleepIQDataUpdateCoordinator @@ -23,7 +23,7 @@ from .entity import SleepIQBedEntity, SleepIQSleeperEntity, sleeper_for_side async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SleepIQ foundation preset select entities.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/sensor.py b/homeassistant/components/sleepiq/sensor.py index 413e8e4d856..ca4fbc186ed 100644 --- a/homeassistant/components/sleepiq/sensor.py +++ b/homeassistant/components/sleepiq/sensor.py @@ -7,7 +7,7 @@ from asyncsleepiq import SleepIQBed, SleepIQSleeper from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, PRESSURE, SLEEP_NUMBER from .coordinator import SleepIQData, SleepIQDataUpdateCoordinator @@ -19,7 +19,7 @@ SENSORS = [PRESSURE, SLEEP_NUMBER] async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SleepIQ bed sensors.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/sleepiq/switch.py b/homeassistant/components/sleepiq/switch.py index 9fc8ca9d20e..8363782c064 100644 --- a/homeassistant/components/sleepiq/switch.py +++ b/homeassistant/components/sleepiq/switch.py @@ -9,7 +9,7 @@ from asyncsleepiq import SleepIQBed from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SleepIQData, SleepIQPauseUpdateCoordinator @@ -19,7 +19,7 @@ from .entity import SleepIQBedEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sleep number switches.""" data: SleepIQData = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/slide_local/button.py b/homeassistant/components/slide_local/button.py index 12474969ca6..3d5de33303d 100644 --- a/homeassistant/components/slide_local/button.py +++ b/homeassistant/components/slide_local/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SlideConfigEntry, SlideCoordinator @@ -25,7 +25,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: SlideConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button for Slide platform.""" diff --git a/homeassistant/components/slide_local/cover.py b/homeassistant/components/slide_local/cover.py index 0e5e647dea8..6bb3f338cb8 100644 --- a/homeassistant/components/slide_local/cover.py +++ b/homeassistant/components/slide_local/cover.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.cover import ATTR_POSITION, CoverDeviceClass, CoverEntity from homeassistant.const import STATE_CLOSED, STATE_CLOSING, STATE_OPENING from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_INVERT_POSITION, DEFAULT_OFFSET from .coordinator import SlideConfigEntry, SlideCoordinator @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SlideConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cover(s) for Slide platform.""" diff --git a/homeassistant/components/slide_local/switch.py b/homeassistant/components/slide_local/switch.py index 8de608b7fc0..e83924c87ee 100644 --- a/homeassistant/components/slide_local/switch.py +++ b/homeassistant/components/slide_local/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SlideConfigEntry, SlideCoordinator @@ -27,7 +27,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: SlideConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch for Slide platform.""" diff --git a/homeassistant/components/slimproto/media_player.py b/homeassistant/components/slimproto/media_player.py index 42c50d21e75..417444961fe 100644 --- a/homeassistant/components/slimproto/media_player.py +++ b/homeassistant/components/slimproto/media_player.py @@ -22,7 +22,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from .const import DEFAULT_NAME, DOMAIN, PLAYER_EVENT @@ -39,7 +39,7 @@ STATE_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SlimProto MediaPlayer(s) from Config Entry.""" slimserver: SlimServer = hass.data[DOMAIN] diff --git a/homeassistant/components/sma/sensor.py b/homeassistant/components/sma/sensor.py index 863f15a9a17..ffef026aaed 100644 --- a/homeassistant/components/sma/sensor.py +++ b/homeassistant/components/sma/sensor.py @@ -27,7 +27,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -838,7 +838,7 @@ SENSOR_ENTITIES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SMA sensors.""" sma_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/smappee/binary_sensor.py b/homeassistant/components/smappee/binary_sensor.py index 86bc225dba1..06dcaa62853 100644 --- a/homeassistant/components/smappee/binary_sensor.py +++ b/homeassistant/components/smappee/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SmappeeConfigEntry from .const import DOMAIN @@ -37,7 +37,7 @@ ICON_MAPPING = { async def async_setup_entry( hass: HomeAssistant, config_entry: SmappeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smappee binary sensor.""" smappee_base = config_entry.runtime_data diff --git a/homeassistant/components/smappee/sensor.py b/homeassistant/components/smappee/sensor.py index 2f9d6443568..759dfb34013 100644 --- a/homeassistant/components/smappee/sensor.py +++ b/homeassistant/components/smappee/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfElectricPotential, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SmappeeConfigEntry from .const import DOMAIN @@ -189,7 +189,7 @@ VOLTAGE_SENSORS: tuple[SmappeeVoltageSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SmappeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smappee sensor.""" smappee_base = config_entry.runtime_data diff --git a/homeassistant/components/smappee/switch.py b/homeassistant/components/smappee/switch.py index bccf816c823..cf2ddea5938 100644 --- a/homeassistant/components/smappee/switch.py +++ b/homeassistant/components/smappee/switch.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SmappeeConfigEntry from .const import DOMAIN @@ -16,7 +16,7 @@ SWITCH_PREFIX = "Switch" async def async_setup_entry( hass: HomeAssistant, config_entry: SmappeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smappee Comfort Plugs.""" smappee_base = config_entry.runtime_data diff --git a/homeassistant/components/smart_meter_texas/sensor.py b/homeassistant/components/smart_meter_texas/sensor.py index 80fc79671b5..c6e18bf43c1 100644 --- a/homeassistant/components/smart_meter_texas/sensor.py +++ b/homeassistant/components/smart_meter_texas/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ADDRESS, UnitOfEnergy from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -30,7 +30,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smart Meter Texas sensors.""" coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA_COORDINATOR] diff --git a/homeassistant/components/smartthings/binary_sensor.py b/homeassistant/components/smartthings/binary_sensor.py index 611473b011d..6b511c86677 100644 --- a/homeassistant/components/smartthings/binary_sensor.py +++ b/homeassistant/components/smartthings/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -48,7 +48,7 @@ ATTRIB_TO_ENTTIY_CATEGORY = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add binary sensors for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/climate.py b/homeassistant/components/smartthings/climate.py index d9535272295..238f8015620 100644 --- a/homeassistant/components/smartthings/climate.py +++ b/homeassistant/components/smartthings/climate.py @@ -26,7 +26,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -100,7 +100,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add climate entities for a config entry.""" ac_capabilities = [ diff --git a/homeassistant/components/smartthings/cover.py b/homeassistant/components/smartthings/cover.py index 55e86bd582e..daf9b0f38f8 100644 --- a/homeassistant/components/smartthings/cover.py +++ b/homeassistant/components/smartthings/cover.py @@ -18,7 +18,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_BATTERY_LEVEL from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -36,7 +36,7 @@ VALUE_TO_STATE = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add covers for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/fan.py b/homeassistant/components/smartthings/fan.py index 61e30589273..1f26a805dcb 100644 --- a/homeassistant/components/smartthings/fan.py +++ b/homeassistant/components/smartthings/fan.py @@ -11,7 +11,7 @@ from pysmartthings import Capability from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -27,7 +27,7 @@ SPEED_RANGE = (1, 3) # off is not included async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add fans for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/light.py b/homeassistant/components/smartthings/light.py index eb7c9af246b..2ee369176cb 100644 --- a/homeassistant/components/smartthings/light.py +++ b/homeassistant/components/smartthings/light.py @@ -20,7 +20,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -29,7 +29,7 @@ from .entity import SmartThingsEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add lights for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/lock.py b/homeassistant/components/smartthings/lock.py index a0ae9e50443..468b7c2083a 100644 --- a/homeassistant/components/smartthings/lock.py +++ b/homeassistant/components/smartthings/lock.py @@ -10,7 +10,7 @@ from pysmartthings import Attribute, Capability from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -29,7 +29,7 @@ ST_LOCK_ATTR_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add locks for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/scene.py b/homeassistant/components/smartthings/scene.py index 9756cef9f04..aa6655b0134 100644 --- a/homeassistant/components/smartthings/scene.py +++ b/homeassistant/components/smartthings/scene.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN @@ -13,7 +13,7 @@ from .const import DATA_BROKERS, DOMAIN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add switches for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smartthings/sensor.py b/homeassistant/components/smartthings/sensor.py index 8bd0421d2bc..3a283bb806b 100644 --- a/homeassistant/components/smartthings/sensor.py +++ b/homeassistant/components/smartthings/sensor.py @@ -2,15 +2,18 @@ from __future__ import annotations -from collections.abc import Sequence -from typing import NamedTuple +from collections.abc import Callable, Mapping, Sequence +from dataclasses import dataclass +from datetime import datetime +from typing import Any from pysmartthings import Attribute, Capability -from pysmartthings.device import DeviceEntity +from pysmartthings.device import DeviceEntity, DeviceStatus from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, + SensorEntityDescription, SensorStateClass, ) from homeassistant.config_entries import ConfigEntry @@ -28,598 +31,715 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity -class Map(NamedTuple): - """Tuple for mapping Smartthings capabilities to Home Assistant sensors.""" - - attribute: str - name: str - default_unit: str | None - device_class: SensorDeviceClass | None - state_class: SensorStateClass | None - entity_category: EntityCategory | None +def power_attributes(status: DeviceStatus) -> dict[str, Any]: + """Return the power attributes.""" + state = {} + for attribute in ("power_consumption_start", "power_consumption_end"): + value = getattr(status, attribute) + if value is not None: + state[attribute] = value + return state -CAPABILITY_TO_SENSORS: dict[str, list[Map]] = { - Capability.activity_lighting_mode: [ - Map( - Attribute.lighting_mode, - "Activity Lighting Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.air_conditioner_mode: [ - Map( - Attribute.air_conditioner_mode, - "Air Conditioner Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.air_quality_sensor: [ - Map( - Attribute.air_quality, - "Air Quality", - "CAQI", - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.alarm: [Map(Attribute.alarm, "Alarm", None, None, None, None)], - Capability.audio_volume: [ - Map(Attribute.volume, "Volume", PERCENTAGE, None, None, None) - ], - Capability.battery: [ - Map( - Attribute.battery, - "Battery", - PERCENTAGE, - SensorDeviceClass.BATTERY, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.body_mass_index_measurement: [ - Map( - Attribute.bmi_measurement, - "Body Mass Index", - f"{UnitOfMass.KILOGRAMS}/{UnitOfArea.SQUARE_METERS}", - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.body_weight_measurement: [ - Map( - Attribute.body_weight_measurement, - "Body Weight", - UnitOfMass.KILOGRAMS, - SensorDeviceClass.WEIGHT, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.carbon_dioxide_measurement: [ - Map( - Attribute.carbon_dioxide, - "Carbon Dioxide Measurement", - CONCENTRATION_PARTS_PER_MILLION, - SensorDeviceClass.CO2, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.carbon_monoxide_detector: [ - Map( - Attribute.carbon_monoxide, - "Carbon Monoxide Detector", - None, - None, - None, - None, - ) - ], - Capability.carbon_monoxide_measurement: [ - Map( - Attribute.carbon_monoxide_level, - "Carbon Monoxide Measurement", - CONCENTRATION_PARTS_PER_MILLION, - SensorDeviceClass.CO, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.dishwasher_operating_state: [ - Map( - Attribute.machine_state, "Dishwasher Machine State", None, None, None, None - ), - Map( - Attribute.dishwasher_job_state, - "Dishwasher Job State", - None, - None, - None, - None, - ), - Map( - Attribute.completion_time, - "Dishwasher Completion Time", - None, - SensorDeviceClass.TIMESTAMP, - None, - None, - ), - ], - Capability.dryer_mode: [ - Map( - Attribute.dryer_mode, - "Dryer Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.dryer_operating_state: [ - Map(Attribute.machine_state, "Dryer Machine State", None, None, None, None), - Map(Attribute.dryer_job_state, "Dryer Job State", None, None, None, None), - Map( - Attribute.completion_time, - "Dryer Completion Time", - None, - SensorDeviceClass.TIMESTAMP, - None, - None, - ), - ], - Capability.dust_sensor: [ - Map( - Attribute.fine_dust_level, - "Fine Dust Level", - None, - None, - SensorStateClass.MEASUREMENT, - None, - ), - Map( - Attribute.dust_level, - "Dust Level", - None, - None, - SensorStateClass.MEASUREMENT, - None, - ), - ], - Capability.energy_meter: [ - Map( - Attribute.energy, - "Energy Meter", - UnitOfEnergy.KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL_INCREASING, - None, - ) - ], - Capability.equivalent_carbon_dioxide_measurement: [ - Map( - Attribute.equivalent_carbon_dioxide_measurement, - "Equivalent Carbon Dioxide Measurement", - CONCENTRATION_PARTS_PER_MILLION, - SensorDeviceClass.CO2, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.formaldehyde_measurement: [ - Map( - Attribute.formaldehyde_level, - "Formaldehyde Measurement", - CONCENTRATION_PARTS_PER_MILLION, - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.gas_meter: [ - Map( - Attribute.gas_meter, - "Gas Meter", - UnitOfEnergy.KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.MEASUREMENT, - None, - ), - Map( - Attribute.gas_meter_calorific, "Gas Meter Calorific", None, None, None, None - ), - Map( - Attribute.gas_meter_time, - "Gas Meter Time", - None, - SensorDeviceClass.TIMESTAMP, - None, - None, - ), - Map( - Attribute.gas_meter_volume, - "Gas Meter Volume", - UnitOfVolume.CUBIC_METERS, - SensorDeviceClass.GAS, - SensorStateClass.MEASUREMENT, - None, - ), - ], - Capability.illuminance_measurement: [ - Map( - Attribute.illuminance, - "Illuminance", - LIGHT_LUX, - SensorDeviceClass.ILLUMINANCE, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.infrared_level: [ - Map( - Attribute.infrared_level, - "Infrared Level", - PERCENTAGE, - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.media_input_source: [ - Map(Attribute.input_source, "Media Input Source", None, None, None, None) - ], - Capability.media_playback_repeat: [ - Map( - Attribute.playback_repeat_mode, - "Media Playback Repeat", - None, - None, - None, - None, - ) - ], - Capability.media_playback_shuffle: [ - Map( - Attribute.playback_shuffle, "Media Playback Shuffle", None, None, None, None - ) - ], - Capability.media_playback: [ - Map(Attribute.playback_status, "Media Playback Status", None, None, None, None) - ], - Capability.odor_sensor: [ - Map(Attribute.odor_level, "Odor Sensor", None, None, None, None) - ], - Capability.oven_mode: [ - Map( - Attribute.oven_mode, - "Oven Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.oven_operating_state: [ - Map(Attribute.machine_state, "Oven Machine State", None, None, None, None), - Map(Attribute.oven_job_state, "Oven Job State", None, None, None, None), - Map(Attribute.completion_time, "Oven Completion Time", None, None, None, None), - ], - Capability.oven_setpoint: [ - Map(Attribute.oven_setpoint, "Oven Set Point", None, None, None, None) - ], - Capability.power_consumption_report: [], - Capability.power_meter: [ - Map( - Attribute.power, - "Power Meter", - UnitOfPower.WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.power_source: [ - Map( - Attribute.power_source, - "Power Source", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.refrigeration_setpoint: [ - Map( - Attribute.refrigeration_setpoint, - "Refrigeration Setpoint", - None, - SensorDeviceClass.TEMPERATURE, - None, - None, - ) - ], - Capability.relative_humidity_measurement: [ - Map( - Attribute.humidity, - "Relative Humidity Measurement", - PERCENTAGE, - SensorDeviceClass.HUMIDITY, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.robot_cleaner_cleaning_mode: [ - Map( - Attribute.robot_cleaner_cleaning_mode, - "Robot Cleaner Cleaning Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.robot_cleaner_movement: [ - Map( - Attribute.robot_cleaner_movement, - "Robot Cleaner Movement", - None, - None, - None, - None, - ) - ], - Capability.robot_cleaner_turbo_mode: [ - Map( - Attribute.robot_cleaner_turbo_mode, - "Robot Cleaner Turbo Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.signal_strength: [ - Map( - Attribute.lqi, - "LQI Signal Strength", - None, - None, - SensorStateClass.MEASUREMENT, - EntityCategory.DIAGNOSTIC, - ), - Map( - Attribute.rssi, - "RSSI Signal Strength", - None, - SensorDeviceClass.SIGNAL_STRENGTH, - SensorStateClass.MEASUREMENT, - EntityCategory.DIAGNOSTIC, - ), - ], - Capability.smoke_detector: [ - Map(Attribute.smoke, "Smoke Detector", None, None, None, None) - ], - Capability.temperature_measurement: [ - Map( - Attribute.temperature, - "Temperature Measurement", - None, - SensorDeviceClass.TEMPERATURE, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.thermostat_cooling_setpoint: [ - Map( - Attribute.cooling_setpoint, - "Thermostat Cooling Setpoint", - None, - SensorDeviceClass.TEMPERATURE, - None, - None, - ) - ], - Capability.thermostat_fan_mode: [ - Map( - Attribute.thermostat_fan_mode, - "Thermostat Fan Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.thermostat_heating_setpoint: [ - Map( - Attribute.heating_setpoint, - "Thermostat Heating Setpoint", - None, - SensorDeviceClass.TEMPERATURE, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.thermostat_mode: [ - Map( - Attribute.thermostat_mode, - "Thermostat Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.thermostat_operating_state: [ - Map( - Attribute.thermostat_operating_state, - "Thermostat Operating State", - None, - None, - None, - None, - ) - ], - Capability.thermostat_setpoint: [ - Map( - Attribute.thermostat_setpoint, - "Thermostat Setpoint", - None, - SensorDeviceClass.TEMPERATURE, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.three_axis: [], - Capability.tv_channel: [ - Map(Attribute.tv_channel, "Tv Channel", None, None, None, None), - Map(Attribute.tv_channel_name, "Tv Channel Name", None, None, None, None), - ], - Capability.tvoc_measurement: [ - Map( - Attribute.tvoc_level, - "Tvoc Measurement", - CONCENTRATION_PARTS_PER_MILLION, - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.ultraviolet_index: [ - Map( - Attribute.ultraviolet_index, - "Ultraviolet Index", - None, - None, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.voltage_measurement: [ - Map( - Attribute.voltage, - "Voltage Measurement", - UnitOfElectricPotential.VOLT, - SensorDeviceClass.VOLTAGE, - SensorStateClass.MEASUREMENT, - None, - ) - ], - Capability.washer_mode: [ - Map( - Attribute.washer_mode, - "Washer Mode", - None, - None, - None, - EntityCategory.DIAGNOSTIC, - ) - ], - Capability.washer_operating_state: [ - Map(Attribute.machine_state, "Washer Machine State", None, None, None, None), - Map(Attribute.washer_job_state, "Washer Job State", None, None, None, None), - Map( - Attribute.completion_time, - "Washer Completion Time", - None, - SensorDeviceClass.TIMESTAMP, - None, - None, - ), - ], +@dataclass(frozen=True, kw_only=True) +class SmartThingsSensorEntityDescription(SensorEntityDescription): + """Describe a SmartThings sensor entity.""" + + value_fn: Callable[[Any], str | float | int | datetime | None] = lambda value: value + extra_state_attributes_fn: Callable[[DeviceStatus], dict[str, Any]] | None = None + unique_id_separator: str = "." + + +CAPABILITY_TO_SENSORS: dict[ + str, dict[str, list[SmartThingsSensorEntityDescription]] +] = { + Capability.activity_lighting_mode: { + Attribute.lighting_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.lighting_mode, + name="Activity Lighting Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.air_conditioner_mode: { + Attribute.air_conditioner_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.air_conditioner_mode, + name="Air Conditioner Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.air_quality_sensor: { + Attribute.air_quality: [ + SmartThingsSensorEntityDescription( + key=Attribute.air_quality, + name="Air Quality", + native_unit_of_measurement="CAQI", + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.alarm: { + Attribute.alarm: [ + SmartThingsSensorEntityDescription( + key=Attribute.alarm, + name="Alarm", + ) + ] + }, + Capability.audio_volume: { + Attribute.volume: [ + SmartThingsSensorEntityDescription( + key=Attribute.volume, + name="Volume", + native_unit_of_measurement=PERCENTAGE, + ) + ] + }, + Capability.battery: { + Attribute.battery: [ + SmartThingsSensorEntityDescription( + key=Attribute.battery, + name="Battery", + native_unit_of_measurement=PERCENTAGE, + device_class=SensorDeviceClass.BATTERY, + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.body_mass_index_measurement: { + Attribute.bmi_measurement: [ + SmartThingsSensorEntityDescription( + key=Attribute.bmi_measurement, + name="Body Mass Index", + native_unit_of_measurement=f"{UnitOfMass.KILOGRAMS}/{UnitOfArea.SQUARE_METERS}", + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.body_weight_measurement: { + Attribute.body_weight_measurement: [ + SmartThingsSensorEntityDescription( + key=Attribute.body_weight_measurement, + name="Body Weight", + native_unit_of_measurement=UnitOfMass.KILOGRAMS, + device_class=SensorDeviceClass.WEIGHT, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.carbon_dioxide_measurement: { + Attribute.carbon_dioxide: [ + SmartThingsSensorEntityDescription( + key=Attribute.carbon_dioxide, + name="Carbon Dioxide", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + device_class=SensorDeviceClass.CO2, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.carbon_monoxide_detector: { + Attribute.carbon_monoxide: [ + SmartThingsSensorEntityDescription( + key=Attribute.carbon_monoxide, + name="Carbon Monoxide Detector", + ) + ] + }, + Capability.carbon_monoxide_measurement: { + Attribute.carbon_monoxide_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.carbon_monoxide_level, + name="Carbon Monoxide Level", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + device_class=SensorDeviceClass.CO, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.dishwasher_operating_state: { + Attribute.machine_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.machine_state, + name="Dishwasher Machine State", + ) + ], + Attribute.dishwasher_job_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.dishwasher_job_state, + name="Dishwasher Job State", + ) + ], + Attribute.completion_time: [ + SmartThingsSensorEntityDescription( + key=Attribute.completion_time, + name="Dishwasher Completion Time", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=dt_util.parse_datetime, + ) + ], + }, + Capability.dryer_mode: { + Attribute.dryer_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.dryer_mode, + name="Dryer Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.dryer_operating_state: { + Attribute.machine_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.machine_state, + name="Dryer Machine State", + ) + ], + Attribute.dryer_job_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.dryer_job_state, + name="Dryer Job State", + ) + ], + Attribute.completion_time: [ + SmartThingsSensorEntityDescription( + key=Attribute.completion_time, + name="Dryer Completion Time", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=dt_util.parse_datetime, + ) + ], + }, + Capability.dust_sensor: { + Attribute.fine_dust_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.fine_dust_level, + name="Fine Dust Level", + state_class=SensorStateClass.MEASUREMENT, + ) + ], + Attribute.dust_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.dust_level, + name="Dust Level", + state_class=SensorStateClass.MEASUREMENT, + ) + ], + }, + Capability.energy_meter: { + Attribute.energy: [ + SmartThingsSensorEntityDescription( + key=Attribute.energy, + name="Energy Meter", + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ) + ] + }, + Capability.equivalent_carbon_dioxide_measurement: { + Attribute.equivalent_carbon_dioxide_measurement: [ + SmartThingsSensorEntityDescription( + key=Attribute.equivalent_carbon_dioxide_measurement, + name="Equivalent Carbon Dioxide Measurement", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + device_class=SensorDeviceClass.CO2, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.formaldehyde_measurement: { + Attribute.formaldehyde_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.formaldehyde_level, + name="Formaldehyde Measurement", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.gas_meter: { + Attribute.gas_meter: [ + SmartThingsSensorEntityDescription( + key=Attribute.gas_meter, + name="Gas Meter", + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.MEASUREMENT, + ) + ], + Attribute.gas_meter_calorific: [ + SmartThingsSensorEntityDescription( + key=Attribute.gas_meter_calorific, + name="Gas Meter Calorific", + ) + ], + Attribute.gas_meter_time: [ + SmartThingsSensorEntityDescription( + key=Attribute.gas_meter_time, + name="Gas Meter Time", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=dt_util.parse_datetime, + ) + ], + Attribute.gas_meter_volume: [ + SmartThingsSensorEntityDescription( + key=Attribute.gas_meter_volume, + name="Gas Meter Volume", + native_unit_of_measurement=UnitOfVolume.CUBIC_METERS, + device_class=SensorDeviceClass.GAS, + state_class=SensorStateClass.MEASUREMENT, + ) + ], + }, + Capability.illuminance_measurement: { + Attribute.illuminance: [ + SmartThingsSensorEntityDescription( + key=Attribute.illuminance, + name="Illuminance", + native_unit_of_measurement=LIGHT_LUX, + device_class=SensorDeviceClass.ILLUMINANCE, + ) + ] + }, + Capability.infrared_level: { + Attribute.infrared_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.infrared_level, + name="Infrared Level", + native_unit_of_measurement=PERCENTAGE, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.media_input_source: { + Attribute.input_source: [ + SmartThingsSensorEntityDescription( + key=Attribute.input_source, + name="Media Input Source", + ) + ] + }, + Capability.media_playback_repeat: { + Attribute.playback_repeat_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.playback_repeat_mode, + name="Media Playback Repeat", + ) + ] + }, + Capability.media_playback_shuffle: { + Attribute.playback_shuffle: [ + SmartThingsSensorEntityDescription( + key=Attribute.playback_shuffle, + name="Media Playback Shuffle", + ) + ] + }, + Capability.media_playback: { + Attribute.playback_status: [ + SmartThingsSensorEntityDescription( + key=Attribute.playback_status, + name="Media Playback Status", + ) + ] + }, + Capability.odor_sensor: { + Attribute.odor_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.odor_level, + name="Odor Sensor", + ) + ] + }, + Capability.oven_mode: { + Attribute.oven_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.oven_mode, + name="Oven Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.oven_operating_state: { + Attribute.machine_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.machine_state, + name="Oven Machine State", + ) + ], + Attribute.oven_job_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.oven_job_state, + name="Oven Job State", + ) + ], + Attribute.completion_time: [ + SmartThingsSensorEntityDescription( + key=Attribute.completion_time, + name="Oven Completion Time", + ) + ], + }, + Capability.oven_setpoint: { + Attribute.oven_setpoint: [ + SmartThingsSensorEntityDescription( + key=Attribute.oven_setpoint, + name="Oven Set Point", + ) + ] + }, + Capability.power_consumption_report: { + Attribute.power_consumption: [ + SmartThingsSensorEntityDescription( + key="energy_meter", + name="energy", + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value_fn=lambda value: ( + val / 1000 if (val := value.get("energy")) is not None else None + ), + ), + SmartThingsSensorEntityDescription( + key="power_meter", + name="power", + state_class=SensorStateClass.MEASUREMENT, + device_class=SensorDeviceClass.POWER, + native_unit_of_measurement=UnitOfPower.WATT, + value_fn=lambda value: value.get("power"), + extra_state_attributes_fn=power_attributes, + ), + SmartThingsSensorEntityDescription( + key="deltaEnergy_meter", + name="deltaEnergy", + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value_fn=lambda value: ( + val / 1000 + if (val := value.get("deltaEnergy")) is not None + else None + ), + ), + SmartThingsSensorEntityDescription( + key="powerEnergy_meter", + name="powerEnergy", + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value_fn=lambda value: ( + val / 1000 + if (val := value.get("powerEnergy")) is not None + else None + ), + ), + SmartThingsSensorEntityDescription( + key="energySaved_meter", + name="energySaved", + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value_fn=lambda value: ( + val / 1000 + if (val := value.get("energySaved")) is not None + else None + ), + ), + ] + }, + Capability.power_meter: { + Attribute.power: [ + SmartThingsSensorEntityDescription( + key=Attribute.power, + name="Power Meter", + native_unit_of_measurement=UnitOfPower.WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.power_source: { + Attribute.power_source: [ + SmartThingsSensorEntityDescription( + key=Attribute.power_source, + name="Power Source", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.refrigeration_setpoint: { + Attribute.refrigeration_setpoint: [ + SmartThingsSensorEntityDescription( + key=Attribute.refrigeration_setpoint, + name="Refrigeration Setpoint", + ) + ] + }, + Capability.relative_humidity_measurement: { + Attribute.humidity: [ + SmartThingsSensorEntityDescription( + key=Attribute.humidity, + name="Relative Humidity", + native_unit_of_measurement=PERCENTAGE, + device_class=SensorDeviceClass.HUMIDITY, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.robot_cleaner_cleaning_mode: { + Attribute.robot_cleaner_cleaning_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.robot_cleaner_cleaning_mode, + name="Robot Cleaner Cleaning Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.robot_cleaner_movement: { + Attribute.robot_cleaner_movement: [ + SmartThingsSensorEntityDescription( + key=Attribute.robot_cleaner_movement, + name="Robot Cleaner Movement", + ) + ] + }, + Capability.robot_cleaner_turbo_mode: { + Attribute.robot_cleaner_turbo_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.robot_cleaner_turbo_mode, + name="Robot Cleaner Turbo Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.signal_strength: { + Attribute.lqi: [ + SmartThingsSensorEntityDescription( + key=Attribute.lqi, + name="LQI Signal Strength", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ) + ], + Attribute.rssi: [ + SmartThingsSensorEntityDescription( + key=Attribute.rssi, + name="RSSI Signal Strength", + device_class=SensorDeviceClass.SIGNAL_STRENGTH, + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + ) + ], + }, + Capability.smoke_detector: { + Attribute.smoke: [ + SmartThingsSensorEntityDescription( + key=Attribute.smoke, + name="Smoke Detector", + ) + ] + }, + Capability.temperature_measurement: { + Attribute.temperature: [ + SmartThingsSensorEntityDescription( + key=Attribute.temperature, + name="Temperature Measurement", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.thermostat_cooling_setpoint: { + Attribute.cooling_setpoint: [ + SmartThingsSensorEntityDescription( + key=Attribute.cooling_setpoint, + name="Thermostat Cooling Setpoint", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + ) + ] + }, + Capability.thermostat_fan_mode: { + Attribute.thermostat_fan_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.thermostat_fan_mode, + name="Thermostat Fan Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.thermostat_heating_setpoint: { + Attribute.heating_setpoint: [ + SmartThingsSensorEntityDescription( + key=Attribute.heating_setpoint, + name="Thermostat Heating Setpoint", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.thermostat_mode: { + Attribute.thermostat_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.thermostat_mode, + name="Thermostat Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.thermostat_operating_state: { + Attribute.thermostat_operating_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.thermostat_operating_state, + name="Thermostat Operating State", + ) + ] + }, + Capability.thermostat_setpoint: { + Attribute.thermostat_setpoint: [ + SmartThingsSensorEntityDescription( + key=Attribute.thermostat_setpoint, + name="Thermostat Setpoint", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.three_axis: { + Attribute.three_axis: [ + SmartThingsSensorEntityDescription( + key="X Coordinate", + name="X Coordinate", + unique_id_separator=" ", + value_fn=lambda value: value[0], + ), + SmartThingsSensorEntityDescription( + key="Y Coordinate", + name="Y Coordinate", + unique_id_separator=" ", + value_fn=lambda value: value[1], + ), + SmartThingsSensorEntityDescription( + key="Z Coordinate", + name="Z Coordinate", + unique_id_separator=" ", + value_fn=lambda value: value[2], + ), + ] + }, + Capability.tv_channel: { + Attribute.tv_channel: [ + SmartThingsSensorEntityDescription( + key=Attribute.tv_channel, + name="Tv Channel", + ) + ], + Attribute.tv_channel_name: [ + SmartThingsSensorEntityDescription( + key=Attribute.tv_channel_name, + name="Tv Channel Name", + ) + ], + }, + Capability.tvoc_measurement: { + Attribute.tvoc_level: [ + SmartThingsSensorEntityDescription( + key=Attribute.tvoc_level, + name="Tvoc Measurement", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.ultraviolet_index: { + Attribute.ultraviolet_index: [ + SmartThingsSensorEntityDescription( + key=Attribute.ultraviolet_index, + name="Ultraviolet Index", + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.voltage_measurement: { + Attribute.voltage: [ + SmartThingsSensorEntityDescription( + key=Attribute.voltage, + name="Voltage Measurement", + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + state_class=SensorStateClass.MEASUREMENT, + ) + ] + }, + Capability.washer_mode: { + Attribute.washer_mode: [ + SmartThingsSensorEntityDescription( + key=Attribute.washer_mode, + name="Washer Mode", + entity_category=EntityCategory.DIAGNOSTIC, + ) + ] + }, + Capability.washer_operating_state: { + Attribute.machine_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.machine_state, + name="Washer Machine State", + ) + ], + Attribute.washer_job_state: [ + SmartThingsSensorEntityDescription( + key=Attribute.washer_job_state, + name="Washer Job State", + ) + ], + Attribute.completion_time: [ + SmartThingsSensorEntityDescription( + key=Attribute.completion_time, + name="Washer Completion Time", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=dt_util.parse_datetime, + ) + ], + }, } UNITS = { "C": UnitOfTemperature.CELSIUS, "F": UnitOfTemperature.FAHRENHEIT, "lux": LIGHT_LUX, + "mG": None, # Three axis sensors never had a unit, so this removes it for now } -THREE_AXIS_NAMES = ["X Coordinate", "Y Coordinate", "Z Coordinate"] -POWER_CONSUMPTION_REPORT_NAMES = [ - "energy", - "power", - "deltaEnergy", - "powerEnergy", - "energySaved", -] - async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add sensors for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] - entities: list[SensorEntity] = [] - for device in broker.devices.values(): - for capability in broker.get_assigned(device.device_id, "sensor"): - if capability == Capability.three_axis: - entities.extend( - [ - SmartThingsThreeAxisSensor(device, index) - for index in range(len(THREE_AXIS_NAMES)) - ] - ) - elif capability == Capability.power_consumption_report: - entities.extend( - [ - SmartThingsPowerConsumptionSensor(device, report_name) - for report_name in POWER_CONSUMPTION_REPORT_NAMES - ] - ) - else: - maps = CAPABILITY_TO_SENSORS[capability] - entities.extend( - [ - SmartThingsSensor( - device, - m.attribute, - m.name, - m.default_unit, - m.device_class, - m.state_class, - m.entity_category, - ) - for m in maps - ] - ) - - if broker.any_assigned(device.device_id, "switch"): - for capability in (Capability.energy_meter, Capability.power_meter): - maps = CAPABILITY_TO_SENSORS[capability] - entities.extend( - [ - SmartThingsSensor( - device, - m.attribute, - m.name, - m.default_unit, - m.device_class, - m.state_class, - m.entity_category, - ) - for m in maps - ] - ) - - async_add_entities(entities) + async_add_entities( + SmartThingsSensor(device, attribute, description) + for device in broker.devices.values() + for capability in broker.get_assigned(device.device_id, "sensor") + for attribute, descriptions in CAPABILITY_TO_SENSORS[capability].items() + for description in descriptions + ) def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None: @@ -632,107 +752,43 @@ def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None: class SmartThingsSensor(SmartThingsEntity, SensorEntity): """Define a SmartThings Sensor.""" + entity_description: SmartThingsSensorEntityDescription + def __init__( self, device: DeviceEntity, attribute: str, - name: str, - default_unit: str | None, - device_class: SensorDeviceClass | None, - state_class: str | None, - entity_category: EntityCategory | None, + entity_description: SmartThingsSensorEntityDescription, ) -> None: """Init the class.""" super().__init__(device) self._attribute = attribute - self._attr_name = f"{device.label} {name}" - self._attr_unique_id = f"{device.device_id}.{attribute}" - self._attr_device_class = device_class - self._default_unit = default_unit - self._attr_state_class = state_class - self._attr_entity_category = entity_category + self._attr_name = f"{device.label} {entity_description.name}" + self._attr_unique_id = f"{device.device_id}{entity_description.unique_id_separator}{entity_description.key}" + self.entity_description = entity_description @property - def native_value(self): + def native_value(self) -> str | float | int | datetime | None: """Return the state of the sensor.""" - value = self._device.status.attributes[self._attribute].value - - if self.device_class != SensorDeviceClass.TIMESTAMP: - return value - - return dt_util.parse_datetime(value) + return self.entity_description.value_fn( + self._device.status.attributes[self._attribute].value + ) @property def native_unit_of_measurement(self): """Return the unit this state is expressed in.""" unit = self._device.status.attributes[self._attribute].unit - return UNITS.get(unit, unit) if unit else self._default_unit - - -class SmartThingsThreeAxisSensor(SmartThingsEntity, SensorEntity): - """Define a SmartThings Three Axis Sensor.""" - - def __init__(self, device, index): - """Init the class.""" - super().__init__(device) - self._index = index - self._attr_name = f"{device.label} {THREE_AXIS_NAMES[index]}" - self._attr_unique_id = f"{device.device_id} {THREE_AXIS_NAMES[index]}" + return ( + UNITS.get(unit, unit) + if unit + else self.entity_description.native_unit_of_measurement + ) @property - def native_value(self): - """Return the state of the sensor.""" - three_axis = self._device.status.attributes[Attribute.three_axis].value - try: - return three_axis[self._index] - except (TypeError, IndexError): - return None - - -class SmartThingsPowerConsumptionSensor(SmartThingsEntity, SensorEntity): - """Define a SmartThings Sensor.""" - - def __init__( - self, - device: DeviceEntity, - report_name: str, - ) -> None: - """Init the class.""" - super().__init__(device) - self.report_name = report_name - self._attr_name = f"{device.label} {report_name}" - self._attr_unique_id = f"{device.device_id}.{report_name}_meter" - if self.report_name == "power": - self._attr_state_class = SensorStateClass.MEASUREMENT - self._attr_device_class = SensorDeviceClass.POWER - self._attr_native_unit_of_measurement = UnitOfPower.WATT - else: - self._attr_state_class = SensorStateClass.TOTAL_INCREASING - self._attr_device_class = SensorDeviceClass.ENERGY - self._attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR - - @property - def native_value(self): - """Return the state of the sensor.""" - value = self._device.status.attributes[Attribute.power_consumption].value - if value is None or value.get(self.report_name) is None: - return None - if self.report_name == "power": - return value[self.report_name] - return value[self.report_name] / 1000 - - @property - def extra_state_attributes(self): - """Return specific state attributes.""" - if self.report_name == "power": - attributes = [ - "power_consumption_start", - "power_consumption_end", - ] - state_attributes = {} - for attribute in attributes: - value = getattr(self._device.status, attribute) - if value is not None: - state_attributes[attribute] = value - return state_attributes + def extra_state_attributes(self) -> Mapping[str, Any] | None: + """Return the state attributes.""" + if self.entity_description.extra_state_attributes_fn: + return self.entity_description.extra_state_attributes_fn( + self._device.status + ) return None diff --git a/homeassistant/components/smartthings/switch.py b/homeassistant/components/smartthings/switch.py index 5cfe4576d6a..7a88ca0c422 100644 --- a/homeassistant/components/smartthings/switch.py +++ b/homeassistant/components/smartthings/switch.py @@ -10,7 +10,7 @@ from pysmartthings import Capability from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_BROKERS, DOMAIN from .entity import SmartThingsEntity @@ -19,7 +19,7 @@ from .entity import SmartThingsEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add switches for a config entry.""" broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] diff --git a/homeassistant/components/smarttub/binary_sensor.py b/homeassistant/components/smarttub/binary_sensor.py index f665f5e61b3..2e8792140b0 100644 --- a/homeassistant/components/smarttub/binary_sensor.py +++ b/homeassistant/components/smarttub/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from .const import ATTR_ERRORS, ATTR_REMINDERS, DOMAIN, SMARTTUB_CONTROLLER @@ -43,7 +43,9 @@ SNOOZE_REMINDER_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor entities for the binary sensors in the tub.""" diff --git a/homeassistant/components/smarttub/climate.py b/homeassistant/components/smarttub/climate.py index 7f3163834e0..f5759f32fa3 100644 --- a/homeassistant/components/smarttub/climate.py +++ b/homeassistant/components/smarttub/climate.py @@ -17,7 +17,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter from .const import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP, DOMAIN, SMARTTUB_CONTROLLER @@ -42,7 +42,9 @@ HVAC_ACTIONS = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate entity for the thermostat in the tub.""" diff --git a/homeassistant/components/smarttub/light.py b/homeassistant/components/smarttub/light.py index 532234f4059..dda936aa56a 100644 --- a/homeassistant/components/smarttub/light.py +++ b/homeassistant/components/smarttub/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_LIGHTS, @@ -28,7 +28,9 @@ from .helpers import get_spa_name async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for any lights in the tub.""" diff --git a/homeassistant/components/smarttub/sensor.py b/homeassistant/components/smarttub/sensor.py index 585e8859432..b2bb1170d09 100644 --- a/homeassistant/components/smarttub/sensor.py +++ b/homeassistant/components/smarttub/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from .const import DOMAIN, SMARTTUB_CONTROLLER @@ -43,7 +43,9 @@ SET_SECONDARY_FILTRATION_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities for the sensors in the tub.""" diff --git a/homeassistant/components/smarttub/switch.py b/homeassistant/components/smarttub/switch.py index 6e1cf9bef2a..2dedad8e18a 100644 --- a/homeassistant/components/smarttub/switch.py +++ b/homeassistant/components/smarttub/switch.py @@ -8,7 +8,7 @@ from smarttub import SpaPump from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import API_TIMEOUT, ATTR_PUMPS, DOMAIN, SMARTTUB_CONTROLLER from .entity import SmartTubEntity @@ -16,7 +16,9 @@ from .helpers import get_spa_name async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch entities for the pumps on the tub.""" diff --git a/homeassistant/components/smarty/binary_sensor.py b/homeassistant/components/smarty/binary_sensor.py index 213cb00d47c..82236a154f0 100644 --- a/homeassistant/components/smarty/binary_sensor.py +++ b/homeassistant/components/smarty/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SmartyConfigEntry, SmartyCoordinator from .entity import SmartyEntity @@ -53,7 +53,7 @@ ENTITIES: tuple[SmartyBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SmartyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smarty Binary Sensor Platform.""" diff --git a/homeassistant/components/smarty/button.py b/homeassistant/components/smarty/button.py index b8e31cf6fc8..78638561088 100644 --- a/homeassistant/components/smarty/button.py +++ b/homeassistant/components/smarty/button.py @@ -11,7 +11,7 @@ from pysmarty2 import Smarty from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SmartyConfigEntry, SmartyCoordinator from .entity import SmartyEntity @@ -38,7 +38,7 @@ ENTITIES: tuple[SmartyButtonDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SmartyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smarty Button Platform.""" diff --git a/homeassistant/components/smarty/fan.py b/homeassistant/components/smarty/fan.py index 2804f14ee15..07dec85ae47 100644 --- a/homeassistant/components/smarty/fan.py +++ b/homeassistant/components/smarty/fan.py @@ -9,7 +9,7 @@ from typing import Any from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -29,7 +29,7 @@ SPEED_RANGE = (1, 3) # off is not included async def async_setup_entry( hass: HomeAssistant, entry: SmartyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smarty Fan Platform.""" diff --git a/homeassistant/components/smarty/sensor.py b/homeassistant/components/smarty/sensor.py index 48b169c104e..fe35f741380 100644 --- a/homeassistant/components/smarty/sensor.py +++ b/homeassistant/components/smarty/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import REVOLUTIONS_PER_MINUTE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .coordinator import SmartyConfigEntry, SmartyCoordinator @@ -85,7 +85,7 @@ ENTITIES: tuple[SmartySensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SmartyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smarty Sensor Platform.""" diff --git a/homeassistant/components/smarty/switch.py b/homeassistant/components/smarty/switch.py index bf5fe80db44..5781bb11680 100644 --- a/homeassistant/components/smarty/switch.py +++ b/homeassistant/components/smarty/switch.py @@ -11,7 +11,7 @@ from pysmarty2 import Smarty from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SmartyConfigEntry, SmartyCoordinator from .entity import SmartyEntity @@ -42,7 +42,7 @@ ENTITIES: tuple[SmartySwitchDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SmartyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Smarty Switch Platform.""" diff --git a/homeassistant/components/smhi/weather.py b/homeassistant/components/smhi/weather.py index 1707afa2fca..a263eeb6174 100644 --- a/homeassistant/components/smhi/weather.py +++ b/homeassistant/components/smhi/weather.py @@ -56,7 +56,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers import aiohttp_client, sun from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.util import Throttle @@ -97,7 +97,7 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=31) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from map location.""" location = config_entry.data diff --git a/homeassistant/components/smlight/__init__.py b/homeassistant/components/smlight/__init__.py index 11c6ffb73fb..8f3e675ef6b 100644 --- a/homeassistant/components/smlight/__init__.py +++ b/homeassistant/components/smlight/__init__.py @@ -2,16 +2,18 @@ from __future__ import annotations -from dataclasses import dataclass - from pysmlight import Api2, Info, Radio -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .coordinator import SmDataUpdateCoordinator, SmFirmwareUpdateCoordinator +from .coordinator import ( + SmConfigEntry, + SmDataUpdateCoordinator, + SmFirmwareUpdateCoordinator, + SmlightData, +) PLATFORMS: list[Platform] = [ Platform.BINARY_SENSOR, @@ -22,25 +24,12 @@ PLATFORMS: list[Platform] = [ ] -@dataclass(kw_only=True) -class SmlightData: - """Coordinator data class.""" - - data: SmDataUpdateCoordinator - firmware: SmFirmwareUpdateCoordinator - - -type SmConfigEntry = ConfigEntry[SmlightData] - - async def async_setup_entry(hass: HomeAssistant, entry: SmConfigEntry) -> bool: """Set up SMLIGHT Zigbee from a config entry.""" client = Api2(host=entry.data[CONF_HOST], session=async_get_clientsession(hass)) - data_coordinator = SmDataUpdateCoordinator(hass, entry.data[CONF_HOST], client) - firmware_coordinator = SmFirmwareUpdateCoordinator( - hass, entry.data[CONF_HOST], client - ) + data_coordinator = SmDataUpdateCoordinator(hass, entry, client) + firmware_coordinator = SmFirmwareUpdateCoordinator(hass, entry, client) await data_coordinator.async_config_entry_first_refresh() await firmware_coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/smlight/binary_sensor.py b/homeassistant/components/smlight/binary_sensor.py index b1aba3a52fe..ce3457ae81b 100644 --- a/homeassistant/components/smlight/binary_sensor.py +++ b/homeassistant/components/smlight/binary_sensor.py @@ -14,13 +14,12 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SCAN_INTERNET_INTERVAL -from .coordinator import SmDataUpdateCoordinator +from .coordinator import SmConfigEntry, SmDataUpdateCoordinator from .entity import SmEntity SCAN_INTERVAL = SCAN_INTERNET_INTERVAL @@ -56,8 +55,8 @@ SENSORS = [ async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: SmConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SMLIGHT sensor based on a config entry.""" coordinator = entry.runtime_data.data diff --git a/homeassistant/components/smlight/button.py b/homeassistant/components/smlight/button.py index d82034b87fb..5caf43b7cba 100644 --- a/homeassistant/components/smlight/button.py +++ b/homeassistant/components/smlight/button.py @@ -14,14 +14,13 @@ from homeassistant.components.button import ( ButtonEntity, ButtonEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN -from .coordinator import SmDataUpdateCoordinator +from .coordinator import SmConfigEntry, SmDataUpdateCoordinator from .entity import SmEntity _LOGGER = logging.getLogger(__name__) @@ -65,8 +64,8 @@ ROUTER = SmButtonDescription( async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + entry: SmConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SMLIGHT buttons based on a config entry.""" coordinator = entry.runtime_data.data diff --git a/homeassistant/components/smlight/coordinator.py b/homeassistant/components/smlight/coordinator.py index 341c627afe5..5a118e7de15 100644 --- a/homeassistant/components/smlight/coordinator.py +++ b/homeassistant/components/smlight/coordinator.py @@ -4,14 +4,14 @@ from __future__ import annotations from abc import abstractmethod from dataclasses import dataclass -from typing import TYPE_CHECKING from pysmlight import Api2, Info, Sensors from pysmlight.const import Settings, SettingsProp from pysmlight.exceptions import SmlightAuthError, SmlightConnectionError from pysmlight.models import FirmwareList -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers import issue_registry as ir @@ -21,8 +21,13 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN, LOGGER, SCAN_FIRMWARE_INTERVAL, SCAN_INTERVAL -if TYPE_CHECKING: - from . import SmConfigEntry + +@dataclass(kw_only=True) +class SmlightData: + """Coordinator data class.""" + + data: SmDataUpdateCoordinator + firmware: SmFirmwareUpdateCoordinator @dataclass @@ -42,17 +47,23 @@ class SmFwData: zb_firmware: list[FirmwareList] +type SmConfigEntry = ConfigEntry[SmlightData] + + class SmBaseDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Base Coordinator for SMLIGHT.""" config_entry: SmConfigEntry - def __init__(self, hass: HomeAssistant, host: str, client: Api2) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: SmConfigEntry, client: Api2 + ) -> None: """Initialize the coordinator.""" super().__init__( hass, LOGGER, - name=f"{DOMAIN}_{host}", + config_entry=config_entry, + name=f"{DOMAIN}_{config_entry.data[CONF_HOST]}", update_interval=SCAN_INTERVAL, ) @@ -133,9 +144,11 @@ class SmDataUpdateCoordinator(SmBaseDataUpdateCoordinator[SmData]): class SmFirmwareUpdateCoordinator(SmBaseDataUpdateCoordinator[SmFwData]): """Class to manage fetching SMLIGHT firmware update data from cloud.""" - def __init__(self, hass: HomeAssistant, host: str, client: Api2) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: SmConfigEntry, client: Api2 + ) -> None: """Initialize the coordinator.""" - super().__init__(hass, host, client) + super().__init__(hass, config_entry, client) self.update_interval = SCAN_FIRMWARE_INTERVAL # only one update can run at a time (core or zibgee) diff --git a/homeassistant/components/smlight/diagnostics.py b/homeassistant/components/smlight/diagnostics.py index d303e5803bb..3812175e673 100644 --- a/homeassistant/components/smlight/diagnostics.py +++ b/homeassistant/components/smlight/diagnostics.py @@ -8,7 +8,7 @@ from pysmlight.const import Actions from homeassistant.core import HomeAssistant -from . import SmConfigEntry +from .coordinator import SmConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/smlight/sensor.py b/homeassistant/components/smlight/sensor.py index 1116b99f8c1..57a08d177d4 100644 --- a/homeassistant/components/smlight/sensor.py +++ b/homeassistant/components/smlight/sensor.py @@ -17,13 +17,12 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import EntityCategory, UnitOfInformation, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow -from . import SmConfigEntry from .const import UPTIME_DEVIATION -from .coordinator import SmDataUpdateCoordinator +from .coordinator import SmConfigEntry, SmDataUpdateCoordinator from .entity import SmEntity @@ -124,7 +123,7 @@ UPTIME: list[SmSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: SmConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SMLIGHT sensor based on a config entry.""" coordinator = entry.runtime_data.data diff --git a/homeassistant/components/smlight/switch.py b/homeassistant/components/smlight/switch.py index 1c591e3dbe8..09d2714956c 100644 --- a/homeassistant/components/smlight/switch.py +++ b/homeassistant/components/smlight/switch.py @@ -17,10 +17,9 @@ from homeassistant.components.switch import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import SmConfigEntry -from .coordinator import SmDataUpdateCoordinator +from .coordinator import SmConfigEntry, SmDataUpdateCoordinator from .entity import SmEntity _LOGGER = logging.getLogger(__name__) @@ -68,7 +67,7 @@ SWITCHES: list[SmSwitchEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, entry: SmConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize switches for SLZB-06 device.""" coordinator = entry.runtime_data.data diff --git a/homeassistant/components/smlight/update.py b/homeassistant/components/smlight/update.py index 50a123345c6..10d142e6221 100644 --- a/homeassistant/components/smlight/update.py +++ b/homeassistant/components/smlight/update.py @@ -20,11 +20,11 @@ from homeassistant.components.update import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import SmConfigEntry, get_radio +from . import get_radio from .const import LOGGER -from .coordinator import SmFirmwareUpdateCoordinator, SmFwData +from .coordinator import SmConfigEntry, SmFirmwareUpdateCoordinator, SmFwData from .entity import SmEntity @@ -62,7 +62,9 @@ ZB_UPDATE_ENTITY = SmUpdateEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: SmConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: SmConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SMLIGHT update entities.""" coordinator = entry.runtime_data.firmware diff --git a/homeassistant/components/sms/sensor.py b/homeassistant/components/sms/sensor.py index 821200f68b1..46ee754a1f1 100644 --- a/homeassistant/components/sms/sensor.py +++ b/homeassistant/components/sms/sensor.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, GATEWAY, NETWORK_COORDINATOR, SIGNAL_COORDINATOR, SMS_GATEWAY @@ -77,7 +77,7 @@ NETWORK_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all device sensors.""" sms_data = hass.data[DOMAIN][SMS_GATEWAY] diff --git a/homeassistant/components/snapcast/__init__.py b/homeassistant/components/snapcast/__init__.py index b853535b525..9c1602494e5 100644 --- a/homeassistant/components/snapcast/__init__.py +++ b/homeassistant/components/snapcast/__init__.py @@ -11,15 +11,14 @@ from .coordinator import SnapcastUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Snapcast from a config entry.""" - host = entry.data[CONF_HOST] - port = entry.data[CONF_PORT] - coordinator = SnapcastUpdateCoordinator(hass, host, port) + coordinator = SnapcastUpdateCoordinator(hass, entry) try: await coordinator.async_config_entry_first_refresh() except OSError as ex: raise ConfigEntryNotReady( - f"Could not connect to Snapcast server at {host}:{port}" + "Could not connect to Snapcast server at " + f"{entry.data[CONF_HOST]}:{entry.data[CONF_PORT]}" ) from ex hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/snapcast/coordinator.py b/homeassistant/components/snapcast/coordinator.py index 5bb9ae4e51f..4c2f0cb81b7 100644 --- a/homeassistant/components/snapcast/coordinator.py +++ b/homeassistant/components/snapcast/coordinator.py @@ -6,6 +6,8 @@ import logging from snapcast.control.server import Snapserver +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -15,15 +17,20 @@ _LOGGER = logging.getLogger(__name__) class SnapcastUpdateCoordinator(DataUpdateCoordinator[None]): """Data update coordinator for pushed data from Snapcast server.""" - def __init__(self, hass: HomeAssistant, host: str, port: int) -> None: + config_entry: ConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize coordinator.""" + host = config_entry.data[CONF_HOST] + port = config_entry.data[CONF_PORT] + super().__init__( hass, logger=_LOGGER, + config_entry=config_entry, name=f"{host}:{port}", update_interval=None, # Disable update interval as server pushes ) - self._server = Snapserver(hass.loop, host, port, True) self.last_update_success = False diff --git a/homeassistant/components/snapcast/media_player.py b/homeassistant/components/snapcast/media_player.py index 0ec27c1ad9c..5f011ca41ee 100644 --- a/homeassistant/components/snapcast/media_player.py +++ b/homeassistant/components/snapcast/media_player.py @@ -25,7 +25,7 @@ from homeassistant.helpers import ( entity_platform, entity_registry as er, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_LATENCY, @@ -73,7 +73,7 @@ def register_services() -> None: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the snapcast config entry.""" diff --git a/homeassistant/components/snooz/fan.py b/homeassistant/components/snooz/fan.py index bfe773b4780..ce804450cab 100644 --- a/homeassistant/components/snooz/fan.py +++ b/homeassistant/components/snooz/fan.py @@ -23,7 +23,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import ( @@ -38,7 +38,9 @@ from .models import SnoozConfigurationData async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Snooz device from a config entry.""" diff --git a/homeassistant/components/solaredge/sensor.py b/homeassistant/components/solaredge/sensor.py index 004335b644b..acb86f875c9 100644 --- a/homeassistant/components/solaredge/sensor.py +++ b/homeassistant/components/solaredge/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -201,7 +201,7 @@ SENSOR_TYPES = [ async def async_setup_entry( hass: HomeAssistant, entry: SolarEdgeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add an solarEdge entry.""" # Add the needed sensors to hass diff --git a/homeassistant/components/solarlog/__init__.py b/homeassistant/components/solarlog/__init__.py index 5937c8a496d..7ad1ec8e547 100644 --- a/homeassistant/components/solarlog/__init__.py +++ b/homeassistant/components/solarlog/__init__.py @@ -2,18 +2,16 @@ import logging -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from .const import CONF_HAS_PWD -from .coordinator import SolarLogCoordinator +from .coordinator import SolarlogConfigEntry, SolarLogCoordinator _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.SENSOR] -type SolarlogConfigEntry = ConfigEntry[SolarLogCoordinator] async def async_setup_entry(hass: HomeAssistant, entry: SolarlogConfigEntry) -> bool: diff --git a/homeassistant/components/solarlog/coordinator.py b/homeassistant/components/solarlog/coordinator.py index bf2bc849111..6292b1332d7 100644 --- a/homeassistant/components/solarlog/coordinator.py +++ b/homeassistant/components/solarlog/coordinator.py @@ -5,7 +5,6 @@ from __future__ import annotations from collections.abc import Callable from datetime import timedelta import logging -from typing import TYPE_CHECKING from urllib.parse import ParseResult, urlparse from solarlog_cli.solarlog_connector import SolarLogConnector @@ -16,6 +15,7 @@ from solarlog_cli.solarlog_exceptions import ( ) from solarlog_cli.solarlog_models import SolarlogData +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -28,30 +28,35 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) -if TYPE_CHECKING: - from . import SolarlogConfigEntry +type SolarlogConfigEntry = ConfigEntry[SolarLogCoordinator] class SolarLogCoordinator(DataUpdateCoordinator[SolarlogData]): """Get and update the latest data.""" - def __init__(self, hass: HomeAssistant, entry: SolarlogConfigEntry) -> None: + config_entry: SolarlogConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: SolarlogConfigEntry) -> None: """Initialize the data object.""" super().__init__( - hass, _LOGGER, name="SolarLog", update_interval=timedelta(seconds=60) + hass, + _LOGGER, + config_entry=config_entry, + name="SolarLog", + update_interval=timedelta(seconds=60), ) self.new_device_callbacks: list[Callable[[int], None]] = [] self._devices_last_update: set[tuple[int, str]] = set() - host_entry = entry.data[CONF_HOST] - password = entry.data.get("password", "") + host_entry = config_entry.data[CONF_HOST] + password = config_entry.data.get("password", "") url = urlparse(host_entry, "http") netloc = url.netloc or url.path path = url.path if url.netloc else "" url = ParseResult("http", netloc, path, *url[3:]) - self.unique_id = entry.entry_id + self.unique_id = config_entry.entry_id self.host = url.geturl() self.solarlog = SolarLogConnector( diff --git a/homeassistant/components/solarlog/diagnostics.py b/homeassistant/components/solarlog/diagnostics.py index 02f6c96edc2..c99222542ea 100644 --- a/homeassistant/components/solarlog/diagnostics.py +++ b/homeassistant/components/solarlog/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant -from . import SolarlogConfigEntry +from .coordinator import SolarlogConfigEntry TO_REDACT = [ CONF_HOST, diff --git a/homeassistant/components/solarlog/sensor.py b/homeassistant/components/solarlog/sensor.py index bcff5d57e1b..c4bb119c006 100644 --- a/homeassistant/components/solarlog/sensor.py +++ b/homeassistant/components/solarlog/sensor.py @@ -21,10 +21,10 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import SolarlogConfigEntry +from .coordinator import SolarlogConfigEntry from .entity import SolarLogCoordinatorEntity, SolarLogInverterEntity @@ -276,7 +276,7 @@ INVERTER_SENSOR_TYPES: tuple[SolarLogInverterSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SolarlogConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add solarlog entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/solax/sensor.py b/homeassistant/components/solax/sensor.py index 6ca0bac0c38..1cdec0389fe 100644 --- a/homeassistant/components/solax/sensor.py +++ b/homeassistant/components/solax/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import SolaxConfigEntry @@ -89,7 +89,7 @@ SENSOR_DESCRIPTIONS: dict[tuple[Units, bool], SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: SolaxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Entry setup.""" api = entry.runtime_data.api diff --git a/homeassistant/components/soma/cover.py b/homeassistant/components/soma/cover.py index e64fee00f16..15aa21b1f48 100644 --- a/homeassistant/components/soma/cover.py +++ b/homeassistant/components/soma/cover.py @@ -14,7 +14,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import API, DEVICES, DOMAIN from .entity import SomaEntity @@ -24,7 +24,7 @@ from .utils import is_api_response_success async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Soma cover platform.""" diff --git a/homeassistant/components/soma/sensor.py b/homeassistant/components/soma/sensor.py index 806886009f3..839f28e9a65 100644 --- a/homeassistant/components/soma/sensor.py +++ b/homeassistant/components/soma/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from .const import API, DEVICES, DOMAIN @@ -18,7 +18,7 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=30) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Soma sensor platform.""" diff --git a/homeassistant/components/somfy_mylink/cover.py b/homeassistant/components/somfy_mylink/cover.py index 8c64e58362b..5b888ea4b96 100644 --- a/homeassistant/components/somfy_mylink/cover.py +++ b/homeassistant/components/somfy_mylink/cover.py @@ -7,7 +7,7 @@ from homeassistant.components.cover import CoverDeviceClass, CoverEntity, CoverS from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .const import ( @@ -29,7 +29,7 @@ MYLINK_COVER_TYPE_TO_DEVICE_CLASS = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Discover and configure Somfy covers.""" reversed_target_ids = config_entry.options.get(CONF_REVERSED_TARGET_IDS, {}) diff --git a/homeassistant/components/sonarr/__init__.py b/homeassistant/components/sonarr/__init__.py index 7718ff799f5..960227ff0da 100644 --- a/homeassistant/components/sonarr/__init__.py +++ b/homeassistant/components/sonarr/__init__.py @@ -67,13 +67,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) entry.async_on_unload(entry.add_update_listener(_async_update_listener)) coordinators: dict[str, SonarrDataUpdateCoordinator[Any]] = { - "upcoming": CalendarDataUpdateCoordinator(hass, host_configuration, sonarr), - "commands": CommandsDataUpdateCoordinator(hass, host_configuration, sonarr), - "diskspace": DiskSpaceDataUpdateCoordinator(hass, host_configuration, sonarr), - "queue": QueueDataUpdateCoordinator(hass, host_configuration, sonarr), - "series": SeriesDataUpdateCoordinator(hass, host_configuration, sonarr), - "status": StatusDataUpdateCoordinator(hass, host_configuration, sonarr), - "wanted": WantedDataUpdateCoordinator(hass, host_configuration, sonarr), + "upcoming": CalendarDataUpdateCoordinator( + hass, entry, host_configuration, sonarr + ), + "commands": CommandsDataUpdateCoordinator( + hass, entry, host_configuration, sonarr + ), + "diskspace": DiskSpaceDataUpdateCoordinator( + hass, entry, host_configuration, sonarr + ), + "queue": QueueDataUpdateCoordinator(hass, entry, host_configuration, sonarr), + "series": SeriesDataUpdateCoordinator(hass, entry, host_configuration, sonarr), + "status": StatusDataUpdateCoordinator(hass, entry, host_configuration, sonarr), + "wanted": WantedDataUpdateCoordinator(hass, entry, host_configuration, sonarr), } # Temporary, until we add diagnostic entities _version = None diff --git a/homeassistant/components/sonarr/coordinator.py b/homeassistant/components/sonarr/coordinator.py index 25fc736212b..a73ef838590 100644 --- a/homeassistant/components/sonarr/coordinator.py +++ b/homeassistant/components/sonarr/coordinator.py @@ -48,6 +48,7 @@ class SonarrDataUpdateCoordinator(DataUpdateCoordinator[SonarrDataT]): def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, host_configuration: PyArrHostConfiguration, api_client: SonarrClient, ) -> None: @@ -55,6 +56,7 @@ class SonarrDataUpdateCoordinator(DataUpdateCoordinator[SonarrDataT]): super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/sonarr/sensor.py b/homeassistant/components/sonarr/sensor.py index fa7d0aa7756..6a0293e455c 100644 --- a/homeassistant/components/sonarr/sensor.py +++ b/homeassistant/components/sonarr/sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -149,7 +149,7 @@ SENSOR_TYPES: dict[str, SonarrSensorEntityDescription[Any]] = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sonarr sensors based on a config entry.""" coordinators: dict[str, SonarrDataUpdateCoordinator[Any]] = hass.data[DOMAIN][ diff --git a/homeassistant/components/songpal/media_player.py b/homeassistant/components/songpal/media_player.py index b4063b09691..3fc75d712a7 100644 --- a/homeassistant/components/songpal/media_player.py +++ b/homeassistant/components/songpal/media_player.py @@ -34,7 +34,10 @@ from homeassistant.helpers import ( entity_platform, ) from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import CONF_ENDPOINT, DOMAIN, ERROR_REQUEST_RETRY, SET_SOUND_SETTING @@ -63,7 +66,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up songpal media player.""" name = config_entry.data[CONF_NAME] diff --git a/homeassistant/components/sonos/binary_sensor.py b/homeassistant/components/sonos/binary_sensor.py index 2c1e8af9961..322beaed092 100644 --- a/homeassistant/components/sonos/binary_sensor.py +++ b/homeassistant/components/sonos/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SONOS_CREATE_BATTERY, SONOS_CREATE_MIC_SENSOR from .entity import SonosEntity @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sonos from a config entry.""" diff --git a/homeassistant/components/sonos/media_player.py b/homeassistant/components/sonos/media_player.py index 8d0917c5dba..0c66484202f 100644 --- a/homeassistant/components/sonos/media_player.py +++ b/homeassistant/components/sonos/media_player.py @@ -46,7 +46,7 @@ from homeassistant.core import HomeAssistant, ServiceCall, SupportsResponse, cal from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform, service from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from . import UnjoinData, media_browser @@ -108,7 +108,7 @@ ATTR_QUEUE_POSITION = "queue_position" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sonos from a config entry.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/sonos/number.py b/homeassistant/components/sonos/number.py index 272218cc01e..c23ba51a877 100644 --- a/homeassistant/components/sonos/number.py +++ b/homeassistant/components/sonos/number.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SONOS_CREATE_LEVELS from .entity import SonosEntity @@ -70,7 +70,7 @@ LEVEL_FROM_NUMBER = {"balance": _balance_from_number} async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Sonos number platform from a config entry.""" diff --git a/homeassistant/components/sonos/sensor.py b/homeassistant/components/sonos/sensor.py index a089c09b33c..d888ee669bb 100644 --- a/homeassistant/components/sonos/sensor.py +++ b/homeassistant/components/sonos/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( SONOS_CREATE_AUDIO_FORMAT_SENSOR, @@ -29,7 +29,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sonos from a config entry.""" diff --git a/homeassistant/components/sonos/switch.py b/homeassistant/components/sonos/switch.py index 4bf5487b1a6..ce4774a4138 100644 --- a/homeassistant/components/sonos/switch.py +++ b/homeassistant/components/sonos/switch.py @@ -15,7 +15,7 @@ from homeassistant.const import ATTR_TIME, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_change from .const import ( @@ -74,7 +74,7 @@ WEEKEND_DAYS = (0, 6) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sonos from a config entry.""" diff --git a/homeassistant/components/soundtouch/media_player.py b/homeassistant/components/soundtouch/media_player.py index 5edd42b931a..c540b8dfd64 100644 --- a/homeassistant/components/soundtouch/media_player.py +++ b/homeassistant/components/soundtouch/media_player.py @@ -27,7 +27,7 @@ from homeassistant.helpers.device_registry import ( DeviceInfo, format_mac, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -47,7 +47,7 @@ ATTR_SOUNDTOUCH_ZONE = "soundtouch_zone" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Bose SoundTouch media player based on a config entry.""" device = hass.data[DOMAIN][entry.entry_id].device diff --git a/homeassistant/components/speedtestdotnet/__init__.py b/homeassistant/components/speedtestdotnet/__init__.py index e4c51ab7aa0..e4f439013c6 100644 --- a/homeassistant/components/speedtestdotnet/__init__.py +++ b/homeassistant/components/speedtestdotnet/__init__.py @@ -6,18 +6,16 @@ from functools import partial import speedtest -from homeassistant.config_entries import ConfigEntry, ConfigEntryState +from homeassistant.config_entries import ConfigEntryState from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.start import async_at_started -from .coordinator import SpeedTestDataCoordinator +from .coordinator import SpeedTestConfigEntry, SpeedTestDataCoordinator PLATFORMS = [Platform.SENSOR] -type SpeedTestConfigEntry = ConfigEntry[SpeedTestDataCoordinator] - async def async_setup_entry( hass: HomeAssistant, config_entry: SpeedTestConfigEntry @@ -49,11 +47,15 @@ async def async_setup_entry( return True -async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_unload_entry( + hass: HomeAssistant, config_entry: SpeedTestConfigEntry +) -> bool: """Unload SpeedTest Entry from config_entry.""" return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) -async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None: +async def update_listener( + hass: HomeAssistant, config_entry: SpeedTestConfigEntry +) -> None: """Handle options update.""" await hass.config_entries.async_reload(config_entry.entry_id) diff --git a/homeassistant/components/speedtestdotnet/config_flow.py b/homeassistant/components/speedtestdotnet/config_flow.py index 3bfd4eb6e4a..4fbca5e0d29 100644 --- a/homeassistant/components/speedtestdotnet/config_flow.py +++ b/homeassistant/components/speedtestdotnet/config_flow.py @@ -9,7 +9,6 @@ import voluptuous as vol from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow from homeassistant.core import callback -from . import SpeedTestConfigEntry from .const import ( CONF_SERVER_ID, CONF_SERVER_NAME, @@ -17,6 +16,7 @@ from .const import ( DEFAULT_SERVER, DOMAIN, ) +from .coordinator import SpeedTestConfigEntry class SpeedTestFlowHandler(ConfigFlow, domain=DOMAIN): diff --git a/homeassistant/components/speedtestdotnet/coordinator.py b/homeassistant/components/speedtestdotnet/coordinator.py index 299652ba0bd..1308cb1d825 100644 --- a/homeassistant/components/speedtestdotnet/coordinator.py +++ b/homeassistant/components/speedtestdotnet/coordinator.py @@ -14,23 +14,28 @@ from .const import CONF_SERVER_ID, DEFAULT_SCAN_INTERVAL, DEFAULT_SERVER, DOMAIN _LOGGER = logging.getLogger(__name__) +type SpeedTestConfigEntry = ConfigEntry[SpeedTestDataCoordinator] + class SpeedTestDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Get the latest data from speedtest.net.""" - config_entry: ConfigEntry + config_entry: SpeedTestConfigEntry def __init__( - self, hass: HomeAssistant, config_entry: ConfigEntry, api: speedtest.Speedtest + self, + hass: HomeAssistant, + config_entry: SpeedTestConfigEntry, + api: speedtest.Speedtest, ) -> None: """Initialize the data object.""" self.hass = hass - self.config_entry = config_entry self.api = api self.servers: dict[str, dict] = {DEFAULT_SERVER: {}} super().__init__( self.hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(minutes=DEFAULT_SCAN_INTERVAL), ) diff --git a/homeassistant/components/speedtestdotnet/sensor.py b/homeassistant/components/speedtestdotnet/sensor.py index 10da1dc93af..c2b7a6de28c 100644 --- a/homeassistant/components/speedtestdotnet/sensor.py +++ b/homeassistant/components/speedtestdotnet/sensor.py @@ -15,11 +15,10 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfDataRate, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import SpeedTestConfigEntry from .const import ( ATTR_BYTES_RECEIVED, ATTR_BYTES_SENT, @@ -30,7 +29,7 @@ from .const import ( DEFAULT_NAME, DOMAIN, ) -from .coordinator import SpeedTestDataCoordinator +from .coordinator import SpeedTestConfigEntry, SpeedTestDataCoordinator @dataclass(frozen=True) @@ -70,7 +69,7 @@ SENSOR_TYPES: tuple[SpeedtestSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SpeedTestConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Speedtestdotnet sensors.""" speedtest_coordinator = config_entry.runtime_data diff --git a/homeassistant/components/spotify/__init__.py b/homeassistant/components/spotify/__init__.py index 663b3f30caa..1c4ea961ce3 100644 --- a/homeassistant/components/spotify/__init__.py +++ b/homeassistant/components/spotify/__init__.py @@ -8,7 +8,6 @@ from typing import TYPE_CHECKING import aiohttp from spotifyaio import Device, SpotifyClient, SpotifyConnectionError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ACCESS_TOKEN, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady @@ -63,7 +62,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> b spotify.refresh_token_function = _refresh_token - coordinator = SpotifyCoordinator(hass, spotify) + coordinator = SpotifyCoordinator(hass, entry, spotify) await coordinator.async_config_entry_first_refresh() @@ -92,6 +91,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> b return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> bool: """Unload Spotify config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/spotify/coordinator.py b/homeassistant/components/spotify/coordinator.py index 8b8539d715a..2d5fffebb7b 100644 --- a/homeassistant/components/spotify/coordinator.py +++ b/homeassistant/components/spotify/coordinator.py @@ -56,11 +56,17 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]): current_user: UserProfile config_entry: SpotifyConfigEntry - def __init__(self, hass: HomeAssistant, client: SpotifyClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: SpotifyConfigEntry, + client: SpotifyClient, + ) -> None: """Initialize.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=UPDATE_INTERVAL, ) diff --git a/homeassistant/components/spotify/media_player.py b/homeassistant/components/spotify/media_player.py index 20a634efb42..d6265cbc39d 100644 --- a/homeassistant/components/spotify/media_player.py +++ b/homeassistant/components/spotify/media_player.py @@ -31,7 +31,7 @@ from homeassistant.components.media_player import ( RepeatMode, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .browse_media import async_browse_media_internal @@ -70,7 +70,7 @@ AFTER_REQUEST_SLEEP = 1 async def async_setup_entry( hass: HomeAssistant, entry: SpotifyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Spotify based on a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/sql/sensor.py b/homeassistant/components/sql/sensor.py index 312b0cd345e..a7b488dd521 100644 --- a/homeassistant/components/sql/sensor.py +++ b/homeassistant/components/sql/sensor.py @@ -36,7 +36,10 @@ from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import TemplateError from homeassistant.helpers import issue_registry as ir from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.template import Template from homeassistant.helpers.trigger_template_entity import ( CONF_AVAILABILITY, @@ -101,7 +104,9 @@ async def async_setup_platform( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SQL sensor from config entry.""" @@ -178,7 +183,7 @@ async def async_setup_sensor( unique_id: str | None, db_url: str, yaml: bool, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback, ) -> None: """Set up the SQL sensor.""" try: diff --git a/homeassistant/components/squeezebox/__init__.py b/homeassistant/components/squeezebox/__init__.py index f94ea118c6a..789f6ddb3a8 100644 --- a/homeassistant/components/squeezebox/__init__.py +++ b/homeassistant/components/squeezebox/__init__.py @@ -127,7 +127,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: SqueezeboxConfigEntry) - ) _LOGGER.debug("LMS Device %s", device) - server_coordinator = LMSStatusDataUpdateCoordinator(hass, lms) + server_coordinator = LMSStatusDataUpdateCoordinator(hass, entry, lms) entry.runtime_data = SqueezeboxData( coordinator=server_coordinator, @@ -151,7 +151,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: SqueezeboxConfigEntry) - else: _LOGGER.debug("Adding new entity: %s", player) player_coordinator = SqueezeBoxPlayerUpdateCoordinator( - hass, player, lms.uuid + hass, entry, player, lms.uuid ) known_players.append(player.player_id) async_dispatcher_send( diff --git a/homeassistant/components/squeezebox/binary_sensor.py b/homeassistant/components/squeezebox/binary_sensor.py index ec0bac0fe43..daae8703597 100644 --- a/homeassistant/components/squeezebox/binary_sensor.py +++ b/homeassistant/components/squeezebox/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SqueezeboxConfigEntry from .const import STATUS_SENSOR_NEEDSRESTART, STATUS_SENSOR_RESCAN @@ -35,7 +35,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: SqueezeboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Platform setup using common elements.""" diff --git a/homeassistant/components/squeezebox/coordinator.py b/homeassistant/components/squeezebox/coordinator.py index f3aacbc9833..955e2896947 100644 --- a/homeassistant/components/squeezebox/coordinator.py +++ b/homeassistant/components/squeezebox/coordinator.py @@ -1,11 +1,13 @@ """DataUpdateCoordinator for the Squeezebox integration.""" +from __future__ import annotations + from asyncio import timeout from collections.abc import Callable from datetime import timedelta import logging import re -from typing import Any +from typing import TYPE_CHECKING, Any from pysqueezebox import Player, Server @@ -14,6 +16,9 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util +if TYPE_CHECKING: + from . import SqueezeboxConfigEntry + from .const import ( PLAYER_UPDATE_INTERVAL, SENSOR_UPDATE_INTERVAL, @@ -30,11 +35,16 @@ _LOGGER = logging.getLogger(__name__) class LMSStatusDataUpdateCoordinator(DataUpdateCoordinator): """LMS Status custom coordinator.""" - def __init__(self, hass: HomeAssistant, lms: Server) -> None: + config_entry: SqueezeboxConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: SqueezeboxConfigEntry, lms: Server + ) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=lms.name, update_interval=timedelta(seconds=SENSOR_UPDATE_INTERVAL), always_update=False, @@ -80,11 +90,20 @@ class LMSStatusDataUpdateCoordinator(DataUpdateCoordinator): class SqueezeBoxPlayerUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Coordinator for Squeezebox players.""" - def __init__(self, hass: HomeAssistant, player: Player, server_uuid: str) -> None: + config_entry: SqueezeboxConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: SqueezeboxConfigEntry, + player: Player, + server_uuid: str, + ) -> None: """Initialize the coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=player.name, update_interval=timedelta(seconds=PLAYER_UPDATE_INTERVAL), always_update=True, diff --git a/homeassistant/components/squeezebox/media_player.py b/homeassistant/components/squeezebox/media_player.py index 19cd1e36910..1b810019373 100644 --- a/homeassistant/components/squeezebox/media_player.py +++ b/homeassistant/components/squeezebox/media_player.py @@ -40,7 +40,7 @@ from homeassistant.helpers.device_registry import ( format_mac, ) from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.start import async_at_start from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utcnow @@ -113,7 +113,7 @@ async def start_server_discovery(hass: HomeAssistant) -> None: async def async_setup_entry( hass: HomeAssistant, entry: SqueezeboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Squeezebox media_player platform from a server config entry.""" diff --git a/homeassistant/components/squeezebox/sensor.py b/homeassistant/components/squeezebox/sensor.py index 0ca33179f9f..c0a7a37d539 100644 --- a/homeassistant/components/squeezebox/sensor.py +++ b/homeassistant/components/squeezebox/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import SqueezeboxConfigEntry @@ -73,7 +73,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: SqueezeboxConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Platform setup using common elements.""" diff --git a/homeassistant/components/srp_energy/__init__.py b/homeassistant/components/srp_energy/__init__.py index 591ba5043e9..13c21709445 100644 --- a/homeassistant/components/srp_energy/__init__.py +++ b/homeassistant/components/srp_energy/__init__.py @@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant -from .const import CONF_IS_TOU, DOMAIN, LOGGER +from .const import DOMAIN, LOGGER from .coordinator import SRPEnergyDataUpdateCoordinator PLATFORMS = [Platform.SENSOR] @@ -26,9 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: api_password, ) - coordinator = SRPEnergyDataUpdateCoordinator( - hass, api_instance, entry.data[CONF_IS_TOU] - ) + coordinator = SRPEnergyDataUpdateCoordinator(hass, entry, api_instance) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/srp_energy/coordinator.py b/homeassistant/components/srp_energy/coordinator.py index e5a72457433..f3821891afa 100644 --- a/homeassistant/components/srp_energy/coordinator.py +++ b/homeassistant/components/srp_energy/coordinator.py @@ -12,7 +12,13 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util -from .const import DOMAIN, LOGGER, MIN_TIME_BETWEEN_UPDATES, PHOENIX_TIME_ZONE +from .const import ( + CONF_IS_TOU, + DOMAIN, + LOGGER, + MIN_TIME_BETWEEN_UPDATES, + PHOENIX_TIME_ZONE, +) TIMEOUT = 10 PHOENIX_ZONE_INFO = dt_util.get_time_zone(PHOENIX_TIME_ZONE) @@ -24,14 +30,15 @@ class SRPEnergyDataUpdateCoordinator(DataUpdateCoordinator[float]): config_entry: ConfigEntry def __init__( - self, hass: HomeAssistant, client: SrpEnergyClient, is_time_of_use: bool + self, hass: HomeAssistant, config_entry: ConfigEntry, client: SrpEnergyClient ) -> None: """Initialize the srp_energy data coordinator.""" self._client = client - self._is_time_of_use = is_time_of_use + self._is_time_of_use = config_entry.data[CONF_IS_TOU] super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=MIN_TIME_BETWEEN_UPDATES, ) diff --git a/homeassistant/components/srp_energy/sensor.py b/homeassistant/components/srp_energy/sensor.py index a9f5c25d6a5..89274390411 100644 --- a/homeassistant/components/srp_energy/sensor.py +++ b/homeassistant/components/srp_energy/sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -20,7 +20,9 @@ from .const import DEVICE_CONFIG_URL, DEVICE_MANUFACTURER, DEVICE_MODEL, DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SRP Energy Usage sensor.""" coordinator: SRPEnergyDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/binary_sensor.py b/homeassistant/components/starline/binary_sensor.py index ac1ad4f2b6e..a570b26a0d1 100644 --- a/homeassistant/components/starline/binary_sensor.py +++ b/homeassistant/components/starline/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .account import StarlineAccount, StarlineDevice from .const import DOMAIN @@ -70,7 +70,9 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the StarLine sensors.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/button.py b/homeassistant/components/starline/button.py index 6fb307cda74..fa46d2a3773 100644 --- a/homeassistant/components/starline/button.py +++ b/homeassistant/components/starline/button.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .account import StarlineAccount, StarlineDevice from .const import DOMAIN @@ -34,7 +34,9 @@ BUTTON_TYPES: tuple[ButtonEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the StarLine button.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/device_tracker.py b/homeassistant/components/starline/device_tracker.py index 610317b72c3..0c8418d28fc 100644 --- a/homeassistant/components/starline/device_tracker.py +++ b/homeassistant/components/starline/device_tracker.py @@ -3,7 +3,7 @@ from homeassistant.components.device_tracker import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .account import StarlineAccount, StarlineDevice @@ -12,7 +12,9 @@ from .entity import StarlineEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up StarLine entry.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/lock.py b/homeassistant/components/starline/lock.py index 19aad1a19b2..43886d63962 100644 --- a/homeassistant/components/starline/lock.py +++ b/homeassistant/components/starline/lock.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .account import StarlineAccount, StarlineDevice from .const import DOMAIN @@ -15,7 +15,9 @@ from .entity import StarlineEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the StarLine lock.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/sensor.py b/homeassistant/components/starline/sensor.py index f9bd304c1e1..16988f1a9dc 100644 --- a/homeassistant/components/starline/sensor.py +++ b/homeassistant/components/starline/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level, icon_for_signal_level from .account import StarlineAccount, StarlineDevice @@ -87,7 +87,9 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the StarLine sensors.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starline/switch.py b/homeassistant/components/starline/switch.py index eb71f0b73b5..79d4fa86ddf 100644 --- a/homeassistant/components/starline/switch.py +++ b/homeassistant/components/starline/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .account import StarlineAccount, StarlineDevice from .const import DOMAIN @@ -34,7 +34,9 @@ SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the StarLine switch.""" account: StarlineAccount = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/__init__.py b/homeassistant/components/starlink/__init__.py index 17081a7491e..4528a35858c 100644 --- a/homeassistant/components/starlink/__init__.py +++ b/homeassistant/components/starlink/__init__.py @@ -3,7 +3,7 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_IP_ADDRESS, Platform +from homeassistant.const import Platform from homeassistant.core import HomeAssistant from .const import DOMAIN @@ -21,11 +21,7 @@ PLATFORMS = [ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Starlink from a config entry.""" - coordinator = StarlinkUpdateCoordinator( - hass=hass, - url=entry.data[CONF_IP_ADDRESS], - name=entry.title, - ) + coordinator = StarlinkUpdateCoordinator(hass, entry) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/starlink/binary_sensor.py b/homeassistant/components/starlink/binary_sensor.py index b03648e81c5..f5eaf2baba0 100644 --- a/homeassistant/components/starlink/binary_sensor.py +++ b/homeassistant/components/starlink/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import StarlinkData @@ -21,7 +21,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all binary sensors for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/button.py b/homeassistant/components/starlink/button.py index f8f18763d30..dc23e31d8d2 100644 --- a/homeassistant/components/starlink/button.py +++ b/homeassistant/components/starlink/button.py @@ -13,7 +13,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import StarlinkUpdateCoordinator @@ -21,7 +21,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all binary sensors for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/coordinator.py b/homeassistant/components/starlink/coordinator.py index 6fcfd8e0bfe..4ae771c9582 100644 --- a/homeassistant/components/starlink/coordinator.py +++ b/homeassistant/components/starlink/coordinator.py @@ -26,6 +26,8 @@ from starlink_grpc import ( status_data, ) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_IP_ADDRESS from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -49,15 +51,18 @@ class StarlinkData: class StarlinkUpdateCoordinator(DataUpdateCoordinator[StarlinkData]): """Coordinates updates between all Starlink sensors defined in this file.""" - def __init__(self, hass: HomeAssistant, name: str, url: str) -> None: + config_entry: ConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize an UpdateCoordinator for a group of sensors.""" - self.channel_context = ChannelContext(target=url) + self.channel_context = ChannelContext(target=config_entry.data[CONF_IP_ADDRESS]) self.history_stats_start = None self.timezone = ZoneInfo(hass.config.time_zone) super().__init__( hass, _LOGGER, - name=name, + config_entry=config_entry, + name=config_entry.title, update_interval=timedelta(seconds=5), ) diff --git a/homeassistant/components/starlink/device_tracker.py b/homeassistant/components/starlink/device_tracker.py index 5174be19760..53e7ab1cee0 100644 --- a/homeassistant/components/starlink/device_tracker.py +++ b/homeassistant/components/starlink/device_tracker.py @@ -10,7 +10,7 @@ from homeassistant.components.device_tracker import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_ALTITUDE, DOMAIN from .coordinator import StarlinkData @@ -18,7 +18,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all binary sensors for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/sensor.py b/homeassistant/components/starlink/sensor.py index 5481e310fbd..dadbf8a061a 100644 --- a/homeassistant/components/starlink/sensor.py +++ b/homeassistant/components/starlink/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import now @@ -34,7 +34,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all sensors for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/switch.py b/homeassistant/components/starlink/switch.py index 3534748127e..51603850690 100644 --- a/homeassistant/components/starlink/switch.py +++ b/homeassistant/components/starlink/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import StarlinkData, StarlinkUpdateCoordinator @@ -21,7 +21,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all binary sensors for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/starlink/time.py b/homeassistant/components/starlink/time.py index 7395ec101ba..3540123e1eb 100644 --- a/homeassistant/components/starlink/time.py +++ b/homeassistant/components/starlink/time.py @@ -11,7 +11,7 @@ from homeassistant.components.time import TimeEntity, TimeEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import StarlinkData, StarlinkUpdateCoordinator @@ -19,7 +19,9 @@ from .entity import StarlinkEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all time entities for this entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/statistics/sensor.py b/homeassistant/components/statistics/sensor.py index 5252c23fd3d..a5c5f10ecd0 100644 --- a/homeassistant/components/statistics/sensor.py +++ b/homeassistant/components/statistics/sensor.py @@ -47,7 +47,10 @@ from homeassistant.core import ( ) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device import async_device_info_to_link_from_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import ( async_track_point_in_utc_time, async_track_state_change_event, @@ -617,7 +620,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Statistics sensor entry.""" sampling_size = entry.options.get(CONF_SAMPLES_MAX_BUFFER_SIZE) diff --git a/homeassistant/components/steam_online/sensor.py b/homeassistant/components/steam_online/sensor.py index 625a8b95979..c1e20933185 100644 --- a/homeassistant/components/steam_online/sensor.py +++ b/homeassistant/components/steam_online/sensor.py @@ -8,7 +8,7 @@ from typing import cast from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utc_from_timestamp @@ -29,7 +29,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: SteamConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Steam platform.""" async_add_entities( diff --git a/homeassistant/components/steamist/sensor.py b/homeassistant/components/steamist/sensor.py index 7c24d015513..94e3ff86ee1 100644 --- a/homeassistant/components/steamist/sensor.py +++ b/homeassistant/components/steamist/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SteamistDataUpdateCoordinator @@ -58,7 +58,7 @@ SENSORS: tuple[SteamistSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" coordinator: SteamistDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/steamist/switch.py b/homeassistant/components/steamist/switch.py index 91806f4fa0c..17e1d6d47ac 100644 --- a/homeassistant/components/steamist/switch.py +++ b/homeassistant/components/steamist/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SteamistDataUpdateCoordinator @@ -22,7 +22,7 @@ ACTIVE_SWITCH = SwitchEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" coordinator: SteamistDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/stookwijzer/sensor.py b/homeassistant/components/stookwijzer/sensor.py index 2660ff2ddb2..91224b711be 100644 --- a/homeassistant/components/stookwijzer/sensor.py +++ b/homeassistant/components/stookwijzer/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfSpeed from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -59,7 +59,7 @@ STOOKWIJZER_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: StookwijzerConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Stookwijzer sensor from a config entry.""" async_add_entities( diff --git a/homeassistant/components/streamlabswater/binary_sensor.py b/homeassistant/components/streamlabswater/binary_sensor.py index 5a0073c25d3..e3e966edde0 100644 --- a/homeassistant/components/streamlabswater/binary_sensor.py +++ b/homeassistant/components/streamlabswater/binary_sensor.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import StreamlabsCoordinator from .const import DOMAIN @@ -15,7 +15,7 @@ from .entity import StreamlabsWaterEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Streamlabs water binary sensor from a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/streamlabswater/sensor.py b/homeassistant/components/streamlabswater/sensor.py index 412b2187495..dea3f081326 100644 --- a/homeassistant/components/streamlabswater/sensor.py +++ b/homeassistant/components/streamlabswater/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfVolume from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import StreamlabsCoordinator @@ -60,7 +60,7 @@ SENSORS: tuple[StreamlabsWaterSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Streamlabs water sensor from a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/subaru/device_tracker.py b/homeassistant/components/subaru/device_tracker.py index d406234c36e..6bcca848ef2 100644 --- a/homeassistant/components/subaru/device_tracker.py +++ b/homeassistant/components/subaru/device_tracker.py @@ -9,7 +9,7 @@ from subarulink.const import LATITUDE, LONGITUDE, TIMESTAMP from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -29,7 +29,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru device tracker by config_entry.""" entry: dict = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/subaru/lock.py b/homeassistant/components/subaru/lock.py index e21102f0b0c..07caa0d6367 100644 --- a/homeassistant/components/subaru/lock.py +++ b/homeassistant/components/subaru/lock.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import SERVICE_LOCK, SERVICE_UNLOCK from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, get_device_info from .const import ( @@ -32,7 +32,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru locks by config_entry.""" entry = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/subaru/sensor.py b/homeassistant/components/subaru/sensor.py index ba9b7d46b06..aa4c4ee16be 100644 --- a/homeassistant/components/subaru/sensor.py +++ b/homeassistant/components/subaru/sensor.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfLength, UnitOfPressure, UnitOfVolume from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -141,7 +141,7 @@ EV_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru sensors by config_entry.""" entry = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/suez_water/sensor.py b/homeassistant/components/suez_water/sensor.py index 1152ebd551b..a162cc6168d 100644 --- a/homeassistant/components/suez_water/sensor.py +++ b/homeassistant/components/suez_water/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import CURRENCY_EURO, UnitOfVolume from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_COUNTER_ID, DOMAIN @@ -53,7 +53,7 @@ SENSORS: tuple[SuezWaterSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SuezWaterConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Suez Water sensor from a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/sun/sensor.py b/homeassistant/components/sun/sensor.py index e7e621d06cd..a042adb9b83 100644 --- a/homeassistant/components/sun/sensor.py +++ b/homeassistant/components/sun/sensor.py @@ -17,7 +17,7 @@ from homeassistant.const import DEGREE, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN, SIGNAL_EVENTS_CHANGED, SIGNAL_POSITION_CHANGED @@ -106,7 +106,9 @@ SENSOR_TYPES: tuple[SunSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: SunConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: SunConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sun sensor platform.""" diff --git a/homeassistant/components/sunweg/sensor/__init__.py b/homeassistant/components/sunweg/sensor/__init__.py index e582b5135d3..f71d992bea9 100644 --- a/homeassistant/components/sunweg/sensor/__init__.py +++ b/homeassistant/components/sunweg/sensor/__init__.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .. import SunWEGData from ..const import CONF_PLANT_ID, DEFAULT_PLANT_ID, DOMAIN, DeviceType @@ -49,7 +49,7 @@ def get_device_list( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the SunWEG sensor.""" name = config_entry.data[CONF_NAME] diff --git a/homeassistant/components/surepetcare/binary_sensor.py b/homeassistant/components/surepetcare/binary_sensor.py index 3acd768cb30..416d56d1bdd 100644 --- a/homeassistant/components/surepetcare/binary_sensor.py +++ b/homeassistant/components/surepetcare/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SurePetcareDataCoordinator @@ -23,7 +23,9 @@ from .entity import SurePetcareEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sure PetCare Flaps binary sensors based on a config entry.""" diff --git a/homeassistant/components/surepetcare/lock.py b/homeassistant/components/surepetcare/lock.py index f960400bcbc..09fadf8be60 100644 --- a/homeassistant/components/surepetcare/lock.py +++ b/homeassistant/components/surepetcare/lock.py @@ -10,7 +10,7 @@ from surepy.enums import EntityType, LockState as SurepyLockState from homeassistant.components.lock import LockEntity, LockState from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SurePetcareDataCoordinator @@ -18,7 +18,9 @@ from .entity import SurePetcareEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sure PetCare locks on a config entry.""" diff --git a/homeassistant/components/surepetcare/sensor.py b/homeassistant/components/surepetcare/sensor.py index b4e7c6203a3..b012878caf7 100644 --- a/homeassistant/components/surepetcare/sensor.py +++ b/homeassistant/components/surepetcare/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_VOLTAGE, PERCENTAGE, EntityCategory, UnitOfVolume from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, SURE_BATT_VOLTAGE_DIFF, SURE_BATT_VOLTAGE_LOW from .coordinator import SurePetcareDataCoordinator @@ -20,7 +20,9 @@ from .entity import SurePetcareEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Sure PetCare Flaps sensors.""" diff --git a/homeassistant/components/swiss_public_transport/sensor.py b/homeassistant/components/swiss_public_transport/sensor.py index c8075a6746c..6475fe802c2 100644 --- a/homeassistant/components/swiss_public_transport/sensor.py +++ b/homeassistant/components/swiss_public_transport/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -90,7 +90,7 @@ SENSORS: tuple[SwissPublicTransportSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: SwissPublicTransportConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor from a config entry created in the integrations UI.""" unique_id = config_entry.unique_id diff --git a/homeassistant/components/switch_as_x/cover.py b/homeassistant/components/switch_as_x/cover.py index 7c6a7ff38ad..8fd9c799bcb 100644 --- a/homeassistant/components/switch_as_x/cover.py +++ b/homeassistant/components/switch_as_x/cover.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_INVERT from .entity import BaseInvertableEntity @@ -29,7 +29,7 @@ from .entity import BaseInvertableEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Cover Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switch_as_x/fan.py b/homeassistant/components/switch_as_x/fan.py index 858379e71df..846e9ae7e80 100644 --- a/homeassistant/components/switch_as_x/fan.py +++ b/homeassistant/components/switch_as_x/fan.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import BaseToggleEntity @@ -21,7 +21,7 @@ from .entity import BaseToggleEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Fan Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switch_as_x/light.py b/homeassistant/components/switch_as_x/light.py index 59b816f7935..c043a354869 100644 --- a/homeassistant/components/switch_as_x/light.py +++ b/homeassistant/components/switch_as_x/light.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import BaseToggleEntity @@ -19,7 +19,7 @@ from .entity import BaseToggleEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Light Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switch_as_x/lock.py b/homeassistant/components/switch_as_x/lock.py index 2095b06bd84..946429e0395 100644 --- a/homeassistant/components/switch_as_x/lock.py +++ b/homeassistant/components/switch_as_x/lock.py @@ -16,7 +16,7 @@ from homeassistant.const import ( ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_INVERT from .entity import BaseInvertableEntity @@ -25,7 +25,7 @@ from .entity import BaseInvertableEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Lock Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switch_as_x/siren.py b/homeassistant/components/switch_as_x/siren.py index 7d9a41d9cd9..b96c7c6e0ea 100644 --- a/homeassistant/components/switch_as_x/siren.py +++ b/homeassistant/components/switch_as_x/siren.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import BaseToggleEntity @@ -19,7 +19,7 @@ from .entity import BaseToggleEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Siren Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switch_as_x/valve.py b/homeassistant/components/switch_as_x/valve.py index 8626ca3cfb4..2b5f252ac2d 100644 --- a/homeassistant/components/switch_as_x/valve.py +++ b/homeassistant/components/switch_as_x/valve.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_INVERT from .entity import BaseInvertableEntity @@ -29,7 +29,7 @@ from .entity import BaseInvertableEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Valve Switch config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/switchbee/button.py b/homeassistant/components/switchbee/button.py index 78b5c0e6888..1ac81ec4e0d 100644 --- a/homeassistant/components/switchbee/button.py +++ b/homeassistant/components/switchbee/button.py @@ -7,7 +7,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SwitchBeeCoordinator @@ -15,7 +15,9 @@ from .entity import SwitchBeeEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbee button.""" coordinator: SwitchBeeCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/switchbee/climate.py b/homeassistant/components/switchbee/climate.py index d946ed1761b..7837798b0cb 100644 --- a/homeassistant/components/switchbee/climate.py +++ b/homeassistant/components/switchbee/climate.py @@ -27,7 +27,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SwitchBeeCoordinator @@ -74,7 +74,9 @@ SUPPORTED_FAN_MODES = [FAN_AUTO, FAN_HIGH, FAN_MEDIUM, FAN_LOW] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBee climate.""" coordinator: SwitchBeeCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/switchbee/cover.py b/homeassistant/components/switchbee/cover.py index 02f3d7167e3..247063ab18a 100644 --- a/homeassistant/components/switchbee/cover.py +++ b/homeassistant/components/switchbee/cover.py @@ -17,7 +17,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SwitchBeeCoordinator @@ -25,7 +25,9 @@ from .entity import SwitchBeeDeviceEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBee switch.""" coordinator: SwitchBeeCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/switchbee/light.py b/homeassistant/components/switchbee/light.py index 0daa6e204aa..228667540df 100644 --- a/homeassistant/components/switchbee/light.py +++ b/homeassistant/components/switchbee/light.py @@ -11,7 +11,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SwitchBeeCoordinator @@ -35,7 +35,9 @@ def _switchbee_brightness_to_hass(value: int) -> int: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBee light.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/switchbee/switch.py b/homeassistant/components/switchbee/switch.py index c502e6f22f5..41538f6fd71 100644 --- a/homeassistant/components/switchbee/switch.py +++ b/homeassistant/components/switchbee/switch.py @@ -17,7 +17,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SwitchBeeCoordinator @@ -25,7 +25,9 @@ from .entity import SwitchBeeDeviceEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbee switch.""" coordinator: SwitchBeeCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/switchbot/binary_sensor.py b/homeassistant/components/switchbot/binary_sensor.py index 144872ff315..6d1490c895b 100644 --- a/homeassistant/components/switchbot/binary_sensor.py +++ b/homeassistant/components/switchbot/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator from .entity import SwitchbotEntity @@ -75,7 +75,7 @@ BINARY_SENSOR_TYPES: dict[str, BinarySensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot curtain based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/switchbot/cover.py b/homeassistant/components/switchbot/cover.py index d2fd073cdcb..3ef0f5625c2 100644 --- a/homeassistant/components/switchbot/cover.py +++ b/homeassistant/components/switchbot/cover.py @@ -17,7 +17,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator @@ -31,7 +31,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot curtain based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/switchbot/humidifier.py b/homeassistant/components/switchbot/humidifier.py index 40f96577842..34a24948df1 100644 --- a/homeassistant/components/switchbot/humidifier.py +++ b/homeassistant/components/switchbot/humidifier.py @@ -12,7 +12,7 @@ from homeassistant.components.humidifier import ( HumidifierEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SwitchbotConfigEntry from .entity import SwitchbotSwitchedEntity @@ -23,7 +23,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot based on a config entry.""" async_add_entities([SwitchBotHumidifier(entry.runtime_data)]) diff --git a/homeassistant/components/switchbot/light.py b/homeassistant/components/switchbot/light.py index 927ad5120c7..0a2c342ecf0 100644 --- a/homeassistant/components/switchbot/light.py +++ b/homeassistant/components/switchbot/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( LightEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator from .entity import SwitchbotEntity @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switchbot light.""" async_add_entities([SwitchbotLightEntity(entry.runtime_data)]) diff --git a/homeassistant/components/switchbot/lock.py b/homeassistant/components/switchbot/lock.py index a3bee5661b2..6bad154813a 100644 --- a/homeassistant/components/switchbot/lock.py +++ b/homeassistant/components/switchbot/lock.py @@ -7,7 +7,7 @@ from switchbot.const import LockStatus from homeassistant.components.lock import LockEntity, LockEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_LOCK_NIGHTLATCH, DEFAULT_LOCK_NIGHTLATCH from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import SwitchbotEntity async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot lock based on a config entry.""" force_nightlatch = entry.options.get(CONF_LOCK_NIGHTLATCH, DEFAULT_LOCK_NIGHTLATCH) diff --git a/homeassistant/components/switchbot/sensor.py b/homeassistant/components/switchbot/sensor.py index 9787521a5e9..025c40bff9e 100644 --- a/homeassistant/components/switchbot/sensor.py +++ b/homeassistant/components/switchbot/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator from .entity import SwitchbotEntity @@ -102,7 +102,7 @@ SENSOR_TYPES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/switchbot/switch.py b/homeassistant/components/switchbot/switch.py index 427496ef20c..fd1e8bb6393 100644 --- a/homeassistant/components/switchbot/switch.py +++ b/homeassistant/components/switchbot/switch.py @@ -9,7 +9,7 @@ import switchbot from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot based on a config entry.""" async_add_entities([SwitchBotSwitch(entry.runtime_data)]) diff --git a/homeassistant/components/switchbot_cloud/__init__.py b/homeassistant/components/switchbot_cloud/__init__.py index d7812158260..44e130cc7a4 100644 --- a/homeassistant/components/switchbot_cloud/__init__.py +++ b/homeassistant/components/switchbot_cloud/__init__.py @@ -47,13 +47,14 @@ class SwitchbotCloudData: async def coordinator_for_device( hass: HomeAssistant, + entry: ConfigEntry, api: SwitchBotAPI, device: Device | Remote, coordinators_by_id: dict[str, SwitchBotCoordinator], ) -> SwitchBotCoordinator: """Instantiate coordinator and adds to list for gathering.""" coordinator = coordinators_by_id.setdefault( - device.device_id, SwitchBotCoordinator(hass, api, device) + device.device_id, SwitchBotCoordinator(hass, entry, api, device) ) if coordinator.data is None: @@ -64,6 +65,7 @@ async def coordinator_for_device( async def make_switchbot_devices( hass: HomeAssistant, + entry: ConfigEntry, api: SwitchBotAPI, devices: list[Device | Remote], coordinators_by_id: dict[str, SwitchBotCoordinator], @@ -72,7 +74,7 @@ async def make_switchbot_devices( devices_data = SwitchbotDevices() await gather( *[ - make_device_data(hass, api, device, devices_data, coordinators_by_id) + make_device_data(hass, entry, api, device, devices_data, coordinators_by_id) for device in devices ] ) @@ -82,6 +84,7 @@ async def make_switchbot_devices( async def make_device_data( hass: HomeAssistant, + entry: ConfigEntry, api: SwitchBotAPI, device: Device | Remote, devices_data: SwitchbotDevices, @@ -90,7 +93,7 @@ async def make_device_data( """Make device data.""" if isinstance(device, Remote) and device.device_type.endswith("Air Conditioner"): coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) devices_data.climates.append((device, coordinator)) if ( @@ -101,7 +104,7 @@ async def make_device_data( ) ) or isinstance(device, Remote): coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) devices_data.switches.append((device, coordinator)) @@ -117,7 +120,7 @@ async def make_device_data( "Plug Mini (JP)", ]: coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) devices_data.sensors.append((device, coordinator)) @@ -128,19 +131,19 @@ async def make_device_data( "Robot Vacuum Cleaner S1 Plus", ]: coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) devices_data.vacuums.append((device, coordinator)) if isinstance(device, Device) and device.device_type.startswith("Smart Lock"): coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) devices_data.locks.append((device, coordinator)) if isinstance(device, Device) and device.device_type in ["Bot"]: coordinator = await coordinator_for_device( - hass, api, device, coordinators_by_id + hass, entry, api, device, coordinators_by_id ) if coordinator.data is not None: if coordinator.data.get("deviceMode") == "pressMode": @@ -149,10 +152,10 @@ async def make_device_data( devices_data.switches.append((device, coordinator)) -async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up SwitchBot via API from a config entry.""" - token = config.data[CONF_API_TOKEN] - secret = config.data[CONF_API_KEY] + token = entry.data[CONF_API_TOKEN] + secret = entry.data[CONF_API_KEY] api = SwitchBotAPI(token=token, secret=secret) try: @@ -168,13 +171,13 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: coordinators_by_id: dict[str, SwitchBotCoordinator] = {} switchbot_devices = await make_switchbot_devices( - hass, api, devices, coordinators_by_id + hass, entry, api, devices, coordinators_by_id ) hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN][config.entry_id] = SwitchbotCloudData( + hass.data[DOMAIN][entry.entry_id] = SwitchbotCloudData( api=api, devices=switchbot_devices ) - await hass.config_entries.async_forward_entry_setups(config, PLATFORMS) + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True diff --git a/homeassistant/components/switchbot_cloud/button.py b/homeassistant/components/switchbot_cloud/button.py index a6eb1a134a5..aae2758f3ca 100644 --- a/homeassistant/components/switchbot_cloud/button.py +++ b/homeassistant/components/switchbot_cloud/button.py @@ -7,7 +7,7 @@ from switchbot_api import BotCommands from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import DOMAIN @@ -17,7 +17,7 @@ from .entity import SwitchBotCloudEntity async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switchbot_cloud/climate.py b/homeassistant/components/switchbot_cloud/climate.py index 9e996649e8c..27698420ae9 100644 --- a/homeassistant/components/switchbot_cloud/climate.py +++ b/homeassistant/components/switchbot_cloud/climate.py @@ -13,7 +13,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import DOMAIN @@ -42,7 +42,7 @@ _DEFAULT_SWITCHBOT_FAN_MODE = _SWITCHBOT_FAN_MODES[FanState.FAN_AUTO] async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switchbot_cloud/coordinator.py b/homeassistant/components/switchbot_cloud/coordinator.py index 0ebd04f7e5a..02ead5940e4 100644 --- a/homeassistant/components/switchbot_cloud/coordinator.py +++ b/homeassistant/components/switchbot_cloud/coordinator.py @@ -6,6 +6,7 @@ from typing import Any from switchbot_api import CannotConnect, Device, Remote, SwitchBotAPI +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -19,16 +20,22 @@ type Status = dict[str, Any] | None class SwitchBotCoordinator(DataUpdateCoordinator[Status]): """SwitchBot Cloud coordinator.""" + config_entry: ConfigEntry _api: SwitchBotAPI _device_id: str def __init__( - self, hass: HomeAssistant, api: SwitchBotAPI, device: Device | Remote + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + api: SwitchBotAPI, + device: Device | Remote, ) -> None: """Initialize SwitchBot Cloud.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=DEFAULT_SCAN_INTERVAL, ) diff --git a/homeassistant/components/switchbot_cloud/lock.py b/homeassistant/components/switchbot_cloud/lock.py index 52f48c66d38..74a9e9d8b1e 100644 --- a/homeassistant/components/switchbot_cloud/lock.py +++ b/homeassistant/components/switchbot_cloud/lock.py @@ -7,7 +7,7 @@ from switchbot_api import LockCommands from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import DOMAIN @@ -17,7 +17,7 @@ from .entity import SwitchBotCloudEntity async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switchbot_cloud/sensor.py b/homeassistant/components/switchbot_cloud/sensor.py index 1f755c141a2..28384ffd4d5 100644 --- a/homeassistant/components/switchbot_cloud/sensor.py +++ b/homeassistant/components/switchbot_cloud/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import DOMAIN @@ -139,7 +139,7 @@ SENSOR_DESCRIPTIONS_BY_DEVICE_TYPES = { async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switchbot_cloud/switch.py b/homeassistant/components/switchbot_cloud/switch.py index 22d033625f9..ebe20620d3e 100644 --- a/homeassistant/components/switchbot_cloud/switch.py +++ b/homeassistant/components/switchbot_cloud/switch.py @@ -7,7 +7,7 @@ from switchbot_api import CommonCommands, Device, PowerState, Remote, SwitchBotA from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import DOMAIN @@ -18,7 +18,7 @@ from .entity import SwitchBotCloudEntity async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switchbot_cloud/vacuum.py b/homeassistant/components/switchbot_cloud/vacuum.py index 84db7cfdbb8..9a9ad49626f 100644 --- a/homeassistant/components/switchbot_cloud/vacuum.py +++ b/homeassistant/components/switchbot_cloud/vacuum.py @@ -11,7 +11,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitchbotCloudData from .const import ( @@ -28,7 +28,7 @@ from .entity import SwitchBotCloudEntity async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up SwitchBot Cloud entry.""" data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/switcher_kis/button.py b/homeassistant/components/switcher_kis/button.py index d2686e2e550..30597ed0738 100644 --- a/homeassistant/components/switcher_kis/button.py +++ b/homeassistant/components/switcher_kis/button.py @@ -20,7 +20,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitcherConfigEntry from .const import SIGNAL_DEVICE_ADD @@ -81,7 +81,7 @@ THERMOSTAT_BUTTONS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: SwitcherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher button from config entry.""" diff --git a/homeassistant/components/switcher_kis/climate.py b/homeassistant/components/switcher_kis/climate.py index 2fc4a331676..c8bf33eca09 100644 --- a/homeassistant/components/switcher_kis/climate.py +++ b/homeassistant/components/switcher_kis/climate.py @@ -29,7 +29,7 @@ from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SwitcherConfigEntry from .const import SIGNAL_DEVICE_ADD @@ -62,7 +62,7 @@ HA_TO_DEVICE_FAN = {value: key for key, value in DEVICE_FAN_TO_HA.items()} async def async_setup_entry( hass: HomeAssistant, config_entry: SwitcherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher climate from config entry.""" diff --git a/homeassistant/components/switcher_kis/cover.py b/homeassistant/components/switcher_kis/cover.py index 513b786a033..5d8e4a4b0ac 100644 --- a/homeassistant/components/switcher_kis/cover.py +++ b/homeassistant/components/switcher_kis/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_DEVICE_ADD from .coordinator import SwitcherDataUpdateCoordinator @@ -28,7 +28,7 @@ API_STOP = "stop_shutter" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher cover from config entry.""" diff --git a/homeassistant/components/switcher_kis/light.py b/homeassistant/components/switcher_kis/light.py index 75156044efa..b9dc78f5bdf 100644 --- a/homeassistant/components/switcher_kis/light.py +++ b/homeassistant/components/switcher_kis/light.py @@ -10,7 +10,7 @@ from homeassistant.components.light import ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import SIGNAL_DEVICE_ADD from .coordinator import SwitcherDataUpdateCoordinator @@ -22,7 +22,7 @@ API_SET_LIGHT = "set_light" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher light from a config entry.""" diff --git a/homeassistant/components/switcher_kis/sensor.py b/homeassistant/components/switcher_kis/sensor.py index 0ed60e5a721..029d517bb09 100644 --- a/homeassistant/components/switcher_kis/sensor.py +++ b/homeassistant/components/switcher_kis/sensor.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfElectricCurrent, UnitOfPower from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import SIGNAL_DEVICE_ADD @@ -61,7 +61,7 @@ THERMOSTAT_SENSORS = TEMPERATURE_SENSORS async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher sensor from config entry.""" diff --git a/homeassistant/components/switcher_kis/switch.py b/homeassistant/components/switcher_kis/switch.py index 7d3d71a0615..30b0b4161b1 100644 --- a/homeassistant/components/switcher_kis/switch.py +++ b/homeassistant/components/switcher_kis/switch.py @@ -16,7 +16,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from .const import ( @@ -49,7 +49,7 @@ SERVICE_TURN_ON_WITH_TIMER_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switcher switch from config entry.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/syncthing/sensor.py b/homeassistant/components/syncthing/sensor.py index fc1f9ae8aea..697ea8aea6e 100644 --- a/homeassistant/components/syncthing/sensor.py +++ b/homeassistant/components/syncthing/sensor.py @@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from .const import ( @@ -25,7 +25,7 @@ from .const import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Syncthing sensors.""" syncthing = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/syncthru/binary_sensor.py b/homeassistant/components/syncthru/binary_sensor.py index 2b110c2af1d..e6d26d22433 100644 --- a/homeassistant/components/syncthru/binary_sensor.py +++ b/homeassistant/components/syncthru/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -35,7 +35,7 @@ SYNCTHRU_STATE_PROBLEM = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" diff --git a/homeassistant/components/syncthru/sensor.py b/homeassistant/components/syncthru/sensor.py index df2ffd99803..c2063bf6c0a 100644 --- a/homeassistant/components/syncthru/sensor.py +++ b/homeassistant/components/syncthru/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -43,7 +43,7 @@ SYNCTHRU_STATE_HUMAN = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up from config entry.""" diff --git a/homeassistant/components/synology_dsm/binary_sensor.py b/homeassistant/components/synology_dsm/binary_sensor.py index b9c7ff483ea..2f7d041cb10 100644 --- a/homeassistant/components/synology_dsm/binary_sensor.py +++ b/homeassistant/components/synology_dsm/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DISKS, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SynoApi from .const import DOMAIN @@ -63,7 +63,9 @@ STORAGE_DISK_BINARY_SENSORS: tuple[SynologyDSMBinarySensorEntityDescription, ... async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Synology NAS binary sensor.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/synology_dsm/button.py b/homeassistant/components/synology_dsm/button.py index fccd0860036..6512c370334 100644 --- a/homeassistant/components/synology_dsm/button.py +++ b/homeassistant/components/synology_dsm/button.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SynoApi from .const import DOMAIN @@ -53,7 +53,7 @@ BUTTONS: Final = [ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set buttons for device.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/synology_dsm/camera.py b/homeassistant/components/synology_dsm/camera.py index cbf17ec05b4..acbcccb8894 100644 --- a/homeassistant/components/synology_dsm/camera.py +++ b/homeassistant/components/synology_dsm/camera.py @@ -20,7 +20,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SynoApi from .const import ( @@ -46,7 +46,9 @@ class SynologyDSMCameraEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Synology NAS cameras.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/synology_dsm/manifest.json b/homeassistant/components/synology_dsm/manifest.json index ab6fc20b5cb..a083fa5a15f 100644 --- a/homeassistant/components/synology_dsm/manifest.json +++ b/homeassistant/components/synology_dsm/manifest.json @@ -7,7 +7,7 @@ "documentation": "https://www.home-assistant.io/integrations/synology_dsm", "iot_class": "local_polling", "loggers": ["synology_dsm"], - "requirements": ["py-synologydsm-api==2.6.0"], + "requirements": ["py-synologydsm-api==2.6.2"], "ssdp": [ { "manufacturer": "Synology", diff --git a/homeassistant/components/synology_dsm/sensor.py b/homeassistant/components/synology_dsm/sensor.py index b29a33f7253..2987de7a7c7 100644 --- a/homeassistant/components/synology_dsm/sensor.py +++ b/homeassistant/components/synology_dsm/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow @@ -286,7 +286,9 @@ INFORMATION_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Synology NAS Sensor.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/synology_dsm/switch.py b/homeassistant/components/synology_dsm/switch.py index facce824bda..c4f1572ceea 100644 --- a/homeassistant/components/synology_dsm/switch.py +++ b/homeassistant/components/synology_dsm/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import SynoApi from .const import DOMAIN @@ -40,7 +40,9 @@ SURVEILLANCE_SWITCH: tuple[SynologyDSMSwitchEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Synology NAS switch.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/synology_dsm/update.py b/homeassistant/components/synology_dsm/update.py index ed60191f296..71eed2d7f1f 100644 --- a/homeassistant/components/synology_dsm/update.py +++ b/homeassistant/components/synology_dsm/update.py @@ -12,7 +12,7 @@ from homeassistant.components.update import UpdateEntity, UpdateEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SynologyDSMCentralUpdateCoordinator @@ -38,7 +38,9 @@ UPDATE_ENTITIES: Final = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Synology DSM update entities.""" data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] diff --git a/homeassistant/components/system_bridge/binary_sensor.py b/homeassistant/components/system_bridge/binary_sensor.py index 019b1df4639..0140499a75a 100644 --- a/homeassistant/components/system_bridge/binary_sensor.py +++ b/homeassistant/components/system_bridge/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PORT from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SystemBridgeDataUpdateCoordinator @@ -65,7 +65,9 @@ BATTERY_BINARY_SENSOR_TYPES: tuple[SystemBridgeBinarySensorEntityDescription, .. async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Bridge binary sensor based on a config entry.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/system_bridge/coordinator.py b/homeassistant/components/system_bridge/coordinator.py index 7151805f154..1690bad4a4d 100644 --- a/homeassistant/components/system_bridge/coordinator.py +++ b/homeassistant/components/system_bridge/coordinator.py @@ -40,6 +40,8 @@ from .data import SystemBridgeData class SystemBridgeDataUpdateCoordinator(DataUpdateCoordinator[SystemBridgeData]): """Class to manage fetching System Bridge data from single endpoint.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, @@ -65,6 +67,7 @@ class SystemBridgeDataUpdateCoordinator(DataUpdateCoordinator[SystemBridgeData]) super().__init__( hass, LOGGER, + config_entry=entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/system_bridge/media_player.py b/homeassistant/components/system_bridge/media_player.py index aeff3b22fb2..6d3bbd21a05 100644 --- a/homeassistant/components/system_bridge/media_player.py +++ b/homeassistant/components/system_bridge/media_player.py @@ -18,7 +18,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PORT from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SystemBridgeDataUpdateCoordinator @@ -66,7 +66,7 @@ MEDIA_PLAYER_DESCRIPTION: Final[MediaPlayerEntityDescription] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Bridge media players based on a config entry.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/system_bridge/sensor.py b/homeassistant/components/system_bridge/sensor.py index 94c73a2ac05..c7cae2f347b 100644 --- a/homeassistant/components/system_bridge/sensor.py +++ b/homeassistant/components/system_bridge/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED, StateType from homeassistant.util import dt as dt_util @@ -359,7 +359,7 @@ BATTERY_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Bridge sensor based on a config entry.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/system_bridge/update.py b/homeassistant/components/system_bridge/update.py index b0d341cee3b..12060c28669 100644 --- a/homeassistant/components/system_bridge/update.py +++ b/homeassistant/components/system_bridge/update.py @@ -6,7 +6,7 @@ from homeassistant.components.update import UpdateEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PORT from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import SystemBridgeDataUpdateCoordinator @@ -16,7 +16,7 @@ from .entity import SystemBridgeEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Bridge update based on a config entry.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/systemmonitor/binary_sensor.py b/homeassistant/components/systemmonitor/binary_sensor.py index aecd30765ff..3968e94ec03 100644 --- a/homeassistant/components/systemmonitor/binary_sensor.py +++ b/homeassistant/components/systemmonitor/binary_sensor.py @@ -20,7 +20,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import slugify @@ -91,7 +91,7 @@ SENSOR_TYPES: tuple[SysMonitorBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: SystemMonitorConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Monitor binary sensors based on a config entry.""" coordinator = entry.runtime_data.coordinator diff --git a/homeassistant/components/systemmonitor/sensor.py b/homeassistant/components/systemmonitor/sensor.py index 048d7cefd6c..e70bccf0833 100644 --- a/homeassistant/components/systemmonitor/sensor.py +++ b/homeassistant/components/systemmonitor/sensor.py @@ -31,7 +31,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import slugify @@ -397,7 +397,7 @@ IF_ADDRS_FAMILY = {"ipv4_address": socket.AF_INET, "ipv6_address": socket.AF_INE async def async_setup_entry( hass: HomeAssistant, entry: SystemMonitorConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up System Monitor sensors based on a config entry.""" entities: list[SystemMonitorSensor] = [] diff --git a/homeassistant/components/tado/binary_sensor.py b/homeassistant/components/tado/binary_sensor.py index c969ea34f42..8cec32e20f0 100644 --- a/homeassistant/components/tado/binary_sensor.py +++ b/homeassistant/components/tado/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TadoConfigEntry @@ -115,7 +115,9 @@ ZONE_SENSORS = { async def async_setup_entry( - hass: HomeAssistant, entry: TadoConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TadoConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tado sensor platform.""" diff --git a/homeassistant/components/tado/climate.py b/homeassistant/components/tado/climate.py index db7b1823bd9..e6aa921d428 100644 --- a/homeassistant/components/tado/climate.py +++ b/homeassistant/components/tado/climate.py @@ -26,7 +26,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import TadoConfigEntry @@ -100,7 +100,9 @@ CLIMATE_TEMP_OFFSET_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: TadoConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TadoConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tado climate platform.""" diff --git a/homeassistant/components/tado/device_tracker.py b/homeassistant/components/tado/device_tracker.py index a9be560f434..34aca2dd833 100644 --- a/homeassistant/components/tado/device_tracker.py +++ b/homeassistant/components/tado/device_tracker.py @@ -11,7 +11,7 @@ from homeassistant.components.device_tracker import ( from homeassistant.const import STATE_HOME, STATE_NOT_HOME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: TadoConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tado device scannery entity.""" _LOGGER.debug("Setting up Tado device scanner entity") @@ -57,7 +57,7 @@ async def async_setup_entry( def add_tracked_entities( hass: HomeAssistant, coordinator: TadoMobileDeviceUpdateCoordinator, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: set[str], ) -> None: """Add new tracker entities from Tado.""" diff --git a/homeassistant/components/tado/sensor.py b/homeassistant/components/tado/sensor.py index 037b33574e7..d0d54e79670 100644 --- a/homeassistant/components/tado/sensor.py +++ b/homeassistant/components/tado/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TadoConfigEntry @@ -191,7 +191,9 @@ ZONE_SENSORS = { async def async_setup_entry( - hass: HomeAssistant, entry: TadoConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TadoConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tado sensor platform.""" diff --git a/homeassistant/components/tado/water_heater.py b/homeassistant/components/tado/water_heater.py index 02fbb3f5e23..3d8825b264f 100644 --- a/homeassistant/components/tado/water_heater.py +++ b/homeassistant/components/tado/water_heater.py @@ -12,7 +12,7 @@ from homeassistant.components.water_heater import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import TadoConfigEntry @@ -61,7 +61,9 @@ WATER_HEATER_TIMER_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: TadoConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TadoConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tado water heater platform.""" diff --git a/homeassistant/components/tailscale/binary_sensor.py b/homeassistant/components/tailscale/binary_sensor.py index 981f871de09..6569b40ada2 100644 --- a/homeassistant/components/tailscale/binary_sensor.py +++ b/homeassistant/components/tailscale/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import TailscaleEntity @@ -84,7 +84,7 @@ BINARY_SENSORS: tuple[TailscaleBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Tailscale binary sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tailscale/coordinator.py b/homeassistant/components/tailscale/coordinator.py index 64ce0147664..1b29cfbf4be 100644 --- a/homeassistant/components/tailscale/coordinator.py +++ b/homeassistant/components/tailscale/coordinator.py @@ -19,18 +19,22 @@ class TailscaleDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Device]]): config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: + def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize the Tailscale coordinator.""" - self.config_entry = entry - session = async_get_clientsession(hass) self.tailscale = Tailscale( session=session, - api_key=entry.data[CONF_API_KEY], - tailnet=entry.data[CONF_TAILNET], + api_key=config_entry.data[CONF_API_KEY], + tailnet=config_entry.data[CONF_TAILNET], ) - super().__init__(hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, + LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) async def _async_update_data(self) -> dict[str, Device]: """Fetch devices from Tailscale.""" diff --git a/homeassistant/components/tailscale/sensor.py b/homeassistant/components/tailscale/sensor.py index fa4c966a7d7..cf944aa73ef 100644 --- a/homeassistant/components/tailscale/sensor.py +++ b/homeassistant/components/tailscale/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import TailscaleEntity @@ -55,7 +55,7 @@ SENSORS: tuple[TailscaleSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Tailscale sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tailwind/binary_sensor.py b/homeassistant/components/tailwind/binary_sensor.py index d2f8e1e2ced..4d927b0769e 100644 --- a/homeassistant/components/tailwind/binary_sensor.py +++ b/homeassistant/components/tailwind/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import TailwindConfigEntry from .entity import TailwindDoorEntity @@ -41,7 +41,7 @@ DESCRIPTIONS: tuple[TailwindDoorBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TailwindConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tailwind binary sensor based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/tailwind/button.py b/homeassistant/components/tailwind/button.py index edff3434866..380eb7ccd7e 100644 --- a/homeassistant/components/tailwind/button.py +++ b/homeassistant/components/tailwind/button.py @@ -16,7 +16,7 @@ from homeassistant.components.button import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import TailwindConfigEntry @@ -43,7 +43,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: TailwindConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tailwind button based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/tailwind/cover.py b/homeassistant/components/tailwind/cover.py index 8ea1c7d4f6d..84f38c7d579 100644 --- a/homeassistant/components/tailwind/cover.py +++ b/homeassistant/components/tailwind/cover.py @@ -20,7 +20,7 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, LOGGER from .coordinator import TailwindConfigEntry @@ -30,7 +30,7 @@ from .entity import TailwindDoorEntity async def async_setup_entry( hass: HomeAssistant, entry: TailwindConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tailwind cover based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/tailwind/number.py b/homeassistant/components/tailwind/number.py index b67df9a6a25..ca6b610c351 100644 --- a/homeassistant/components/tailwind/number.py +++ b/homeassistant/components/tailwind/number.py @@ -12,7 +12,7 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import TailwindConfigEntry @@ -47,7 +47,7 @@ DESCRIPTIONS = [ async def async_setup_entry( hass: HomeAssistant, entry: TailwindConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tailwind number based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/tami4/__init__.py b/homeassistant/components/tami4/__init__.py index 8c597409c77..8b9a5e1a90f 100644 --- a/homeassistant/components/tami4/__init__.py +++ b/homeassistant/components/tami4/__init__.py @@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except exceptions.TokenRefreshFailedException as ex: raise ConfigEntryNotReady("Error connecting to API") from ex - coordinator = Tami4EdgeCoordinator(hass, api) + coordinator = Tami4EdgeCoordinator(hass, entry, api) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { diff --git a/homeassistant/components/tami4/button.py b/homeassistant/components/tami4/button.py index 11377a2dcfb..a1b8db79674 100644 --- a/homeassistant/components/tami4/button.py +++ b/homeassistant/components/tami4/button.py @@ -11,7 +11,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import API, DOMAIN from .entity import Tami4EdgeBaseEntity @@ -41,7 +41,9 @@ BOIL_WATER_BUTTON = Tami4EdgeButtonEntityDescription( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Tami4Edge.""" diff --git a/homeassistant/components/tami4/coordinator.py b/homeassistant/components/tami4/coordinator.py index 4764562bc34..f65c819b3d8 100644 --- a/homeassistant/components/tami4/coordinator.py +++ b/homeassistant/components/tami4/coordinator.py @@ -7,6 +7,7 @@ import logging from Tami4EdgeAPI import Tami4EdgeAPI, exceptions from Tami4EdgeAPI.water_quality import WaterQuality +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -36,11 +37,16 @@ class FlattenedWaterQuality: class Tami4EdgeCoordinator(DataUpdateCoordinator[FlattenedWaterQuality]): """Tami4Edge water quality coordinator.""" - def __init__(self, hass: HomeAssistant, api: Tami4EdgeAPI) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: Tami4EdgeAPI + ) -> None: """Initialize the water quality coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Tami4Edge water quality coordinator", update_interval=timedelta(minutes=60), ) diff --git a/homeassistant/components/tami4/sensor.py b/homeassistant/components/tami4/sensor.py index 888acda9372..2bfd3079c19 100644 --- a/homeassistant/components/tami4/sensor.py +++ b/homeassistant/components/tami4/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfVolume from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import API, COORDINATOR, DOMAIN @@ -52,7 +52,9 @@ ENTITY_DESCRIPTIONS = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Tami4Edge.""" data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tankerkoenig/binary_sensor.py b/homeassistant/components/tankerkoenig/binary_sensor.py index 774262a8854..a38266e57e8 100644 --- a/homeassistant/components/tankerkoenig/binary_sensor.py +++ b/homeassistant/components/tankerkoenig/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import TankerkoenigConfigEntry, TankerkoenigDataUpdateCoordinator from .entity import TankerkoenigCoordinatorEntity @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: TankerkoenigConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the tankerkoenig binary sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/tankerkoenig/sensor.py b/homeassistant/components/tankerkoenig/sensor.py index 5970f3d3b24..b1646489d96 100644 --- a/homeassistant/components/tankerkoenig/sensor.py +++ b/homeassistant/components/tankerkoenig/sensor.py @@ -9,7 +9,7 @@ from aiotankerkoenig import GasType, Station from homeassistant.components.sensor import SensorEntity, SensorStateClass from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE, CURRENCY_EURO from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_BRAND, @@ -30,7 +30,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: TankerkoenigConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the tankerkoenig sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/tasmota/binary_sensor.py b/homeassistant/components/tasmota/binary_sensor.py index 22cdf1a5ff0..3b2e640b807 100644 --- a/homeassistant/components/tasmota/binary_sensor.py +++ b/homeassistant/components/tasmota/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import event as evt from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_REMOVE_DISCOVER_COMPONENT from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW @@ -26,7 +26,7 @@ from .entity import TasmotaAvailability, TasmotaDiscoveryUpdate async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota binary sensor dynamically through discovery.""" diff --git a/homeassistant/components/tasmota/cover.py b/homeassistant/components/tasmota/cover.py index 2cb3cfeea25..1d7aa8316b6 100644 --- a/homeassistant/components/tasmota/cover.py +++ b/homeassistant/components/tasmota/cover.py @@ -18,7 +18,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_REMOVE_DISCOVER_COMPONENT from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW @@ -28,7 +28,7 @@ from .entity import TasmotaAvailability, TasmotaDiscoveryUpdate async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota cover dynamically through discovery.""" diff --git a/homeassistant/components/tasmota/fan.py b/homeassistant/components/tasmota/fan.py index e927bd6ad72..c89b36577be 100644 --- a/homeassistant/components/tasmota/fan.py +++ b/homeassistant/components/tasmota/fan.py @@ -16,7 +16,7 @@ from homeassistant.components.fan import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -36,7 +36,7 @@ ORDERED_NAMED_FAN_SPEEDS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota fan dynamically through discovery.""" diff --git a/homeassistant/components/tasmota/light.py b/homeassistant/components/tasmota/light.py index a06e77eceb1..ed66fa128dc 100644 --- a/homeassistant/components/tasmota/light.py +++ b/homeassistant/components/tasmota/light.py @@ -31,7 +31,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import DATA_REMOVE_DISCOVER_COMPONENT @@ -45,7 +45,7 @@ TASMOTA_BRIGHTNESS_MAX = 100 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota light dynamically through discovery.""" diff --git a/homeassistant/components/tasmota/sensor.py b/homeassistant/components/tasmota/sensor.py index 8cc538e706a..ec20e1c0348 100644 --- a/homeassistant/components/tasmota/sensor.py +++ b/homeassistant/components/tasmota/sensor.py @@ -40,7 +40,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_REMOVE_DISCOVER_COMPONENT from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW @@ -243,7 +243,7 @@ SENSOR_UNIT_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota sensor dynamically through discovery.""" diff --git a/homeassistant/components/tasmota/switch.py b/homeassistant/components/tasmota/switch.py index b5c19fc2431..03e594b125c 100644 --- a/homeassistant/components/tasmota/switch.py +++ b/homeassistant/components/tasmota/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_REMOVE_DISCOVER_COMPONENT from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW @@ -21,7 +21,7 @@ from .entity import TasmotaAvailability, TasmotaDiscoveryUpdate, TasmotaOnOffEnt async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tasmota switch dynamically through discovery.""" diff --git a/homeassistant/components/tautulli/__init__.py b/homeassistant/components/tautulli/__init__.py index a031354ae7d..41089016fac 100644 --- a/homeassistant/components/tautulli/__init__.py +++ b/homeassistant/components/tautulli/__init__.py @@ -4,15 +4,13 @@ from __future__ import annotations from pytautulli import PyTautulli, PyTautulliHostConfiguration -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_URL, CONF_VERIFY_SSL, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .coordinator import TautulliDataUpdateCoordinator +from .coordinator import TautulliConfigEntry, TautulliDataUpdateCoordinator PLATFORMS = [Platform.SENSOR] -type TautulliConfigEntry = ConfigEntry[TautulliDataUpdateCoordinator] async def async_setup_entry(hass: HomeAssistant, entry: TautulliConfigEntry) -> bool: @@ -27,7 +25,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TautulliConfigEntry) -> session=async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL]), ) entry.runtime_data = TautulliDataUpdateCoordinator( - hass, host_configuration, api_client + hass, entry, host_configuration, api_client ) await entry.runtime_data.async_config_entry_first_refresh() await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/tautulli/coordinator.py b/homeassistant/components/tautulli/coordinator.py index f392ab8df03..5d0f26b83b6 100644 --- a/homeassistant/components/tautulli/coordinator.py +++ b/homeassistant/components/tautulli/coordinator.py @@ -4,7 +4,6 @@ from __future__ import annotations import asyncio from datetime import timedelta -from typing import TYPE_CHECKING from pytautulli import ( PyTautulli, @@ -18,14 +17,14 @@ from pytautulli.exceptions import ( ) from pytautulli.models.host_configuration import PyTautulliHostConfiguration +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, LOGGER -if TYPE_CHECKING: - from . import TautulliConfigEntry +type TautulliConfigEntry = ConfigEntry[TautulliDataUpdateCoordinator] class TautulliDataUpdateCoordinator(DataUpdateCoordinator[None]): @@ -36,6 +35,7 @@ class TautulliDataUpdateCoordinator(DataUpdateCoordinator[None]): def __init__( self, hass: HomeAssistant, + config_entry: TautulliConfigEntry, host_configuration: PyTautulliHostConfiguration, api_client: PyTautulli, ) -> None: @@ -43,6 +43,7 @@ class TautulliDataUpdateCoordinator(DataUpdateCoordinator[None]): super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=10), ) diff --git a/homeassistant/components/tautulli/sensor.py b/homeassistant/components/tautulli/sensor.py index cd21630031a..c8d35623c21 100644 --- a/homeassistant/components/tautulli/sensor.py +++ b/homeassistant/components/tautulli/sensor.py @@ -23,12 +23,14 @@ from homeassistant.config_entries import SOURCE_IMPORT from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfInformation from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityDescription -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType -from . import TautulliConfigEntry from .const import ATTR_TOP_USER, DOMAIN -from .coordinator import TautulliDataUpdateCoordinator +from .coordinator import TautulliConfigEntry, TautulliDataUpdateCoordinator from .entity import TautulliEntity @@ -213,7 +215,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: TautulliConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tautulli sensor.""" data = entry.runtime_data diff --git a/homeassistant/components/technove/__init__.py b/homeassistant/components/technove/__init__.py index b886dabc80c..df4fc7713aa 100644 --- a/homeassistant/components/technove/__init__.py +++ b/homeassistant/components/technove/__init__.py @@ -2,16 +2,13 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from .coordinator import TechnoVEDataUpdateCoordinator +from .coordinator import TechnoVEConfigEntry, TechnoVEDataUpdateCoordinator PLATFORMS = [Platform.BINARY_SENSOR, Platform.NUMBER, Platform.SENSOR, Platform.SWITCH] -TechnoVEConfigEntry = ConfigEntry[TechnoVEDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: TechnoVEConfigEntry) -> bool: """Set up TechnoVE from a config entry.""" @@ -25,6 +22,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: TechnoVEConfigEntry) -> return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: TechnoVEConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/technove/binary_sensor.py b/homeassistant/components/technove/binary_sensor.py index f231e206c96..ac52a19884e 100644 --- a/homeassistant/components/technove/binary_sensor.py +++ b/homeassistant/components/technove/binary_sensor.py @@ -14,10 +14,9 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TechnoVEConfigEntry -from .coordinator import TechnoVEDataUpdateCoordinator +from .coordinator import TechnoVEConfigEntry, TechnoVEDataUpdateCoordinator from .entity import TechnoVEEntity @@ -66,7 +65,7 @@ BINARY_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: TechnoVEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensor platform.""" async_add_entities( diff --git a/homeassistant/components/technove/coordinator.py b/homeassistant/components/technove/coordinator.py index 8527c6e543a..53108463301 100644 --- a/homeassistant/components/technove/coordinator.py +++ b/homeassistant/components/technove/coordinator.py @@ -2,10 +2,9 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from technove import Station as TechnoVEStation, TechnoVE, TechnoVEError +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -13,22 +12,24 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN, LOGGER, SCAN_INTERVAL -if TYPE_CHECKING: - from . import TechnoVEConfigEntry +type TechnoVEConfigEntry = ConfigEntry[TechnoVEDataUpdateCoordinator] class TechnoVEDataUpdateCoordinator(DataUpdateCoordinator[TechnoVEStation]): """Class to manage fetching TechnoVE data from single endpoint.""" - def __init__(self, hass: HomeAssistant, entry: TechnoVEConfigEntry) -> None: + config_entry: TechnoVEConfigEntry + + def __init__(self, hass: HomeAssistant, config_entry: TechnoVEConfigEntry) -> None: """Initialize global TechnoVE data updater.""" self.technove = TechnoVE( - entry.data[CONF_HOST], + config_entry.data[CONF_HOST], session=async_get_clientsession(hass), ) super().__init__( hass, LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=SCAN_INTERVAL, ) diff --git a/homeassistant/components/technove/diagnostics.py b/homeassistant/components/technove/diagnostics.py index f070d58ab6f..7ac0f6f44fd 100644 --- a/homeassistant/components/technove/diagnostics.py +++ b/homeassistant/components/technove/diagnostics.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.diagnostics import async_redact_data from homeassistant.core import HomeAssistant -from . import TechnoVEConfigEntry +from .coordinator import TechnoVEConfigEntry TO_REDACT = {"unique_id", "mac_address"} diff --git a/homeassistant/components/technove/number.py b/homeassistant/components/technove/number.py index a1cf094c6bf..11d8f281276 100644 --- a/homeassistant/components/technove/number.py +++ b/homeassistant/components/technove/number.py @@ -17,11 +17,10 @@ from homeassistant.components.number import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TechnoVEConfigEntry from .const import DOMAIN -from .coordinator import TechnoVEDataUpdateCoordinator +from .coordinator import TechnoVEConfigEntry, TechnoVEDataUpdateCoordinator from .entity import TechnoVEEntity from .helpers import technove_exception_handler @@ -66,7 +65,7 @@ NUMBERS = [ async def async_setup_entry( hass: HomeAssistant, entry: TechnoVEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up TechnoVE number entity based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/technove/sensor.py b/homeassistant/components/technove/sensor.py index e16ac23f89c..398c1911cd4 100644 --- a/homeassistant/components/technove/sensor.py +++ b/homeassistant/components/technove/sensor.py @@ -21,11 +21,10 @@ from homeassistant.const import ( UnitOfEnergy, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import TechnoVEConfigEntry -from .coordinator import TechnoVEDataUpdateCoordinator +from .coordinator import TechnoVEConfigEntry, TechnoVEDataUpdateCoordinator from .entity import TechnoVEEntity STATUS_TYPE = [s.value for s in Status if s != Status.UNKNOWN] @@ -122,7 +121,7 @@ SENSORS: tuple[TechnoVESensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TechnoVEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" async_add_entities( diff --git a/homeassistant/components/technove/switch.py b/homeassistant/components/technove/switch.py index a8ad7581da5..19688075b35 100644 --- a/homeassistant/components/technove/switch.py +++ b/homeassistant/components/technove/switch.py @@ -12,11 +12,10 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TechnoVEConfigEntry from .const import DOMAIN -from .coordinator import TechnoVEDataUpdateCoordinator +from .coordinator import TechnoVEConfigEntry, TechnoVEDataUpdateCoordinator from .entity import TechnoVEEntity from .helpers import technove_exception_handler @@ -80,7 +79,7 @@ SWITCHES = [ async def async_setup_entry( hass: HomeAssistant, entry: TechnoVEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up TechnoVE switch based on a config entry.""" diff --git a/homeassistant/components/tedee/binary_sensor.py b/homeassistant/components/tedee/binary_sensor.py index 4f167619f04..a01b889ef8f 100644 --- a/homeassistant/components/tedee/binary_sensor.py +++ b/homeassistant/components/tedee/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import TedeeConfigEntry from .entity import TedeeDescriptionEntity @@ -64,7 +64,7 @@ ENTITIES: tuple[TedeeBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TedeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tedee sensor entity.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/tedee/lock.py b/homeassistant/components/tedee/lock.py index 482cd039a98..da6db242db3 100644 --- a/homeassistant/components/tedee/lock.py +++ b/homeassistant/components/tedee/lock.py @@ -7,7 +7,7 @@ from aiotedee import TedeeClientException, TedeeLock, TedeeLockState from homeassistant.components.lock import LockEntity, LockEntityFeature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import TedeeApiCoordinator, TedeeConfigEntry @@ -19,7 +19,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: TedeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tedee lock entity.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/tedee/sensor.py b/homeassistant/components/tedee/sensor.py index 828793b4458..a697d36be50 100644 --- a/homeassistant/components/tedee/sensor.py +++ b/homeassistant/components/tedee/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import TedeeConfigEntry from .entity import TedeeDescriptionEntity @@ -53,7 +53,7 @@ ENTITIES: tuple[TedeeSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TedeeConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tedee sensor entity.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/telegram_bot/__init__.py b/homeassistant/components/telegram_bot/__init__.py index fa3ec1dc4f7..b3c09049ae5 100644 --- a/homeassistant/components/telegram_bot/__init__.py +++ b/homeassistant/components/telegram_bot/__init__.py @@ -756,7 +756,8 @@ class TelegramNotificationService: message_thread_id=params[ATTR_MESSAGE_THREAD_ID], context=context, ) - msg_ids[chat_id] = msg.id + if msg is not None: + msg_ids[chat_id] = msg.id return msg_ids async def delete_message(self, chat_id=None, context=None, **kwargs): diff --git a/homeassistant/components/tellduslive/binary_sensor.py b/homeassistant/components/tellduslive/binary_sensor.py index 33f936beb54..65301708646 100644 --- a/homeassistant/components/tellduslive/binary_sensor.py +++ b/homeassistant/components/tellduslive/binary_sensor.py @@ -5,7 +5,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TELLDUS_DISCOVERY_NEW from .entity import TelldusLiveEntity @@ -14,7 +14,7 @@ from .entity import TelldusLiveEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tellduslive sensors dynamically.""" diff --git a/homeassistant/components/tellduslive/cover.py b/homeassistant/components/tellduslive/cover.py index d55a72cd633..2554acc428c 100644 --- a/homeassistant/components/tellduslive/cover.py +++ b/homeassistant/components/tellduslive/cover.py @@ -7,7 +7,7 @@ from homeassistant.components.cover import CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TelldusLiveClient from .const import DOMAIN, TELLDUS_DISCOVERY_NEW @@ -17,7 +17,7 @@ from .entity import TelldusLiveEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tellduslive sensors dynamically.""" diff --git a/homeassistant/components/tellduslive/light.py b/homeassistant/components/tellduslive/light.py index 005bf97d8c0..9f291bb845a 100644 --- a/homeassistant/components/tellduslive/light.py +++ b/homeassistant/components/tellduslive/light.py @@ -8,7 +8,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEnti from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TELLDUS_DISCOVERY_NEW from .entity import TelldusLiveEntity @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tellduslive sensors dynamically.""" diff --git a/homeassistant/components/tellduslive/sensor.py b/homeassistant/components/tellduslive/sensor.py index 9bd2b1fe599..782f240cc41 100644 --- a/homeassistant/components/tellduslive/sensor.py +++ b/homeassistant/components/tellduslive/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TELLDUS_DISCOVERY_NEW from .entity import TelldusLiveEntity @@ -121,7 +121,7 @@ SENSOR_TYPES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tellduslive sensors dynamically.""" diff --git a/homeassistant/components/tellduslive/switch.py b/homeassistant/components/tellduslive/switch.py index bd770ab08f5..3ca2ba066ab 100644 --- a/homeassistant/components/tellduslive/switch.py +++ b/homeassistant/components/tellduslive/switch.py @@ -7,7 +7,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TELLDUS_DISCOVERY_NEW from .entity import TelldusLiveEntity @@ -16,7 +16,7 @@ from .entity import TelldusLiveEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tellduslive sensors dynamically.""" diff --git a/homeassistant/components/template/alarm_control_panel.py b/homeassistant/components/template/alarm_control_panel.py index a67e2969f9a..0a468994295 100644 --- a/homeassistant/components/template/alarm_control_panel.py +++ b/homeassistant/components/template/alarm_control_panel.py @@ -31,7 +31,10 @@ from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id from homeassistant.helpers.entity import async_generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -146,7 +149,7 @@ async def _async_create_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/binary_sensor.py b/homeassistant/components/template/binary_sensor.py index 3c6e4899502..7ef64e8077b 100644 --- a/homeassistant/components/template/binary_sensor.py +++ b/homeassistant/components/template/binary_sensor.py @@ -43,7 +43,10 @@ from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv, selector, template from homeassistant.helpers.device import async_device_info_to_link_from_device_id from homeassistant.helpers.entity import async_generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_call_later, async_track_point_in_utc_time from homeassistant.helpers.restore_state import ExtraStoredData, RestoreEntity from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -150,7 +153,7 @@ PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend( @callback def _async_create_template_tracking_entities( - async_add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback, hass: HomeAssistant, definitions: list[dict], unique_id_prefix: str | None, @@ -209,7 +212,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/button.py b/homeassistant/components/template/button.py index 67ce7e7a16b..f43fc242bba 100644 --- a/homeassistant/components/template/button.py +++ b/homeassistant/components/template/button.py @@ -19,7 +19,10 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -93,7 +96,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/image.py b/homeassistant/components/template/image.py index ba85418c339..5afbca55cbb 100644 --- a/homeassistant/components/template/image.py +++ b/homeassistant/components/template/image.py @@ -20,7 +20,10 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -96,7 +99,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/number.py b/homeassistant/components/template/number.py index 90dd555ca42..661dbb45dc1 100644 --- a/homeassistant/components/template/number.py +++ b/homeassistant/components/template/number.py @@ -27,7 +27,10 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -121,7 +124,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/select.py b/homeassistant/components/template/select.py index bd37ca1015c..a42ee3d0612 100644 --- a/homeassistant/components/template/select.py +++ b/homeassistant/components/template/select.py @@ -24,7 +24,10 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -115,7 +118,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/sensor.py b/homeassistant/components/template/sensor.py index ee24407699d..ca3736ebf76 100644 --- a/homeassistant/components/template/sensor.py +++ b/homeassistant/components/template/sensor.py @@ -44,7 +44,10 @@ from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv, selector, template from homeassistant.helpers.device import async_device_info_to_link_from_device_id from homeassistant.helpers.entity import async_generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.trigger_template_entity import TEMPLATE_SENSOR_BASE_SCHEMA from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -178,7 +181,7 @@ _LOGGER = logging.getLogger(__name__) @callback def _async_create_template_tracking_entities( - async_add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback | AddConfigEntryEntitiesCallback, hass: HomeAssistant, definitions: list[dict], unique_id_prefix: str | None, @@ -237,7 +240,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/template/switch.py b/homeassistant/components/template/switch.py index bddb51e5e67..756866cfd44 100644 --- a/homeassistant/components/template/switch.py +++ b/homeassistant/components/template/switch.py @@ -28,7 +28,10 @@ from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv, selector from homeassistant.helpers.device import async_device_info_to_link_from_device_id from homeassistant.helpers.entity import async_generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -104,7 +107,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize config entry.""" _options = dict(config_entry.options) diff --git a/homeassistant/components/tesla_fleet/__init__.py b/homeassistant/components/tesla_fleet/__init__.py index 634e8f845f9..27bfb9134ab 100644 --- a/homeassistant/components/tesla_fleet/__init__.py +++ b/homeassistant/components/tesla_fleet/__init__.py @@ -139,7 +139,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslaFleetConfigEntry) - api = VehicleSigned(tesla.vehicle, vin) else: api = VehicleSpecific(tesla.vehicle, vin) - coordinator = TeslaFleetVehicleDataCoordinator(hass, api, product) + coordinator = TeslaFleetVehicleDataCoordinator(hass, entry, api, product) await coordinator.async_config_entry_first_refresh() @@ -175,9 +175,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslaFleetConfigEntry) - api = EnergySpecific(tesla.energy, site_id) - live_coordinator = TeslaFleetEnergySiteLiveCoordinator(hass, api) - history_coordinator = TeslaFleetEnergySiteHistoryCoordinator(hass, api) - info_coordinator = TeslaFleetEnergySiteInfoCoordinator(hass, api, product) + live_coordinator = TeslaFleetEnergySiteLiveCoordinator(hass, entry, api) + history_coordinator = TeslaFleetEnergySiteHistoryCoordinator( + hass, entry, api + ) + info_coordinator = TeslaFleetEnergySiteInfoCoordinator( + hass, entry, api, product + ) await live_coordinator.async_config_entry_first_refresh() await history_coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/tesla_fleet/binary_sensor.py b/homeassistant/components/tesla_fleet/binary_sensor.py index b92ef9233d1..886fe304c91 100644 --- a/homeassistant/components/tesla_fleet/binary_sensor.py +++ b/homeassistant/components/tesla_fleet/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TeslaFleetConfigEntry @@ -179,7 +179,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tesla Fleet binary sensor platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/button.py b/homeassistant/components/tesla_fleet/button.py index aea0f91a97c..2ddce2d517b 100644 --- a/homeassistant/components/tesla_fleet/button.py +++ b/homeassistant/components/tesla_fleet/button.py @@ -10,7 +10,7 @@ from tesla_fleet_api.const import Scope from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .entity import TeslaFleetVehicleEntity @@ -61,7 +61,7 @@ DESCRIPTIONS: tuple[TeslaFleetButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet Button platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/climate.py b/homeassistant/components/tesla_fleet/climate.py index 06e9c9d7c64..f752509ee17 100644 --- a/homeassistant/components/tesla_fleet/climate.py +++ b/homeassistant/components/tesla_fleet/climate.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .const import DOMAIN, TeslaFleetClimateSide @@ -38,7 +38,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tesla Fleet Climate platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/coordinator.py b/homeassistant/components/tesla_fleet/coordinator.py index 4d99319d49f..129f460ff90 100644 --- a/homeassistant/components/tesla_fleet/coordinator.py +++ b/homeassistant/components/tesla_fleet/coordinator.py @@ -1,9 +1,11 @@ """Tesla Fleet Data Coordinator.""" +from __future__ import annotations + from datetime import datetime, timedelta from random import randint from time import time -from typing import Any +from typing import TYPE_CHECKING, Any from tesla_fleet_api import EnergySpecific, VehicleSpecific from tesla_fleet_api.const import TeslaEnergyPeriod, VehicleDataEndpoint @@ -21,6 +23,9 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import TeslaFleetConfigEntry + from .const import ENERGY_HISTORY_FIELDS, LOGGER, TeslaFleetState VEHICLE_INTERVAL_SECONDS = 300 @@ -57,18 +62,24 @@ def flatten(data: dict[str, Any], parent: str | None = None) -> dict[str, Any]: class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching data from the TeslaFleet API.""" + config_entry: TeslaFleetConfigEntry updated_once: bool pre2021: bool last_active: datetime rate: RateCalculator def __init__( - self, hass: HomeAssistant, api: VehicleSpecific, product: dict + self, + hass: HomeAssistant, + config_entry: TeslaFleetConfigEntry, + api: VehicleSpecific, + product: dict, ) -> None: """Initialize TeslaFleet Vehicle Update Coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Tesla Fleet Vehicle", update_interval=VEHICLE_INTERVAL, ) @@ -141,13 +152,20 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): class TeslaFleetEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site live status from the TeslaFleet API.""" + config_entry: TeslaFleetConfigEntry updated_once: bool - def __init__(self, hass: HomeAssistant, api: EnergySpecific) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslaFleetConfigEntry, + api: EnergySpecific, + ) -> None: """Initialize TeslaFleet Energy Site Live coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Tesla Fleet Energy Site Live", update_interval=timedelta(seconds=10), ) @@ -188,11 +206,19 @@ class TeslaFleetEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]) class TeslaFleetEnergySiteHistoryCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site history import and export from the Tesla Fleet API.""" - def __init__(self, hass: HomeAssistant, api: EnergySpecific) -> None: + config_entry: TeslaFleetConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslaFleetConfigEntry, + api: EnergySpecific, + ) -> None: """Initialize Tesla Fleet Energy Site History coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=f"Tesla Fleet Energy History {api.energy_site_id}", update_interval=timedelta(seconds=300), ) @@ -243,13 +269,21 @@ class TeslaFleetEnergySiteHistoryCoordinator(DataUpdateCoordinator[dict[str, Any class TeslaFleetEnergySiteInfoCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site info from the TeslaFleet API.""" + config_entry: TeslaFleetConfigEntry updated_once: bool - def __init__(self, hass: HomeAssistant, api: EnergySpecific, product: dict) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslaFleetConfigEntry, + api: EnergySpecific, + product: dict, + ) -> None: """Initialize TeslaFleet Energy Info coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Tesla Fleet Energy Site Info", update_interval=timedelta(seconds=15), ) diff --git a/homeassistant/components/tesla_fleet/cover.py b/homeassistant/components/tesla_fleet/cover.py index f270734424f..701b107f9f9 100644 --- a/homeassistant/components/tesla_fleet/cover.py +++ b/homeassistant/components/tesla_fleet/cover.py @@ -12,7 +12,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .entity import TeslaFleetVehicleEntity @@ -28,7 +28,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet cover platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/device_tracker.py b/homeassistant/components/tesla_fleet/device_tracker.py index d6dcef895a6..19bf353c62d 100644 --- a/homeassistant/components/tesla_fleet/device_tracker.py +++ b/homeassistant/components/tesla_fleet/device_tracker.py @@ -6,7 +6,7 @@ from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_HOME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .entity import TeslaFleetVehicleEntity @@ -14,7 +14,9 @@ from .models import TeslaFleetVehicleData async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tesla Fleet device tracker platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/lock.py b/homeassistant/components/tesla_fleet/lock.py index 32998d409be..cdb1d4b066b 100644 --- a/homeassistant/components/tesla_fleet/lock.py +++ b/homeassistant/components/tesla_fleet/lock.py @@ -9,7 +9,7 @@ from tesla_fleet_api.const import Scope from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .const import DOMAIN @@ -25,7 +25,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet lock platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/media_player.py b/homeassistant/components/tesla_fleet/media_player.py index 455c990077d..89f0768f082 100644 --- a/homeassistant/components/tesla_fleet/media_player.py +++ b/homeassistant/components/tesla_fleet/media_player.py @@ -11,7 +11,7 @@ from homeassistant.components.media_player import ( MediaPlayerState, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .entity import TeslaFleetVehicleEntity @@ -33,7 +33,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tesla Fleet Media platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/number.py b/homeassistant/components/tesla_fleet/number.py index b806b4dbc77..a1123ab9553 100644 --- a/homeassistant/components/tesla_fleet/number.py +++ b/homeassistant/components/tesla_fleet/number.py @@ -18,7 +18,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import PERCENTAGE, PRECISION_WHOLE, UnitOfElectricCurrent from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from . import TeslaFleetConfigEntry @@ -95,7 +95,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[TeslaFleetNumberBatteryEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet number platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/select.py b/homeassistant/components/tesla_fleet/select.py index 515a0e7c2e7..1c495657bc1 100644 --- a/homeassistant/components/tesla_fleet/select.py +++ b/homeassistant/components/tesla_fleet/select.py @@ -10,7 +10,7 @@ from tesla_fleet_api.const import EnergyExportMode, EnergyOperationMode, Scope, from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslaFleetConfigEntry from .entity import TeslaFleetEnergyInfoEntity, TeslaFleetVehicleEntity @@ -78,7 +78,7 @@ SEAT_HEATER_DESCRIPTIONS: tuple[SeatHeaterDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet select platform from a config entry.""" diff --git a/homeassistant/components/tesla_fleet/sensor.py b/homeassistant/components/tesla_fleet/sensor.py index c1d38bf85c5..64ecc35469b 100644 --- a/homeassistant/components/tesla_fleet/sensor.py +++ b/homeassistant/components/tesla_fleet/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util from homeassistant.util.variance import ignore_variance @@ -446,7 +446,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tesla Fleet sensor platform from a config entry.""" async_add_entities( diff --git a/homeassistant/components/tesla_fleet/switch.py b/homeassistant/components/tesla_fleet/switch.py index 054ea84cbe1..614af8772cc 100644 --- a/homeassistant/components/tesla_fleet/switch.py +++ b/homeassistant/components/tesla_fleet/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TeslaFleetConfigEntry @@ -94,7 +94,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslaFleetSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslaFleetConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the TeslaFleet Switch platform from a config entry.""" diff --git a/homeassistant/components/tesla_wall_connector/binary_sensor.py b/homeassistant/components/tesla_wall_connector/binary_sensor.py index f7ef385b8ed..6d60162412e 100644 --- a/homeassistant/components/tesla_wall_connector/binary_sensor.py +++ b/homeassistant/components/tesla_wall_connector/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WallConnectorData from .const import DOMAIN, WALLCONNECTOR_DATA_VITALS @@ -48,7 +48,7 @@ WALL_CONNECTOR_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Wall Connector sensor devices.""" wall_connector_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/tesla_wall_connector/sensor.py b/homeassistant/components/tesla_wall_connector/sensor.py index a50c81c912e..c6c63a93edb 100644 --- a/homeassistant/components/tesla_wall_connector/sensor.py +++ b/homeassistant/components/tesla_wall_connector/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WallConnectorData from .const import DOMAIN, WALLCONNECTOR_DATA_LIFETIME, WALLCONNECTOR_DATA_VITALS @@ -187,7 +187,7 @@ WALL_CONNECTOR_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Wall Connector sensor devices.""" wall_connector_data = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/teslemetry/__init__.py b/homeassistant/components/teslemetry/__init__.py index 6e60b34825f..eef974cc5a7 100644 --- a/homeassistant/components/teslemetry/__init__.py +++ b/homeassistant/components/teslemetry/__init__.py @@ -112,7 +112,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslemetryConfigEntry) - product.pop("cached_data", None) vin = product["vin"] api = VehicleSpecific(teslemetry.vehicle, vin) - coordinator = TeslemetryVehicleDataCoordinator(hass, api, product) + coordinator = TeslemetryVehicleDataCoordinator(hass, entry, api, product) device = DeviceInfo( identifiers={(DOMAIN, vin)}, manufacturer="Tesla", @@ -177,15 +177,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslemetryConfigEntry) - TeslemetryEnergyData( api=api, live_coordinator=( - TeslemetryEnergySiteLiveCoordinator(hass, api, live_status) + TeslemetryEnergySiteLiveCoordinator( + hass, entry, api, live_status + ) if isinstance(live_status, dict) else None ), info_coordinator=TeslemetryEnergySiteInfoCoordinator( - hass, api, product + hass, entry, api, product ), history_coordinator=( - TeslemetryEnergyHistoryCoordinator(hass, api) + TeslemetryEnergyHistoryCoordinator(hass, entry, api) if powerwall else None ), @@ -242,7 +244,9 @@ async def async_unload_entry(hass: HomeAssistant, entry: TeslemetryConfigEntry) return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) -async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_migrate_entry( + hass: HomeAssistant, config_entry: TeslemetryConfigEntry +) -> bool: """Migrate config entry.""" if config_entry.version > 1: return False @@ -282,7 +286,7 @@ def create_handle_vehicle_stream(vin: str, coordinator) -> Callable[[dict], None async def async_setup_stream( - hass: HomeAssistant, entry: ConfigEntry, vehicle: TeslemetryVehicleData + hass: HomeAssistant, entry: TeslemetryConfigEntry, vehicle: TeslemetryVehicleData ): """Set up the stream for a vehicle.""" diff --git a/homeassistant/components/teslemetry/binary_sensor.py b/homeassistant/components/teslemetry/binary_sensor.py index 0b6823f8b61..9d14df4501b 100644 --- a/homeassistant/components/teslemetry/binary_sensor.py +++ b/homeassistant/components/teslemetry/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import StateType @@ -377,7 +377,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry binary sensor platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/button.py b/homeassistant/components/teslemetry/button.py index ceeda265795..4ca2fd9b166 100644 --- a/homeassistant/components/teslemetry/button.py +++ b/homeassistant/components/teslemetry/button.py @@ -10,7 +10,7 @@ from tesla_fleet_api.const import Scope from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslemetryConfigEntry from .entity import TeslemetryVehicleEntity @@ -61,7 +61,7 @@ DESCRIPTIONS: tuple[TeslemetryButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry Button platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/climate.py b/homeassistant/components/teslemetry/climate.py index 95b769a1c2d..86811131ab6 100644 --- a/homeassistant/components/teslemetry/climate.py +++ b/homeassistant/components/teslemetry/climate.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslemetryConfigEntry from .const import DOMAIN, TeslemetryClimateSide @@ -38,7 +38,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry Climate platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/coordinator.py b/homeassistant/components/teslemetry/coordinator.py index d39402c622c..0cd2a5a62d6 100644 --- a/homeassistant/components/teslemetry/coordinator.py +++ b/homeassistant/components/teslemetry/coordinator.py @@ -1,7 +1,9 @@ """Teslemetry Data Coordinator.""" +from __future__ import annotations + from datetime import datetime, timedelta -from typing import Any +from typing import TYPE_CHECKING, Any from tesla_fleet_api import EnergySpecific, VehicleSpecific from tesla_fleet_api.const import TeslaEnergyPeriod, VehicleDataEndpoint @@ -15,6 +17,9 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import TeslemetryConfigEntry + from .const import ENERGY_HISTORY_FIELDS, LOGGER from .helpers import flatten @@ -37,15 +42,21 @@ ENDPOINTS = [ class TeslemetryVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching data from the Teslemetry API.""" + config_entry: TeslemetryConfigEntry last_active: datetime def __init__( - self, hass: HomeAssistant, api: VehicleSpecific, product: dict + self, + hass: HomeAssistant, + config_entry: TeslemetryConfigEntry, + api: VehicleSpecific, + product: dict, ) -> None: """Initialize Teslemetry Vehicle Update Coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Teslemetry Vehicle", update_interval=VEHICLE_INTERVAL, ) @@ -69,13 +80,21 @@ class TeslemetryVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]): class TeslemetryEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site live status from the Teslemetry API.""" + config_entry: TeslemetryConfigEntry updated_once: bool - def __init__(self, hass: HomeAssistant, api: EnergySpecific, data: dict) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslemetryConfigEntry, + api: EnergySpecific, + data: dict, + ) -> None: """Initialize Teslemetry Energy Site Live coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Teslemetry Energy Site Live", update_interval=ENERGY_LIVE_INTERVAL, ) @@ -108,11 +127,20 @@ class TeslemetryEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]) class TeslemetryEnergySiteInfoCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site info from the Teslemetry API.""" - def __init__(self, hass: HomeAssistant, api: EnergySpecific, product: dict) -> None: + config_entry: TeslemetryConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslemetryConfigEntry, + api: EnergySpecific, + product: dict, + ) -> None: """Initialize Teslemetry Energy Info coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="Teslemetry Energy Site Info", update_interval=ENERGY_INFO_INTERVAL, ) @@ -135,11 +163,19 @@ class TeslemetryEnergySiteInfoCoordinator(DataUpdateCoordinator[dict[str, Any]]) class TeslemetryEnergyHistoryCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site info from the Teslemetry API.""" - def __init__(self, hass: HomeAssistant, api: EnergySpecific) -> None: + config_entry: TeslemetryConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: TeslemetryConfigEntry, + api: EnergySpecific, + ) -> None: """Initialize Teslemetry Energy Info coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name=f"Teslemetry Energy History {api.energy_site_id}", update_interval=ENERGY_HISTORY_INTERVAL, ) diff --git a/homeassistant/components/teslemetry/cover.py b/homeassistant/components/teslemetry/cover.py index 4cc15b6feb8..de91f43f084 100644 --- a/homeassistant/components/teslemetry/cover.py +++ b/homeassistant/components/teslemetry/cover.py @@ -15,7 +15,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import TeslemetryConfigEntry @@ -36,7 +36,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry cover platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/device_tracker.py b/homeassistant/components/teslemetry/device_tracker.py index 42c8fea8d09..6a758e68497 100644 --- a/homeassistant/components/teslemetry/device_tracker.py +++ b/homeassistant/components/teslemetry/device_tracker.py @@ -14,7 +14,7 @@ from homeassistant.components.device_tracker.config_entry import ( ) from homeassistant.const import STATE_HOME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import TeslemetryConfigEntry @@ -68,7 +68,7 @@ DESCRIPTIONS: tuple[TeslemetryDeviceTrackerEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry device tracker platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/lock.py b/homeassistant/components/teslemetry/lock.py index 18b88273bec..68505a12a13 100644 --- a/homeassistant/components/teslemetry/lock.py +++ b/homeassistant/components/teslemetry/lock.py @@ -10,7 +10,7 @@ from tesla_fleet_api.const import Scope from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import TeslemetryConfigEntry @@ -31,7 +31,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry lock platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/media_player.py b/homeassistant/components/teslemetry/media_player.py index e0e144ffe3a..1bfc9bf66dc 100644 --- a/homeassistant/components/teslemetry/media_player.py +++ b/homeassistant/components/teslemetry/media_player.py @@ -11,7 +11,7 @@ from homeassistant.components.media_player import ( MediaPlayerState, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslemetryConfigEntry from .entity import TeslemetryVehicleEntity @@ -33,7 +33,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry Media platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/number.py b/homeassistant/components/teslemetry/number.py index c44028f2da7..10c15a68b09 100644 --- a/homeassistant/components/teslemetry/number.py +++ b/homeassistant/components/teslemetry/number.py @@ -26,7 +26,7 @@ from homeassistant.const import ( UnitOfElectricCurrent, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from . import TeslemetryConfigEntry @@ -133,7 +133,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[TeslemetryNumberBatteryEntityDescription, ...] = async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry number platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/select.py b/homeassistant/components/teslemetry/select.py index d2e90a4f5c9..0d268e302de 100644 --- a/homeassistant/components/teslemetry/select.py +++ b/homeassistant/components/teslemetry/select.py @@ -13,7 +13,7 @@ from teslemetry_stream import TeslemetryStreamVehicle from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import TeslemetryConfigEntry @@ -170,7 +170,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySelectEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry select platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/sensor.py b/homeassistant/components/teslemetry/sensor.py index dd83ad04ed6..70315e92da0 100644 --- a/homeassistant/components/teslemetry/sensor.py +++ b/homeassistant/components/teslemetry/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util from homeassistant.util.variance import ignore_variance @@ -529,7 +529,7 @@ ENERGY_HISTORY_DESCRIPTIONS: tuple[SensorEntityDescription, ...] = tuple( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry sensor platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/switch.py b/homeassistant/components/teslemetry/switch.py index f810dee8554..83441e6c4f6 100644 --- a/homeassistant/components/teslemetry/switch.py +++ b/homeassistant/components/teslemetry/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TeslemetryConfigEntry @@ -94,7 +94,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry Switch platform from a config entry.""" diff --git a/homeassistant/components/teslemetry/update.py b/homeassistant/components/teslemetry/update.py index 670cd0e0eda..f560f25a8ff 100644 --- a/homeassistant/components/teslemetry/update.py +++ b/homeassistant/components/teslemetry/update.py @@ -8,7 +8,7 @@ from tesla_fleet_api.const import Scope from homeassistant.components.update import UpdateEntity, UpdateEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TeslemetryConfigEntry from .entity import TeslemetryVehicleEntity @@ -27,7 +27,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TeslemetryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Teslemetry update platform from a config entry.""" diff --git a/homeassistant/components/tessie/__init__.py b/homeassistant/components/tessie/__init__.py index a0bc58896e4..f73ecc7a729 100644 --- a/homeassistant/components/tessie/__init__.py +++ b/homeassistant/components/tessie/__init__.py @@ -69,6 +69,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TessieConfigEntry) -> bo vin=vehicle["vin"], data_coordinator=TessieStateUpdateCoordinator( hass, + entry, api_key=api_key, vin=vehicle["vin"], data=vehicle["last_state"], @@ -127,8 +128,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: TessieConfigEntry) -> bo TessieEnergyData( api=api, id=site_id, - live_coordinator=TessieEnergySiteLiveCoordinator(hass, api), - info_coordinator=TessieEnergySiteInfoCoordinator(hass, api), + live_coordinator=TessieEnergySiteLiveCoordinator( + hass, entry, api + ), + info_coordinator=TessieEnergySiteInfoCoordinator( + hass, entry, api + ), device=DeviceInfo( identifiers={(DOMAIN, str(site_id))}, manufacturer="Tesla", diff --git a/homeassistant/components/tessie/binary_sensor.py b/homeassistant/components/tessie/binary_sensor.py index fd6565b62b7..515339c3da8 100644 --- a/homeassistant/components/tessie/binary_sensor.py +++ b/homeassistant/components/tessie/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import TessieState @@ -177,7 +177,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie binary sensor platform from a config entry.""" async_add_entities( diff --git a/homeassistant/components/tessie/button.py b/homeassistant/components/tessie/button.py index bef9c2585f6..a370f504323 100644 --- a/homeassistant/components/tessie/button.py +++ b/homeassistant/components/tessie/button.py @@ -16,7 +16,7 @@ from tessie_api import ( from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .entity import TessieEntity @@ -50,7 +50,7 @@ DESCRIPTIONS: tuple[TessieButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie Button platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/climate.py b/homeassistant/components/tessie/climate.py index 1d26926aeaa..a8aa18132ee 100644 --- a/homeassistant/components/tessie/climate.py +++ b/homeassistant/components/tessie/climate.py @@ -19,7 +19,7 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import TessieClimateKeeper @@ -32,7 +32,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie Climate platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/coordinator.py b/homeassistant/components/tessie/coordinator.py index 4582260bfb2..b06fe6123a5 100644 --- a/homeassistant/components/tessie/coordinator.py +++ b/homeassistant/components/tessie/coordinator.py @@ -1,9 +1,11 @@ """Tessie Data Coordinator.""" +from __future__ import annotations + from datetime import timedelta from http import HTTPStatus import logging -from typing import Any +from typing import TYPE_CHECKING, Any from aiohttp import ClientResponseError from tesla_fleet_api import EnergySpecific @@ -15,6 +17,9 @@ from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import TessieConfigEntry + from .const import TessieStatus # This matches the update interval Tessie performs server side @@ -40,9 +45,12 @@ def flatten(data: dict[str, Any], parent: str | None = None) -> dict[str, Any]: class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching data from the Tessie API.""" + config_entry: TessieConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: TessieConfigEntry, api_key: str, vin: str, data: dict[str, Any], @@ -51,6 +59,7 @@ class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Tessie", update_interval=timedelta(seconds=TESSIE_SYNC_INTERVAL), ) @@ -90,11 +99,16 @@ class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): class TessieEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site live status from the Tessie API.""" - def __init__(self, hass: HomeAssistant, api: EnergySpecific) -> None: + config_entry: TessieConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: TessieConfigEntry, api: EnergySpecific + ) -> None: """Initialize Tessie Energy Site Live coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Tessie Energy Site Live", update_interval=TESSIE_FLEET_API_SYNC_INTERVAL, ) @@ -121,11 +135,16 @@ class TessieEnergySiteLiveCoordinator(DataUpdateCoordinator[dict[str, Any]]): class TessieEnergySiteInfoCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching energy site info from the Tessie API.""" - def __init__(self, hass: HomeAssistant, api: EnergySpecific) -> None: + config_entry: TessieConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: TessieConfigEntry, api: EnergySpecific + ) -> None: """Initialize Tessie Energy Info coordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name="Tessie Energy Site Info", update_interval=TESSIE_FLEET_API_SYNC_INTERVAL, ) diff --git a/homeassistant/components/tessie/cover.py b/homeassistant/components/tessie/cover.py index e739f8c074d..bfd7b1b816c 100644 --- a/homeassistant/components/tessie/cover.py +++ b/homeassistant/components/tessie/cover.py @@ -22,7 +22,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import TessieCoverStates @@ -35,7 +35,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie sensor platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/device_tracker.py b/homeassistant/components/tessie/device_tracker.py index df74cd2a7a7..fe81ed67337 100644 --- a/homeassistant/components/tessie/device_tracker.py +++ b/homeassistant/components/tessie/device_tracker.py @@ -4,7 +4,7 @@ from __future__ import annotations from homeassistant.components.device_tracker.config_entry import TrackerEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TessieConfigEntry @@ -17,7 +17,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie device tracker platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/lock.py b/homeassistant/components/tessie/lock.py index 76d58a9070c..66cb813b995 100644 --- a/homeassistant/components/tessie/lock.py +++ b/homeassistant/components/tessie/lock.py @@ -9,7 +9,7 @@ from tessie_api import lock, open_unlock_charge_port, unlock from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import DOMAIN, TessieChargeCableLockStates @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie sensor platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/media_player.py b/homeassistant/components/tessie/media_player.py index 7dfe568926b..139ee07ca5b 100644 --- a/homeassistant/components/tessie/media_player.py +++ b/homeassistant/components/tessie/media_player.py @@ -8,7 +8,7 @@ from homeassistant.components.media_player import ( MediaPlayerState, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .entity import TessieEntity @@ -26,7 +26,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie Media platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/number.py b/homeassistant/components/tessie/number.py index 74249d392a7..1e857345278 100644 --- a/homeassistant/components/tessie/number.py +++ b/homeassistant/components/tessie/number.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfSpeed, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.icon import icon_for_battery_level from . import TessieConfigEntry @@ -111,7 +111,7 @@ ENERGY_INFO_DESCRIPTIONS: tuple[TessieNumberBatteryEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie sensor platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/tessie/select.py b/homeassistant/components/tessie/select.py index 4dfe7088439..471372a68bd 100644 --- a/homeassistant/components/tessie/select.py +++ b/homeassistant/components/tessie/select.py @@ -9,7 +9,7 @@ from tessie_api import set_seat_cool, set_seat_heat from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import TessieSeatCoolerOptions, TessieSeatHeaterOptions @@ -38,7 +38,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie select platform from a config entry.""" diff --git a/homeassistant/components/tessie/sensor.py b/homeassistant/components/tessie/sensor.py index 323fa76ef1f..4f62e1b1855 100644 --- a/homeassistant/components/tessie/sensor.py +++ b/homeassistant/components/tessie/sensor.py @@ -28,7 +28,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util from homeassistant.util.variance import ignore_variance @@ -375,7 +375,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie sensor platform from a config entry.""" diff --git a/homeassistant/components/tessie/switch.py b/homeassistant/components/tessie/switch.py index dba00a85bb2..41134b38fda 100644 --- a/homeassistant/components/tessie/switch.py +++ b/homeassistant/components/tessie/switch.py @@ -26,7 +26,7 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TessieConfigEntry @@ -81,7 +81,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie Switch platform from a config entry.""" diff --git a/homeassistant/components/tessie/update.py b/homeassistant/components/tessie/update.py index f6198fa6c03..e9af673b1f4 100644 --- a/homeassistant/components/tessie/update.py +++ b/homeassistant/components/tessie/update.py @@ -8,7 +8,7 @@ from tessie_api import schedule_software_update from homeassistant.components.update import UpdateEntity, UpdateEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TessieConfigEntry from .const import TessieUpdateStatus @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TessieConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tessie Update platform from a config entry.""" data = entry.runtime_data diff --git a/homeassistant/components/thermobeacon/sensor.py b/homeassistant/components/thermobeacon/sensor.py index 53e86f37f11..916ec91359a 100644 --- a/homeassistant/components/thermobeacon/sensor.py +++ b/homeassistant/components/thermobeacon/sensor.py @@ -29,7 +29,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -113,7 +113,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ThermoBeacon BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/thermopro/sensor.py b/homeassistant/components/thermopro/sensor.py index 4aca6101685..4c9c6a4e42a 100644 --- a/homeassistant/components/thermopro/sensor.py +++ b/homeassistant/components/thermopro/sensor.py @@ -30,7 +30,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -111,7 +111,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ThermoPro BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/thethingsnetwork/coordinator.py b/homeassistant/components/thethingsnetwork/coordinator.py index 64608c2f064..78ffceecf84 100644 --- a/homeassistant/components/thethingsnetwork/coordinator.py +++ b/homeassistant/components/thethingsnetwork/coordinator.py @@ -19,11 +19,14 @@ _LOGGER = logging.getLogger(__name__) class TTNCoordinator(DataUpdateCoordinator[TTNClient.DATA_TYPE]): """TTN coordinator.""" + config_entry: ConfigEntry + def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize my coordinator.""" super().__init__( hass, _LOGGER, + config_entry=entry, # Name of the data. For logging purposes. name=f"TheThingsNetwork_{entry.data[CONF_APP_ID]}", # Polling interval. Will only be polled if there are subscribers. diff --git a/homeassistant/components/thethingsnetwork/sensor.py b/homeassistant/components/thethingsnetwork/sensor.py index 25dd2f1e1eb..ba512d07f18 100644 --- a/homeassistant/components/thethingsnetwork/sensor.py +++ b/homeassistant/components/thethingsnetwork/sensor.py @@ -7,7 +7,7 @@ from ttn_client import TTNSensorValue from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import CONF_APP_ID, DOMAIN @@ -17,7 +17,9 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add entities for TTN.""" diff --git a/homeassistant/components/threshold/binary_sensor.py b/homeassistant/components/threshold/binary_sensor.py index 3d52d2225be..3227f030812 100644 --- a/homeassistant/components/threshold/binary_sensor.py +++ b/homeassistant/components/threshold/binary_sensor.py @@ -33,7 +33,10 @@ from homeassistant.core import ( from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -90,7 +93,7 @@ PLATFORM_SCHEMA = vol.All( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize threshold config entry.""" registry = er.async_get(hass) diff --git a/homeassistant/components/tibber/coordinator.py b/homeassistant/components/tibber/coordinator.py index 78841f9db91..2de9ebd1ec6 100644 --- a/homeassistant/components/tibber/coordinator.py +++ b/homeassistant/components/tibber/coordinator.py @@ -33,11 +33,17 @@ class TibberDataCoordinator(DataUpdateCoordinator[None]): config_entry: ConfigEntry - def __init__(self, hass: HomeAssistant, tibber_connection: tibber.Tibber) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + tibber_connection: tibber.Tibber, + ) -> None: """Initialize the data handler.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"Tibber {tibber_connection.name}", update_interval=timedelta(minutes=20), ) diff --git a/homeassistant/components/tibber/notify.py b/homeassistant/components/tibber/notify.py index fdeeeba68ef..df6541591e0 100644 --- a/homeassistant/components/tibber/notify.py +++ b/homeassistant/components/tibber/notify.py @@ -12,13 +12,15 @@ from homeassistant.components.notify import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN as TIBBER_DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tibber notification entity.""" async_add_entities([TibberNotificationEntity(entry.entry_id)]) diff --git a/homeassistant/components/tibber/sensor.py b/homeassistant/components/tibber/sensor.py index c1ec7bf2a9e..9f87b8a8490 100644 --- a/homeassistant/components/tibber/sensor.py +++ b/homeassistant/components/tibber/sensor.py @@ -33,7 +33,7 @@ from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -261,7 +261,9 @@ SENSORS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tibber sensor.""" @@ -285,7 +287,7 @@ async def async_setup_entry( if home.has_active_subscription: entities.append(TibberSensorElPrice(home)) if coordinator is None: - coordinator = TibberDataCoordinator(hass, tibber_connection) + coordinator = TibberDataCoordinator(hass, entry, tibber_connection) entities.extend( TibberDataSensor(home, coordinator, entity_description) for entity_description in SENSORS @@ -531,7 +533,7 @@ class TibberRtEntityCreator: def __init__( self, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tibber_home: tibber.TibberHome, entity_registry: er.EntityRegistry, ) -> None: diff --git a/homeassistant/components/tile/binary_sensor.py b/homeassistant/components/tile/binary_sensor.py index 1719c793c0e..6abc80732a6 100644 --- a/homeassistant/components/tile/binary_sensor.py +++ b/homeassistant/components/tile/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import TileConfigEntry, TileCoordinator from .entity import TileEntity @@ -35,7 +35,9 @@ ENTITIES: tuple[TileBinarySensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: TileConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TileConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tile binary sensors.""" diff --git a/homeassistant/components/tile/device_tracker.py b/homeassistant/components/tile/device_tracker.py index 6a0aae1bdf9..66a3b8b0e27 100644 --- a/homeassistant/components/tile/device_tracker.py +++ b/homeassistant/components/tile/device_tracker.py @@ -6,7 +6,7 @@ import logging from homeassistant.components.device_tracker import TrackerEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import as_utc from .coordinator import TileConfigEntry, TileCoordinator @@ -26,7 +26,9 @@ ATTR_VOIP_STATE = "voip_state" async def async_setup_entry( - hass: HomeAssistant, entry: TileConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TileConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tile device trackers.""" diff --git a/homeassistant/components/tilt_ble/sensor.py b/homeassistant/components/tilt_ble/sensor.py index e8e1f902cd9..411484cf2fe 100644 --- a/homeassistant/components/tilt_ble/sensor.py +++ b/homeassistant/components/tilt_ble/sensor.py @@ -20,7 +20,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .const import DOMAIN @@ -86,7 +86,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Tilt Hydrometer BLE sensors.""" coordinator: PassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/time_date/sensor.py b/homeassistant/components/time_date/sensor.py index 1e86a1ba6c6..f05244e7680 100644 --- a/homeassistant/components/time_date/sensor.py +++ b/homeassistant/components/time_date/sensor.py @@ -18,7 +18,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DISPLAY_OPTIONS, EVENT_CORE_CONFIG_UPDATE from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -56,7 +59,9 @@ async def async_setup_platform( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Time & Date sensor.""" diff --git a/homeassistant/components/tod/binary_sensor.py b/homeassistant/components/tod/binary_sensor.py index 3ac90b5578c..1ab34861a6e 100644 --- a/homeassistant/components/tod/binary_sensor.py +++ b/homeassistant/components/tod/binary_sensor.py @@ -24,7 +24,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, event -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.sun import get_astral_event_date, get_astral_event_next from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -59,7 +62,7 @@ PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Times of the Day config entry.""" if hass.config.time_zone is None: diff --git a/homeassistant/components/todoist/calendar.py b/homeassistant/components/todoist/calendar.py index 8c61394d300..2e2873353c6 100644 --- a/homeassistant/components/todoist/calendar.py +++ b/homeassistant/components/todoist/calendar.py @@ -24,7 +24,10 @@ from homeassistant.core import Event, HomeAssistant, ServiceCall, callback from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -113,7 +116,9 @@ SCAN_INTERVAL = timedelta(minutes=1) async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Todoist calendar platform config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/todoist/todo.py b/homeassistant/components/todoist/todo.py index 490e4ad9f1a..202c51fb4c0 100644 --- a/homeassistant/components/todoist/todo.py +++ b/homeassistant/components/todoist/todo.py @@ -14,7 +14,7 @@ from homeassistant.components.todo import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -23,7 +23,9 @@ from .coordinator import TodoistCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Todoist todo platform config entry.""" coordinator: TodoistCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/binary_sensor.py b/homeassistant/components/tolo/binary_sensor.py index 845f8ed22e3..cb3ba46b604 100644 --- a/homeassistant/components/tolo/binary_sensor.py +++ b/homeassistant/components/tolo/binary_sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import ToloSaunaCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/button.py b/homeassistant/components/tolo/button.py index b7c4362ca7b..9e4c8c84be9 100644 --- a/homeassistant/components/tolo/button.py +++ b/homeassistant/components/tolo/button.py @@ -6,7 +6,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -16,7 +16,7 @@ from .entity import ToloSaunaCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/climate.py b/homeassistant/components/tolo/climate.py index 5e6428525c1..0df8635fca9 100644 --- a/homeassistant/components/tolo/climate.py +++ b/homeassistant/components/tolo/climate.py @@ -23,7 +23,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -33,7 +33,7 @@ from .entity import ToloSaunaCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate controls for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/coordinator.py b/homeassistant/components/tolo/coordinator.py index 632cc819f5a..729073b16c4 100644 --- a/homeassistant/components/tolo/coordinator.py +++ b/homeassistant/components/tolo/coordinator.py @@ -28,6 +28,8 @@ class ToloSaunaData(NamedTuple): class ToloSaunaUpdateCoordinator(DataUpdateCoordinator[ToloSaunaData]): """DataUpdateCoordinator for TOLO Sauna.""" + config_entry: ConfigEntry + def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: """Initialize ToloSaunaUpdateCoordinator.""" self.client = ToloClient( @@ -38,6 +40,7 @@ class ToloSaunaUpdateCoordinator(DataUpdateCoordinator[ToloSaunaData]): super().__init__( hass=hass, logger=_LOGGER, + config_entry=entry, name=f"{entry.title} ({entry.data[CONF_HOST]}) Data Update Coordinator", update_interval=timedelta(seconds=5), ) diff --git a/homeassistant/components/tolo/fan.py b/homeassistant/components/tolo/fan.py index 9e48778b507..7bddf775143 100644 --- a/homeassistant/components/tolo/fan.py +++ b/homeassistant/components/tolo/fan.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import ToloSaunaCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up fan controls for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/light.py b/homeassistant/components/tolo/light.py index eeb37305fe8..9ccd4a8e407 100644 --- a/homeassistant/components/tolo/light.py +++ b/homeassistant/components/tolo/light.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.light import ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import ToloSaunaCoordinatorEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up light controls for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/number.py b/homeassistant/components/tolo/number.py index 73505c5b251..902fb749d23 100644 --- a/homeassistant/components/tolo/number.py +++ b/homeassistant/components/tolo/number.py @@ -18,7 +18,7 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -68,7 +68,7 @@ NUMBERS = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number controls for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/select.py b/homeassistant/components/tolo/select.py index fee1ac1774e..b08f37e40ae 100644 --- a/homeassistant/components/tolo/select.py +++ b/homeassistant/components/tolo/select.py @@ -11,7 +11,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, AromaTherapySlot, LampMode from .coordinator import ToloSaunaUpdateCoordinator @@ -54,7 +54,7 @@ SELECTS = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select entities for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/sensor.py b/homeassistant/components/tolo/sensor.py index 0e94ec0ae1e..e97211c8e40 100644 --- a/homeassistant/components/tolo/sensor.py +++ b/homeassistant/components/tolo/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -89,7 +89,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up (non-binary, general) sensors for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tolo/switch.py b/homeassistant/components/tolo/switch.py index d39dd17f0f3..ce863053e26 100644 --- a/homeassistant/components/tolo/switch.py +++ b/homeassistant/components/tolo/switch.py @@ -11,7 +11,7 @@ from tololib import ToloClient, ToloStatus from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToloSaunaUpdateCoordinator @@ -45,7 +45,7 @@ SWITCHES = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch controls for TOLO Sauna.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tomorrowio/__init__.py b/homeassistant/components/tomorrowio/__init__.py index 73f62735e06..7d6b9ed3f73 100644 --- a/homeassistant/components/tomorrowio/__init__.py +++ b/homeassistant/components/tomorrowio/__init__.py @@ -29,7 +29,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # we will not use the class's lat and long so we can pass in garbage # lats and longs api = TomorrowioV4(api_key, 361.0, 361.0, unit_system="metric", session=session) - coordinator = TomorrowioDataUpdateCoordinator(hass, api) + coordinator = TomorrowioDataUpdateCoordinator(hass, entry, api) hass.data[DOMAIN][api_key] = coordinator await coordinator.async_setup_entry(entry) diff --git a/homeassistant/components/tomorrowio/coordinator.py b/homeassistant/components/tomorrowio/coordinator.py index 60b997e4c0d..2a6b3675792 100644 --- a/homeassistant/components/tomorrowio/coordinator.py +++ b/homeassistant/components/tomorrowio/coordinator.py @@ -116,14 +116,23 @@ def async_set_update_interval( class TomorrowioDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Define an object to hold Tomorrow.io data.""" - def __init__(self, hass: HomeAssistant, api: TomorrowioV4) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, api: TomorrowioV4 + ) -> None: """Initialize.""" self._api = api self.data = {CURRENT: {}, FORECASTS: {}} self.entry_id_to_location_dict: dict[str, str] = {} self._coordinator_ready: asyncio.Event | None = None - super().__init__(hass, LOGGER, name=f"{DOMAIN}_{self._api.api_key_masked}") + super().__init__( + hass, + LOGGER, + config_entry=config_entry, + name=f"{DOMAIN}_{self._api.api_key_masked}", + ) def add_entry_to_location_dict(self, entry: ConfigEntry) -> None: """Add an entry to the location dict.""" diff --git a/homeassistant/components/tomorrowio/sensor.py b/homeassistant/components/tomorrowio/sensor.py index 7ff17961b58..08e1991d831 100644 --- a/homeassistant/components/tomorrowio/sensor.py +++ b/homeassistant/components/tomorrowio/sensor.py @@ -34,7 +34,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import DistanceConverter, SpeedConverter from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM @@ -328,7 +328,7 @@ SENSOR_TYPES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = hass.data[DOMAIN][config_entry.data[CONF_API_KEY]] diff --git a/homeassistant/components/tomorrowio/weather.py b/homeassistant/components/tomorrowio/weather.py index 92b09500e7b..0a070a1b33b 100644 --- a/homeassistant/components/tomorrowio/weather.py +++ b/homeassistant/components/tomorrowio/weather.py @@ -33,7 +33,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sun import is_up from homeassistant.util import dt as dt_util @@ -66,7 +66,7 @@ from .entity import TomorrowioEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a config entry.""" coordinator = hass.data[DOMAIN][config_entry.data[CONF_API_KEY]] diff --git a/homeassistant/components/toon/binary_sensor.py b/homeassistant/components/toon/binary_sensor.py index 11b13a32ee5..eff8aed0a20 100644 --- a/homeassistant/components/toon/binary_sensor.py +++ b/homeassistant/components/toon/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToonDataUpdateCoordinator @@ -25,7 +25,9 @@ from .entity import ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Toon binary sensor based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/toon/climate.py b/homeassistant/components/toon/climate.py index 0c2e5b9b232..5538a0abd91 100644 --- a/homeassistant/components/toon/climate.py +++ b/homeassistant/components/toon/climate.py @@ -24,7 +24,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ToonDataUpdateCoordinator from .const import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP, DOMAIN @@ -33,7 +33,9 @@ from .helpers import toon_exception_handler async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Toon binary sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/toon/sensor.py b/homeassistant/components/toon/sensor.py index 09f36c88079..e5b155b409b 100644 --- a/homeassistant/components/toon/sensor.py +++ b/homeassistant/components/toon/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CURRENCY_EUR, DOMAIN, VOLUME_CM3, VOLUME_LMIN from .coordinator import ToonDataUpdateCoordinator @@ -36,7 +36,9 @@ from .entity import ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Toon sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/toon/switch.py b/homeassistant/components/toon/switch.py index deb2a12f2d0..d59a542d4d8 100644 --- a/homeassistant/components/toon/switch.py +++ b/homeassistant/components/toon/switch.py @@ -15,7 +15,7 @@ from toonapi import ( from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ToonDataUpdateCoordinator @@ -24,7 +24,9 @@ from .helpers import toon_exception_handler async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Toon switches based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/totalconnect/__init__.py b/homeassistant/components/totalconnect/__init__.py index 9f291ea15a6..a481fd41c84 100644 --- a/homeassistant/components/totalconnect/__init__.py +++ b/homeassistant/components/totalconnect/__init__.py @@ -3,18 +3,15 @@ from total_connect_client.client import TotalConnectClient from total_connect_client.exceptions import AuthenticationError -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from .const import AUTO_BYPASS, CONF_USERCODES -from .coordinator import TotalConnectDataUpdateCoordinator +from .coordinator import TotalConnectConfigEntry, TotalConnectDataUpdateCoordinator PLATFORMS = [Platform.ALARM_CONTROL_PANEL, Platform.BINARY_SENSOR, Platform.BUTTON] -type TotalConnectConfigEntry = ConfigEntry[TotalConnectDataUpdateCoordinator] - async def async_setup_entry( hass: HomeAssistant, entry: TotalConnectConfigEntry @@ -41,7 +38,7 @@ async def async_setup_entry( "TotalConnect authentication failed during setup" ) from exception - coordinator = TotalConnectDataUpdateCoordinator(hass, client) + coordinator = TotalConnectDataUpdateCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator diff --git a/homeassistant/components/totalconnect/alarm_control_panel.py b/homeassistant/components/totalconnect/alarm_control_panel.py index 021d1c7b886..9ed29ea01c8 100644 --- a/homeassistant/components/totalconnect/alarm_control_panel.py +++ b/homeassistant/components/totalconnect/alarm_control_panel.py @@ -12,14 +12,13 @@ from homeassistant.components.alarm_control_panel import ( AlarmControlPanelState, CodeFormat, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CODE_REQUIRED, DOMAIN -from .coordinator import TotalConnectDataUpdateCoordinator +from .coordinator import TotalConnectConfigEntry, TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity SERVICE_ALARM_ARM_AWAY_INSTANT = "arm_away_instant" @@ -27,7 +26,9 @@ SERVICE_ALARM_ARM_HOME_INSTANT = "arm_home_instant" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TotalConnectConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up TotalConnect alarm panels based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/totalconnect/binary_sensor.py b/homeassistant/components/totalconnect/binary_sensor.py index 9a3c2558999..2f3802dc9a6 100644 --- a/homeassistant/components/totalconnect/binary_sensor.py +++ b/homeassistant/components/totalconnect/binary_sensor.py @@ -12,12 +12,11 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import TotalConnectDataUpdateCoordinator +from .coordinator import TotalConnectConfigEntry, TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity, TotalConnectZoneEntity LOW_BATTERY = "low_battery" @@ -119,7 +118,9 @@ LOCATION_BINARY_SENSORS: tuple[TotalConnectAlarmBinarySensorEntityDescription, . async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TotalConnectConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up TotalConnect device sensors based on a config entry.""" sensors: list = [] diff --git a/homeassistant/components/totalconnect/button.py b/homeassistant/components/totalconnect/button.py index e228f03ec6b..eb85dcce1bf 100644 --- a/homeassistant/components/totalconnect/button.py +++ b/homeassistant/components/totalconnect/button.py @@ -7,12 +7,11 @@ from total_connect_client.location import TotalConnectLocation from total_connect_client.zone import TotalConnectZone from homeassistant.components.button import ButtonEntity, ButtonEntityDescription -from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import TotalConnectDataUpdateCoordinator +from .coordinator import TotalConnectConfigEntry, TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity, TotalConnectZoneEntity @@ -38,7 +37,9 @@ PANEL_BUTTONS: tuple[TotalConnectButtonEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TotalConnectConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up TotalConnect buttons based on a config entry.""" buttons: list = [] diff --git a/homeassistant/components/totalconnect/coordinator.py b/homeassistant/components/totalconnect/coordinator.py index 9b500db1951..673c168d204 100644 --- a/homeassistant/components/totalconnect/coordinator.py +++ b/homeassistant/components/totalconnect/coordinator.py @@ -20,17 +20,28 @@ from .const import DOMAIN SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) +type TotalConnectConfigEntry = ConfigEntry[TotalConnectDataUpdateCoordinator] + class TotalConnectDataUpdateCoordinator(DataUpdateCoordinator[None]): """Class to fetch data from TotalConnect.""" - config_entry: ConfigEntry + config_entry: TotalConnectConfigEntry - def __init__(self, hass: HomeAssistant, client: TotalConnectClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: TotalConnectConfigEntry, + client: TotalConnectClient, + ) -> None: """Initialize.""" self.client = client super().__init__( - hass, logger=_LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL + hass, + logger=_LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, ) async def _async_update_data(self) -> None: diff --git a/homeassistant/components/totalconnect/diagnostics.py b/homeassistant/components/totalconnect/diagnostics.py index 85f52ccc670..f42ed5e44c3 100644 --- a/homeassistant/components/totalconnect/diagnostics.py +++ b/homeassistant/components/totalconnect/diagnostics.py @@ -5,9 +5,10 @@ from __future__ import annotations from typing import Any from homeassistant.components.diagnostics import async_redact_data -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant +from .coordinator import TotalConnectConfigEntry + TO_REDACT = [ "username", "Password", @@ -22,7 +23,7 @@ TO_REDACT = [ async def async_get_config_entry_diagnostics( - hass: HomeAssistant, config_entry: ConfigEntry + hass: HomeAssistant, config_entry: TotalConnectConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" client = config_entry.runtime_data.client diff --git a/homeassistant/components/touchline_sl/__init__.py b/homeassistant/components/touchline_sl/__init__.py index 45a85185673..ba1da06ed5a 100644 --- a/homeassistant/components/touchline_sl/__init__.py +++ b/homeassistant/components/touchline_sl/__init__.py @@ -6,18 +6,15 @@ import asyncio from pytouchlinesl import TouchlineSL -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr from .const import DOMAIN -from .coordinator import TouchlineSLModuleCoordinator +from .coordinator import TouchlineSLConfigEntry, TouchlineSLModuleCoordinator PLATFORMS: list[Platform] = [Platform.CLIMATE] -type TouchlineSLConfigEntry = ConfigEntry[list[TouchlineSLModuleCoordinator]] - async def async_setup_entry(hass: HomeAssistant, entry: TouchlineSLConfigEntry) -> bool: """Set up Roth Touchline SL from a config entry.""" @@ -26,7 +23,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: TouchlineSLConfigEntry) ) coordinators: list[TouchlineSLModuleCoordinator] = [ - TouchlineSLModuleCoordinator(hass, module) for module in await account.modules() + TouchlineSLModuleCoordinator(hass, entry, module) + for module in await account.modules() ] await asyncio.gather( diff --git a/homeassistant/components/touchline_sl/climate.py b/homeassistant/components/touchline_sl/climate.py index 8a0ffc4cd86..7c5ea4ea9ca 100644 --- a/homeassistant/components/touchline_sl/climate.py +++ b/homeassistant/components/touchline_sl/climate.py @@ -10,17 +10,16 @@ from homeassistant.components.climate import ( ) from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TouchlineSLConfigEntry -from .coordinator import TouchlineSLModuleCoordinator +from .coordinator import TouchlineSLConfigEntry, TouchlineSLModuleCoordinator from .entity import TouchlineSLZoneEntity async def async_setup_entry( hass: HomeAssistant, entry: TouchlineSLConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Touchline devices.""" coordinators = entry.runtime_data diff --git a/homeassistant/components/touchline_sl/coordinator.py b/homeassistant/components/touchline_sl/coordinator.py index cd74ba6130f..dce616a81b3 100644 --- a/homeassistant/components/touchline_sl/coordinator.py +++ b/homeassistant/components/touchline_sl/coordinator.py @@ -10,6 +10,7 @@ from pytouchlinesl import Module, Zone from pytouchlinesl.client import RothAPIError from pytouchlinesl.client.models import GlobalScheduleModel +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -26,14 +27,22 @@ class TouchlineSLModuleData: schedules: dict[str, GlobalScheduleModel] +type TouchlineSLConfigEntry = ConfigEntry[list[TouchlineSLModuleCoordinator]] + + class TouchlineSLModuleCoordinator(DataUpdateCoordinator[TouchlineSLModuleData]): """A coordinator to manage the fetching of Touchline SL data.""" - def __init__(self, hass: HomeAssistant, module: Module) -> None: + config_entry: TouchlineSLConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: TouchlineSLConfigEntry, module: Module + ) -> None: """Initialize coordinator.""" super().__init__( hass, logger=_LOGGER, + config_entry=config_entry, name=f"Touchline SL ({module.name})", update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/tplink/binary_sensor.py b/homeassistant/components/tplink/binary_sensor.py index 6986765b110..38935595fe2 100644 --- a/homeassistant/components/tplink/binary_sensor.py +++ b/homeassistant/components/tplink/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .entity import CoordinatedTPLinkFeatureEntity, TPLinkFeatureEntityDescription @@ -73,7 +73,7 @@ BINARYSENSOR_DESCRIPTIONS_MAP = {desc.key: desc for desc in BINARY_SENSOR_DESCRI async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/button.py b/homeassistant/components/tplink/button.py index 4279a233d21..145adb79185 100644 --- a/homeassistant/components/tplink/button.py +++ b/homeassistant/components/tplink/button.py @@ -15,7 +15,7 @@ from homeassistant.components.button import ( ) from homeassistant.components.siren import DOMAIN as SIREN_DOMAIN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .deprecate import DeprecatedInfo @@ -95,7 +95,7 @@ BUTTON_DESCRIPTIONS_MAP = {desc.key: desc for desc in BUTTON_DESCRIPTIONS} async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up buttons.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/camera.py b/homeassistant/components/tplink/camera.py index b0f1f1a62c1..7b59678da8e 100644 --- a/homeassistant/components/tplink/camera.py +++ b/homeassistant/components/tplink/camera.py @@ -19,7 +19,7 @@ from homeassistant.components.camera import ( from homeassistant.config_entries import ConfigFlowContext from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .const import CONF_CAMERA_CREDENTIALS @@ -59,7 +59,7 @@ CAMERA_DESCRIPTIONS: tuple[TPLinkCameraEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up camera entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/climate.py b/homeassistant/components/tplink/climate.py index 7204c2a7665..66037d7476e 100644 --- a/homeassistant/components/tplink/climate.py +++ b/homeassistant/components/tplink/climate.py @@ -22,7 +22,7 @@ from homeassistant.components.climate import ( from homeassistant.const import PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry, legacy_device_id from .const import DOMAIN, UNIT_MAPPING @@ -71,7 +71,7 @@ CLIMATE_DESCRIPTIONS: tuple[TPLinkClimateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up climate entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/fan.py b/homeassistant/components/tplink/fan.py index 1c31d84b778..88396742b36 100644 --- a/homeassistant/components/tplink/fan.py +++ b/homeassistant/components/tplink/fan.py @@ -15,7 +15,7 @@ from homeassistant.components.fan import ( FanEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -59,7 +59,7 @@ FAN_DESCRIPTIONS: tuple[TPLinkFanEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up fans.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/light.py b/homeassistant/components/tplink/light.py index 718b5ed7120..b3cee1d3baf 100644 --- a/homeassistant/components/tplink/light.py +++ b/homeassistant/components/tplink/light.py @@ -29,7 +29,7 @@ from homeassistant.components.light import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import TPLinkConfigEntry, legacy_device_id @@ -196,7 +196,7 @@ LIGHT_EFFECT_DESCRIPTIONS: tuple[TPLinkLightEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lights.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/number.py b/homeassistant/components/tplink/number.py index a9d002c0083..252c4888d26 100644 --- a/homeassistant/components/tplink/number.py +++ b/homeassistant/components/tplink/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( NumberMode, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .entity import ( @@ -81,7 +81,7 @@ NUMBER_DESCRIPTIONS_MAP = {desc.key: desc for desc in NUMBER_DESCRIPTIONS} async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/select.py b/homeassistant/components/tplink/select.py index 8e9dee7b964..72042f571e6 100644 --- a/homeassistant/components/tplink/select.py +++ b/homeassistant/components/tplink/select.py @@ -13,7 +13,7 @@ from homeassistant.components.select import ( SelectEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .entity import ( @@ -53,7 +53,7 @@ SELECT_DESCRIPTIONS_MAP = {desc.key: desc for desc in SELECT_DESCRIPTIONS} async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up select entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/sensor.py b/homeassistant/components/tplink/sensor.py index 9b21ba775a9..cc35b1fd142 100644 --- a/homeassistant/components/tplink/sensor.py +++ b/homeassistant/components/tplink/sensor.py @@ -19,7 +19,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .const import UNIT_MAPPING @@ -271,7 +271,7 @@ SENSOR_DESCRIPTIONS_MAP = {desc.key: desc for desc in SENSOR_DESCRIPTIONS} async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/siren.py b/homeassistant/components/tplink/siren.py index 027fa2dd58f..65cb722052f 100644 --- a/homeassistant/components/tplink/siren.py +++ b/homeassistant/components/tplink/siren.py @@ -21,7 +21,7 @@ from homeassistant.components.siren import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry, legacy_device_id from .const import DOMAIN @@ -61,7 +61,7 @@ SIREN_DESCRIPTIONS: tuple[TPLinkSirenEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up siren entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/switch.py b/homeassistant/components/tplink/switch.py index f08753def26..3cb20d63cd7 100644 --- a/homeassistant/components/tplink/switch.py +++ b/homeassistant/components/tplink/switch.py @@ -14,7 +14,7 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .entity import ( @@ -85,7 +85,7 @@ SWITCH_DESCRIPTIONS_MAP = {desc.key: desc for desc in SWITCH_DESCRIPTIONS} async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink/vacuum.py b/homeassistant/components/tplink/vacuum.py index c62cd1d27c8..e948e778be4 100644 --- a/homeassistant/components/tplink/vacuum.py +++ b/homeassistant/components/tplink/vacuum.py @@ -16,7 +16,7 @@ from homeassistant.components.vacuum import ( VacuumEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TPLinkConfigEntry from .coordinator import TPLinkDataUpdateCoordinator @@ -63,7 +63,7 @@ VACUUM_DESCRIPTIONS: tuple[TPLinkVacuumEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TPLinkConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up vacuum entities.""" data = config_entry.runtime_data diff --git a/homeassistant/components/tplink_omada/__init__.py b/homeassistant/components/tplink_omada/__init__.py index 2d33a890510..06df118463b 100644 --- a/homeassistant/components/tplink_omada/__init__.py +++ b/homeassistant/components/tplink_omada/__init__.py @@ -55,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: OmadaConfigEntry) -> boo ) from ex site_client = await client.get_site_client(OmadaSite("", entry.data[CONF_SITE])) - controller = OmadaSiteController(hass, site_client) + controller = OmadaSiteController(hass, entry, site_client) await controller.initialize_first_refresh() entry.runtime_data = controller diff --git a/homeassistant/components/tplink_omada/binary_sensor.py b/homeassistant/components/tplink_omada/binary_sensor.py index 73d5f54b8b3..fb179634fd1 100644 --- a/homeassistant/components/tplink_omada/binary_sensor.py +++ b/homeassistant/components/tplink_omada/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OmadaConfigEntry from .controller import OmadaGatewayCoordinator @@ -28,7 +28,7 @@ from .entity import OmadaDeviceEntity async def async_setup_entry( hass: HomeAssistant, config_entry: OmadaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/tplink_omada/controller.py b/homeassistant/components/tplink_omada/controller.py index 658286981f9..60a07f76b23 100644 --- a/homeassistant/components/tplink_omada/controller.py +++ b/homeassistant/components/tplink_omada/controller.py @@ -1,10 +1,17 @@ """Controller for sharing Omada API coordinators between platforms.""" +from __future__ import annotations + +from typing import TYPE_CHECKING + from tplink_omada_client import OmadaSiteClient from tplink_omada_client.devices import OmadaSwitch from homeassistant.core import HomeAssistant +if TYPE_CHECKING: + from . import OmadaConfigEntry + from .coordinator import ( OmadaClientsCoordinator, OmadaDevicesCoordinator, @@ -21,15 +28,21 @@ class OmadaSiteController: def __init__( self, hass: HomeAssistant, + config_entry: OmadaConfigEntry, omada_client: OmadaSiteClient, ) -> None: """Create the controller.""" self._hass = hass + self._config_entry = config_entry self._omada_client = omada_client self._switch_port_coordinators: dict[str, OmadaSwitchPortCoordinator] = {} - self._devices_coordinator = OmadaDevicesCoordinator(hass, omada_client) - self._clients_coordinator = OmadaClientsCoordinator(hass, omada_client) + self._devices_coordinator = OmadaDevicesCoordinator( + hass, config_entry, omada_client + ) + self._clients_coordinator = OmadaClientsCoordinator( + hass, config_entry, omada_client + ) async def initialize_first_refresh(self) -> None: """Initialize the all coordinators, and perform first refresh.""" @@ -39,7 +52,7 @@ class OmadaSiteController: gateway = next((d for d in devices if d.type == "gateway"), None) if gateway: self._gateway_coordinator = OmadaGatewayCoordinator( - self._hass, self._omada_client, gateway.mac + self._hass, self._config_entry, self._omada_client, gateway.mac ) await self._gateway_coordinator.async_config_entry_first_refresh() @@ -56,7 +69,7 @@ class OmadaSiteController: """Get coordinator for network port information of a given switch.""" if switch.mac not in self._switch_port_coordinators: self._switch_port_coordinators[switch.mac] = OmadaSwitchPortCoordinator( - self._hass, self._omada_client, switch + self._hass, self._config_entry, self._omada_client, switch ) return self._switch_port_coordinators[switch.mac] diff --git a/homeassistant/components/tplink_omada/coordinator.py b/homeassistant/components/tplink_omada/coordinator.py index a80bedeb65e..1552b568297 100644 --- a/homeassistant/components/tplink_omada/coordinator.py +++ b/homeassistant/components/tplink_omada/coordinator.py @@ -1,8 +1,11 @@ """Generic Omada API coordinator.""" +from __future__ import annotations + import asyncio from datetime import timedelta import logging +from typing import TYPE_CHECKING from tplink_omada_client import OmadaSiteClient, OmadaSwitchPortDetails from tplink_omada_client.clients import OmadaWirelessClient @@ -12,6 +15,9 @@ from tplink_omada_client.exceptions import OmadaClientException from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +if TYPE_CHECKING: + from . import OmadaConfigEntry + _LOGGER = logging.getLogger(__name__) POLL_SWITCH_PORT = 300 @@ -23,9 +29,12 @@ POLL_DEVICES = 300 class OmadaCoordinator[_T](DataUpdateCoordinator[dict[str, _T]]): """Coordinator for synchronizing bulk Omada data.""" + config_entry: OmadaConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: OmadaConfigEntry, omada_client: OmadaSiteClient, name: str, poll_delay: int | None = 300, @@ -34,6 +43,7 @@ class OmadaCoordinator[_T](DataUpdateCoordinator[dict[str, _T]]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=f"Omada API Data - {name}", update_interval=timedelta(seconds=poll_delay) if poll_delay else None, ) @@ -58,12 +68,17 @@ class OmadaSwitchPortCoordinator(OmadaCoordinator[OmadaSwitchPortDetails]): def __init__( self, hass: HomeAssistant, + config_entry: OmadaConfigEntry, omada_client: OmadaSiteClient, network_switch: OmadaSwitch, ) -> None: """Initialize my coordinator.""" super().__init__( - hass, omada_client, f"{network_switch.name} Ports", POLL_SWITCH_PORT + hass, + config_entry, + omada_client, + f"{network_switch.name} Ports", + POLL_SWITCH_PORT, ) self._network_switch = network_switch @@ -79,11 +94,12 @@ class OmadaGatewayCoordinator(OmadaCoordinator[OmadaGateway]): def __init__( self, hass: HomeAssistant, + config_entry: OmadaConfigEntry, omada_client: OmadaSiteClient, mac: str, ) -> None: """Initialize my coordinator.""" - super().__init__(hass, omada_client, "Gateway", POLL_GATEWAY) + super().__init__(hass, config_entry, omada_client, "Gateway", POLL_GATEWAY) self.mac = mac async def poll_update(self) -> dict[str, OmadaGateway]: @@ -98,10 +114,11 @@ class OmadaDevicesCoordinator(OmadaCoordinator[OmadaListDevice]): def __init__( self, hass: HomeAssistant, + config_entry: OmadaConfigEntry, omada_client: OmadaSiteClient, ) -> None: """Initialize my coordinator.""" - super().__init__(hass, omada_client, "DeviceList", POLL_CLIENTS) + super().__init__(hass, config_entry, omada_client, "DeviceList", POLL_CLIENTS) async def poll_update(self) -> dict[str, OmadaListDevice]: """Poll the site's current registered Omada devices.""" @@ -111,9 +128,14 @@ class OmadaDevicesCoordinator(OmadaCoordinator[OmadaListDevice]): class OmadaClientsCoordinator(OmadaCoordinator[OmadaWirelessClient]): """Coordinator for getting details about the site's connected clients.""" - def __init__(self, hass: HomeAssistant, omada_client: OmadaSiteClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: OmadaConfigEntry, + omada_client: OmadaSiteClient, + ) -> None: """Initialize my coordinator.""" - super().__init__(hass, omada_client, "ClientsList", POLL_CLIENTS) + super().__init__(hass, config_entry, omada_client, "ClientsList", POLL_CLIENTS) async def poll_update(self) -> dict[str, OmadaWirelessClient]: """Poll the site's current active wi-fi clients.""" diff --git a/homeassistant/components/tplink_omada/device_tracker.py b/homeassistant/components/tplink_omada/device_tracker.py index fe78adf8847..ce1c8ba40e1 100644 --- a/homeassistant/components/tplink_omada/device_tracker.py +++ b/homeassistant/components/tplink_omada/device_tracker.py @@ -6,7 +6,7 @@ from tplink_omada_client.clients import OmadaWirelessClient from homeassistant.components.device_tracker import ScannerEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import OmadaConfigEntry @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: OmadaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device trackers and scanners.""" diff --git a/homeassistant/components/tplink_omada/sensor.py b/homeassistant/components/tplink_omada/sensor.py index 272334d1b52..b41f3da2f33 100644 --- a/homeassistant/components/tplink_omada/sensor.py +++ b/homeassistant/components/tplink_omada/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import OmadaConfigEntry @@ -57,7 +57,7 @@ def _map_device_status(device: OmadaListDevice) -> str | None: async def async_setup_entry( hass: HomeAssistant, config_entry: OmadaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/tplink_omada/switch.py b/homeassistant/components/tplink_omada/switch.py index f99d8aaedde..37c73a9e11f 100644 --- a/homeassistant/components/tplink_omada/switch.py +++ b/homeassistant/components/tplink_omada/switch.py @@ -22,7 +22,7 @@ from tplink_omada_client.omadasiteclient import GatewayPortSettings from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OmadaConfigEntry from .controller import OmadaGatewayCoordinator, OmadaSwitchPortCoordinator @@ -37,7 +37,7 @@ TCoordinator = TypeVar("TCoordinator", bound="OmadaCoordinator[Any]") async def async_setup_entry( hass: HomeAssistant, config_entry: OmadaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/tplink_omada/update.py b/homeassistant/components/tplink_omada/update.py index 54b586794be..8a8531c10b6 100644 --- a/homeassistant/components/tplink_omada/update.py +++ b/homeassistant/components/tplink_omada/update.py @@ -16,7 +16,7 @@ from homeassistant.components.update import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import OmadaConfigEntry from .coordinator import POLL_DEVICES, OmadaCoordinator, OmadaDevicesCoordinator @@ -43,7 +43,9 @@ class OmadaFirmwareUpdateCoordinator(OmadaCoordinator[FirmwareUpdateStatus]): # devices_coordinator: OmadaDevicesCoordinator, ) -> None: """Initialize my coordinator.""" - super().__init__(hass, omada_client, "Firmware Updates", poll_delay=None) + super().__init__( + hass, config_entry, omada_client, "Firmware Updates", poll_delay=None + ) self._devices_coordinator = devices_coordinator self._config_entry = config_entry @@ -91,7 +93,7 @@ class OmadaFirmwareUpdateCoordinator(OmadaCoordinator[FirmwareUpdateStatus]): # async def async_setup_entry( hass: HomeAssistant, config_entry: OmadaConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" controller = config_entry.runtime_data diff --git a/homeassistant/components/traccar/device_tracker.py b/homeassistant/components/traccar/device_tracker.py index 0fa7fc344ea..43210ee92ea 100644 --- a/homeassistant/components/traccar/device_tracker.py +++ b/homeassistant/components/traccar/device_tracker.py @@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import DOMAIN, TRACKER_UPDATE @@ -69,7 +69,9 @@ EVENTS = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure a dispatcher connection based on a config entry.""" diff --git a/homeassistant/components/traccar_server/__init__.py b/homeassistant/components/traccar_server/__init__.py index c7a65d2d4a8..44aeedc3376 100644 --- a/homeassistant/components/traccar_server/__init__.py +++ b/homeassistant/components/traccar_server/__init__.py @@ -21,13 +21,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_create_clientsession from homeassistant.helpers.event import async_track_time_interval -from .const import ( - CONF_CUSTOM_ATTRIBUTES, - CONF_EVENTS, - CONF_MAX_ACCURACY, - CONF_SKIP_ACCURACY_FILTER_FOR, - DOMAIN, -) +from .const import CONF_EVENTS, DOMAIN from .coordinator import TraccarServerCoordinator PLATFORMS: list[Platform] = [ @@ -47,6 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) coordinator = TraccarServerCoordinator( hass=hass, + config_entry=entry, client=ApiClient( client_session=client_session, host=entry.data[CONF_HOST], @@ -56,10 +51,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ssl=entry.data[CONF_SSL], verify_ssl=entry.data[CONF_VERIFY_SSL], ), - events=entry.options.get(CONF_EVENTS, []), - max_accuracy=entry.options.get(CONF_MAX_ACCURACY, 0.0), - skip_accuracy_filter_for=entry.options.get(CONF_SKIP_ACCURACY_FILTER_FOR, []), - custom_attributes=entry.options.get(CONF_CUSTOM_ATTRIBUTES, []), ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/traccar_server/binary_sensor.py b/homeassistant/components/traccar_server/binary_sensor.py index 58c46502b53..6d81ba84ed4 100644 --- a/homeassistant/components/traccar_server/binary_sensor.py +++ b/homeassistant/components/traccar_server/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import TraccarServerCoordinator @@ -55,7 +55,7 @@ TRACCAR_SERVER_BINARY_SENSOR_ENTITY_DESCRIPTIONS: tuple[ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor entities.""" coordinator: TraccarServerCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/traccar_server/coordinator.py b/homeassistant/components/traccar_server/coordinator.py index 95ce42469f1..2c878856cc2 100644 --- a/homeassistant/components/traccar_server/coordinator.py +++ b/homeassistant/components/traccar_server/coordinator.py @@ -22,7 +22,15 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util -from .const import DOMAIN, EVENTS, LOGGER +from .const import ( + CONF_CUSTOM_ATTRIBUTES, + CONF_EVENTS, + CONF_MAX_ACCURACY, + CONF_SKIP_ACCURACY_FILTER_FOR, + DOMAIN, + EVENTS, + LOGGER, +) from .helpers import get_device, get_first_geofence @@ -46,25 +54,24 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, client: ApiClient, - *, - events: list[str], - max_accuracy: float, - skip_accuracy_filter_for: list[str], - custom_attributes: list[str], ) -> None: """Initialize global Traccar Server data updater.""" super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=None, ) self.client = client - self.custom_attributes = custom_attributes - self.events = events - self.max_accuracy = max_accuracy - self.skip_accuracy_filter_for = skip_accuracy_filter_for + self.custom_attributes = config_entry.options.get(CONF_CUSTOM_ATTRIBUTES, []) + self.events = config_entry.options.get(CONF_EVENTS, []) + self.max_accuracy = config_entry.options.get(CONF_MAX_ACCURACY, 0.0) + self.skip_accuracy_filter_for = config_entry.options.get( + CONF_SKIP_ACCURACY_FILTER_FOR, [] + ) self._geofences: list[GeofenceModel] = [] self._last_event_import: datetime | None = None self._should_log_subscription_error: bool = True diff --git a/homeassistant/components/traccar_server/device_tracker.py b/homeassistant/components/traccar_server/device_tracker.py index 9e5a3c0ee9f..7f2a6dd7c40 100644 --- a/homeassistant/components/traccar_server/device_tracker.py +++ b/homeassistant/components/traccar_server/device_tracker.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.device_tracker import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_CATEGORY, ATTR_TRACCAR_ID, ATTR_TRACKER, DOMAIN from .coordinator import TraccarServerCoordinator @@ -17,7 +17,7 @@ from .entity import TraccarServerEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker entities.""" coordinator: TraccarServerCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/traccar_server/sensor.py b/homeassistant/components/traccar_server/sensor.py index bb3c4ed4401..9aee6f28489 100644 --- a/homeassistant/components/traccar_server/sensor.py +++ b/homeassistant/components/traccar_server/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOfSpeed from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -83,7 +83,7 @@ TRACCAR_SERVER_SENSOR_ENTITY_DESCRIPTIONS: tuple[ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensor entities.""" coordinator: TraccarServerCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/tractive/binary_sensor.py b/homeassistant/components/tractive/binary_sensor.py index 80219154d81..2978d369344 100644 --- a/homeassistant/components/tractive/binary_sensor.py +++ b/homeassistant/components/tractive/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import ATTR_BATTERY_CHARGING, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Trackables, TractiveClient, TractiveConfigEntry from .const import TRACKER_HARDWARE_STATUS_UPDATED @@ -58,7 +58,7 @@ SENSOR_TYPE = BinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: TractiveConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tractive device trackers.""" client = entry.runtime_data.client diff --git a/homeassistant/components/tractive/device_tracker.py b/homeassistant/components/tractive/device_tracker.py index f31afaf92f6..73be7216a2f 100644 --- a/homeassistant/components/tractive/device_tracker.py +++ b/homeassistant/components/tractive/device_tracker.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.device_tracker import SourceType, TrackerEntity from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Trackables, TractiveClient, TractiveConfigEntry from .const import ( @@ -21,7 +21,7 @@ from .entity import TractiveEntity async def async_setup_entry( hass: HomeAssistant, entry: TractiveConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tractive device trackers.""" client = entry.runtime_data.client diff --git a/homeassistant/components/tractive/sensor.py b/homeassistant/components/tractive/sensor.py index a3c1893267c..18d7e4c23ab 100644 --- a/homeassistant/components/tractive/sensor.py +++ b/homeassistant/components/tractive/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import Trackables, TractiveClient, TractiveConfigEntry @@ -182,7 +182,7 @@ SENSOR_TYPES: tuple[TractiveSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TractiveConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tractive device trackers.""" client = entry.runtime_data.client diff --git a/homeassistant/components/tractive/switch.py b/homeassistant/components/tractive/switch.py index 3bf6887e99c..da2c8e35ff7 100644 --- a/homeassistant/components/tractive/switch.py +++ b/homeassistant/components/tractive/switch.py @@ -11,7 +11,7 @@ from aiotractive.exceptions import TractiveError from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Trackables, TractiveClient, TractiveConfigEntry from .const import ( @@ -57,7 +57,7 @@ SWITCH_TYPES: tuple[TractiveSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TractiveConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tractive switches.""" client = entry.runtime_data.client diff --git a/homeassistant/components/tradfri/__init__.py b/homeassistant/components/tradfri/__init__.py index 92ed2ea8b82..2073829e021 100644 --- a/homeassistant/components/tradfri/__init__.py +++ b/homeassistant/components/tradfri/__init__.py @@ -106,7 +106,7 @@ async def async_setup_entry( for device in devices: coordinator = TradfriDeviceDataUpdateCoordinator( - hass=hass, api=api, device=device + hass=hass, config_entry=entry, api=api, device=device ) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/tradfri/coordinator.py b/homeassistant/components/tradfri/coordinator.py index 5246545ae65..4c5c186626e 100644 --- a/homeassistant/components/tradfri/coordinator.py +++ b/homeassistant/components/tradfri/coordinator.py @@ -10,6 +10,7 @@ from pytradfri.command import Command from pytradfri.device import Device from pytradfri.error import RequestError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -21,10 +22,12 @@ SCAN_INTERVAL = 60 # Interval for updating the coordinator class TradfriDeviceDataUpdateCoordinator(DataUpdateCoordinator[Device]): """Coordinator to manage data for a specific Tradfri device.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - *, + config_entry: ConfigEntry, api: Callable[[Command | list[Command]], Any], device: Device, ) -> None: @@ -36,6 +39,7 @@ class TradfriDeviceDataUpdateCoordinator(DataUpdateCoordinator[Device]): super().__init__( hass, LOGGER, + config_entry=config_entry, name=f"Update coordinator for {device}", update_interval=timedelta(seconds=SCAN_INTERVAL), ) diff --git a/homeassistant/components/tradfri/cover.py b/homeassistant/components/tradfri/cover.py index 92d10320327..b1fb9b153ad 100644 --- a/homeassistant/components/tradfri/cover.py +++ b/homeassistant/components/tradfri/cover.py @@ -10,7 +10,7 @@ from pytradfri.command import Command from homeassistant.components.cover import ATTR_POSITION, CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator @@ -20,7 +20,7 @@ from .entity import TradfriBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Tradfri covers based on a config entry.""" gateway_id = config_entry.data[CONF_GATEWAY_ID] diff --git a/homeassistant/components/tradfri/fan.py b/homeassistant/components/tradfri/fan.py index 3f45ee3e1eb..e8fb7c050ed 100644 --- a/homeassistant/components/tradfri/fan.py +++ b/homeassistant/components/tradfri/fan.py @@ -10,7 +10,7 @@ from pytradfri.command import Command from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator @@ -33,7 +33,7 @@ def _from_fan_speed(fan_speed: int) -> int: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Tradfri switches based on a config entry.""" gateway_id = config_entry.data[CONF_GATEWAY_ID] diff --git a/homeassistant/components/tradfri/light.py b/homeassistant/components/tradfri/light.py index e464d1a8142..b945c7f2bec 100644 --- a/homeassistant/components/tradfri/light.py +++ b/homeassistant/components/tradfri/light.py @@ -19,7 +19,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API @@ -30,7 +30,7 @@ from .entity import TradfriBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Tradfri lights based on a config entry.""" gateway_id = config_entry.data[CONF_GATEWAY_ID] diff --git a/homeassistant/components/tradfri/sensor.py b/homeassistant/components/tradfri/sensor.py index 4e560f0e7b5..b4a7c335481 100644 --- a/homeassistant/components/tradfri/sensor.py +++ b/homeassistant/components/tradfri/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_GATEWAY_ID, @@ -128,7 +128,7 @@ def _migrate_old_unique_ids(hass: HomeAssistant, old_unique_id: str, key: str) - async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Tradfri config entry.""" gateway_id = config_entry.data[CONF_GATEWAY_ID] diff --git a/homeassistant/components/tradfri/switch.py b/homeassistant/components/tradfri/switch.py index 088b775b9fd..a2a1a5b4623 100644 --- a/homeassistant/components/tradfri/switch.py +++ b/homeassistant/components/tradfri/switch.py @@ -10,7 +10,7 @@ from pytradfri.command import Command from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator @@ -20,7 +20,7 @@ from .entity import TradfriBaseEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Load Tradfri switches based on a config entry.""" gateway_id = config_entry.data[CONF_GATEWAY_ID] diff --git a/homeassistant/components/trafikverket_camera/binary_sensor.py b/homeassistant/components/trafikverket_camera/binary_sensor.py index b367fa0fb45..92112b41466 100644 --- a/homeassistant/components/trafikverket_camera/binary_sensor.py +++ b/homeassistant/components/trafikverket_camera/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TVCameraConfigEntry from .coordinator import CameraData @@ -36,7 +36,7 @@ BINARY_SENSOR_TYPE = TVCameraSensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: TVCameraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Trafikverket Camera binary sensor platform.""" diff --git a/homeassistant/components/trafikverket_camera/camera.py b/homeassistant/components/trafikverket_camera/camera.py index ece02cacf70..b4eddb0890f 100644 --- a/homeassistant/components/trafikverket_camera/camera.py +++ b/homeassistant/components/trafikverket_camera/camera.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.camera import Camera from homeassistant.const import ATTR_LOCATION from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TVCameraConfigEntry from .const import ATTR_DESCRIPTION, ATTR_TYPE @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: TVCameraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Trafikverket Camera.""" diff --git a/homeassistant/components/trafikverket_camera/sensor.py b/homeassistant/components/trafikverket_camera/sensor.py index cb5c458f742..726fcb6f901 100644 --- a/homeassistant/components/trafikverket_camera/sensor.py +++ b/homeassistant/components/trafikverket_camera/sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import DEGREE from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TVCameraConfigEntry @@ -74,7 +74,7 @@ SENSOR_TYPES: tuple[TVCameraSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TVCameraConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Trafikverket Camera sensor platform.""" diff --git a/homeassistant/components/trafikverket_ferry/sensor.py b/homeassistant/components/trafikverket_ferry/sensor.py index 44176ab82b7..b908bc5f550 100644 --- a/homeassistant/components/trafikverket_ferry/sensor.py +++ b/homeassistant/components/trafikverket_ferry/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import as_utc @@ -92,7 +92,7 @@ SENSOR_TYPES: tuple[TrafikverketSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TVFerryConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Trafikverket sensor entry.""" diff --git a/homeassistant/components/trafikverket_train/sensor.py b/homeassistant/components/trafikverket_train/sensor.py index a4de8c1ef26..150b5ee7abb 100644 --- a/homeassistant/components/trafikverket_train/sensor.py +++ b/homeassistant/components/trafikverket_train/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.const import CONF_NAME, UnitOfTime from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -110,7 +110,7 @@ SENSOR_TYPES: tuple[TrafikverketSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TVTrainConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Trafikverket sensor entry.""" diff --git a/homeassistant/components/trafikverket_weatherstation/sensor.py b/homeassistant/components/trafikverket_weatherstation/sensor.py index bc17c82748a..cb923037a24 100644 --- a/homeassistant/components/trafikverket_weatherstation/sensor.py +++ b/homeassistant/components/trafikverket_weatherstation/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -204,7 +204,7 @@ SENSOR_TYPES: tuple[TrafikverketSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TVWeatherConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Trafikverket sensor entry.""" diff --git a/homeassistant/components/transmission/__init__.py b/homeassistant/components/transmission/__init__.py index 578488dad1a..6d23017ab75 100644 --- a/homeassistant/components/transmission/__init__.py +++ b/homeassistant/components/transmission/__init__.py @@ -15,7 +15,7 @@ from transmission_rpc.error import ( ) import voluptuous as vol -from homeassistant.config_entries import ConfigEntry, ConfigEntryState +from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ( CONF_HOST, CONF_ID, @@ -54,7 +54,7 @@ from .const import ( SERVICE_START_TORRENT, SERVICE_STOP_TORRENT, ) -from .coordinator import TransmissionDataUpdateCoordinator +from .coordinator import TransmissionConfigEntry, TransmissionDataUpdateCoordinator from .errors import AuthenticationError, CannotConnect, UnknownError _LOGGER = logging.getLogger(__name__) @@ -117,8 +117,6 @@ SERVICE_STOP_TORRENT_SCHEMA = vol.All( CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) -type TransmissionConfigEntry = ConfigEntry[TransmissionDataUpdateCoordinator] - async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Transmission component.""" @@ -167,12 +165,16 @@ async def async_setup_entry( return True -async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_unload_entry( + hass: HomeAssistant, config_entry: TransmissionConfigEntry +) -> bool: """Unload Transmission Entry from config_entry.""" return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) -async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: +async def async_migrate_entry( + hass: HomeAssistant, config_entry: TransmissionConfigEntry +) -> bool: """Migrate an old config entry.""" _LOGGER.debug( "Migrating from version %s.%s", diff --git a/homeassistant/components/transmission/coordinator.py b/homeassistant/components/transmission/coordinator.py index b998ab6fbdd..afe2660e711 100644 --- a/homeassistant/components/transmission/coordinator.py +++ b/homeassistant/components/transmission/coordinator.py @@ -27,17 +27,21 @@ from .const import ( _LOGGER = logging.getLogger(__name__) +type TransmissionConfigEntry = ConfigEntry[TransmissionDataUpdateCoordinator] + class TransmissionDataUpdateCoordinator(DataUpdateCoordinator[SessionStats]): """Transmission dataupdate coordinator class.""" - config_entry: ConfigEntry + config_entry: TransmissionConfigEntry def __init__( - self, hass: HomeAssistant, entry: ConfigEntry, api: transmission_rpc.Client + self, + hass: HomeAssistant, + entry: TransmissionConfigEntry, + api: transmission_rpc.Client, ) -> None: """Initialize the Transmission RPC API.""" - self.config_entry = entry self.api = api self.host = entry.data[CONF_HOST] self._session: transmission_rpc.Session | None = None @@ -47,6 +51,7 @@ class TransmissionDataUpdateCoordinator(DataUpdateCoordinator[SessionStats]): self.torrents: list[transmission_rpc.Torrent] = [] super().__init__( hass, + config_entry=entry, name=f"{DOMAIN} - {self.host}", logger=_LOGGER, update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), diff --git a/homeassistant/components/transmission/sensor.py b/homeassistant/components/transmission/sensor.py index 652f5d51fbb..a0babe7464a 100644 --- a/homeassistant/components/transmission/sensor.py +++ b/homeassistant/components/transmission/sensor.py @@ -17,11 +17,10 @@ from homeassistant.components.sensor import ( from homeassistant.const import STATE_IDLE, UnitOfDataRate from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import TransmissionConfigEntry from .const import ( DOMAIN, STATE_ATTR_TORRENT_INFO, @@ -30,7 +29,7 @@ from .const import ( STATE_UP_DOWN, SUPPORTED_ORDER_MODES, ) -from .coordinator import TransmissionDataUpdateCoordinator +from .coordinator import TransmissionConfigEntry, TransmissionDataUpdateCoordinator MODES: dict[str, list[str] | None] = { "started_torrents": ["downloading"], @@ -130,7 +129,7 @@ SENSOR_TYPES: tuple[TransmissionSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TransmissionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Transmission sensors.""" diff --git a/homeassistant/components/transmission/switch.py b/homeassistant/components/transmission/switch.py index d88f794cb10..9ca8a197344 100644 --- a/homeassistant/components/transmission/switch.py +++ b/homeassistant/components/transmission/switch.py @@ -7,12 +7,11 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import TransmissionConfigEntry from .const import DOMAIN -from .coordinator import TransmissionDataUpdateCoordinator +from .coordinator import TransmissionConfigEntry, TransmissionDataUpdateCoordinator @dataclass(frozen=True, kw_only=True) @@ -45,7 +44,7 @@ SWITCH_TYPES: tuple[TransmissionSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: TransmissionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Transmission switch.""" diff --git a/homeassistant/components/trend/binary_sensor.py b/homeassistant/components/trend/binary_sensor.py index e5ff5c64a8b..4261f96bbe6 100644 --- a/homeassistant/components/trend/binary_sensor.py +++ b/homeassistant/components/trend/binary_sensor.py @@ -35,7 +35,10 @@ from homeassistant.core import Event, EventStateChangedData, HomeAssistant, call from homeassistant.helpers import config_validation as cv, device_registry as dr from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.entity import generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.restore_state import RestoreEntity @@ -130,7 +133,7 @@ async def async_setup_platform( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up trend sensor from config entry.""" diff --git a/homeassistant/components/triggercmd/switch.py b/homeassistant/components/triggercmd/switch.py index 94566fe301d..e04cf5ee7e8 100644 --- a/homeassistant/components/triggercmd/switch.py +++ b/homeassistant/components/triggercmd/switch.py @@ -9,7 +9,7 @@ from triggercmd import client, ha from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TriggercmdConfigEntry from .const import DOMAIN @@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: TriggercmdConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add switch for passed config_entry in HA.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/tuya/alarm_control_panel.py b/homeassistant/components/tuya/alarm_control_panel.py index 56bccc73581..96f7d3a1e1c 100644 --- a/homeassistant/components/tuya/alarm_control_panel.py +++ b/homeassistant/components/tuya/alarm_control_panel.py @@ -14,7 +14,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -53,7 +53,9 @@ ALARM: dict[str, tuple[AlarmControlPanelEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya alarm dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/binary_sensor.py b/homeassistant/components/tuya/binary_sensor.py index 12661a26fd1..1487a80248c 100644 --- a/homeassistant/components/tuya/binary_sensor.py +++ b/homeassistant/components/tuya/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode @@ -341,7 +341,9 @@ BINARY_SENSORS: dict[str, tuple[TuyaBinarySensorEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya binary sensor dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/button.py b/homeassistant/components/tuya/button.py index f77fed776b0..8e538b07309 100644 --- a/homeassistant/components/tuya/button.py +++ b/homeassistant/components/tuya/button.py @@ -8,7 +8,7 @@ from homeassistant.components.button import ButtonEntity, ButtonEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode @@ -58,7 +58,9 @@ BUTTONS: dict[str, tuple[ButtonEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya buttons dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/camera.py b/homeassistant/components/tuya/camera.py index 9e66531dd51..b07b9e9959e 100644 --- a/homeassistant/components/tuya/camera.py +++ b/homeassistant/components/tuya/camera.py @@ -8,7 +8,7 @@ from homeassistant.components import ffmpeg from homeassistant.components.camera import Camera as CameraEntity, CameraEntityFeature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode @@ -24,7 +24,9 @@ CAMERAS: tuple[str, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya cameras dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/climate.py b/homeassistant/components/tuya/climate.py index 1780256a740..deccb08c5aa 100644 --- a/homeassistant/components/tuya/climate.py +++ b/homeassistant/components/tuya/climate.py @@ -21,7 +21,7 @@ from homeassistant.components.climate import ( from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -84,7 +84,9 @@ CLIMATE_DESCRIPTIONS: dict[str, TuyaClimateEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya climate dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/cover.py b/homeassistant/components/tuya/cover.py index 9c3269c27f2..315075e7f37 100644 --- a/homeassistant/components/tuya/cover.py +++ b/homeassistant/components/tuya/cover.py @@ -17,7 +17,7 @@ from homeassistant.components.cover import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -142,7 +142,9 @@ COVERS: dict[str, tuple[TuyaCoverEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya cover dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/fan.py b/homeassistant/components/tuya/fan.py index ffab9efdde8..3b951e75da1 100644 --- a/homeassistant/components/tuya/fan.py +++ b/homeassistant/components/tuya/fan.py @@ -14,7 +14,7 @@ from homeassistant.components.fan import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -34,7 +34,9 @@ TUYA_SUPPORT_TYPE = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tuya fan dynamically through tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/humidifier.py b/homeassistant/components/tuya/humidifier.py index cb872d67719..6c47148eeda 100644 --- a/homeassistant/components/tuya/humidifier.py +++ b/homeassistant/components/tuya/humidifier.py @@ -14,7 +14,7 @@ from homeassistant.components.humidifier import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -55,7 +55,9 @@ HUMIDIFIERS: dict[str, TuyaHumidifierEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya (de)humidifier dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/light.py b/homeassistant/components/tuya/light.py index d7dffc16b58..7f4a964f47e 100644 --- a/homeassistant/components/tuya/light.py +++ b/homeassistant/components/tuya/light.py @@ -20,7 +20,7 @@ from homeassistant.components.light import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import TuyaConfigEntry @@ -421,7 +421,9 @@ class ColorData: async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tuya light dynamically through tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/number.py b/homeassistant/components/tuya/number.py index 8d5b5dbfa19..4e98cf34d4d 100644 --- a/homeassistant/components/tuya/number.py +++ b/homeassistant/components/tuya/number.py @@ -12,7 +12,7 @@ from homeassistant.components.number import ( from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import DEVICE_CLASS_UNITS, DOMAIN, TUYA_DISCOVERY_NEW, DPCode, DPType @@ -307,7 +307,9 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya number dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/scene.py b/homeassistant/components/tuya/scene.py index dbc849356b2..4ad027d39ee 100644 --- a/homeassistant/components/tuya/scene.py +++ b/homeassistant/components/tuya/scene.py @@ -9,14 +9,16 @@ from tuya_sharing import Manager, SharingScene from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import DOMAIN async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya scenes.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/select.py b/homeassistant/components/tuya/select.py index 831d3cb3e0c..766cdd295f1 100644 --- a/homeassistant/components/tuya/select.py +++ b/homeassistant/components/tuya/select.py @@ -8,7 +8,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -328,7 +328,9 @@ SELECTS["pc"] = SELECTS["kg"] async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya select dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/sensor.py b/homeassistant/components/tuya/sensor.py index 756564c6a03..cb7602e24fe 100644 --- a/homeassistant/components/tuya/sensor.py +++ b/homeassistant/components/tuya/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import TuyaConfigEntry @@ -1222,7 +1222,9 @@ SENSORS["pc"] = SENSORS["kg"] async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya sensor dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/siren.py b/homeassistant/components/tuya/siren.py index 6f7dfe4c96c..310385df93d 100644 --- a/homeassistant/components/tuya/siren.py +++ b/homeassistant/components/tuya/siren.py @@ -14,7 +14,7 @@ from homeassistant.components.siren import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode @@ -56,7 +56,9 @@ SIRENS: dict[str, tuple[SirenEntityDescription, ...]] = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya siren dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/switch.py b/homeassistant/components/tuya/switch.py index 2b5e6fec4a6..d0192b41ee6 100644 --- a/homeassistant/components/tuya/switch.py +++ b/homeassistant/components/tuya/switch.py @@ -14,7 +14,7 @@ from homeassistant.components.switch import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode @@ -728,7 +728,9 @@ SWITCHES["cz"] = SWITCHES["pc"] async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up tuya sensors dynamically through tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/tuya/vacuum.py b/homeassistant/components/tuya/vacuum.py index bab9ac309ec..e36a682fa4e 100644 --- a/homeassistant/components/tuya/vacuum.py +++ b/homeassistant/components/tuya/vacuum.py @@ -13,7 +13,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DPCode, DPType @@ -48,7 +48,9 @@ TUYA_STATUS_TO_HA = { async def async_setup_entry( - hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: TuyaConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Tuya vacuum dynamically through Tuya discovery.""" hass_data = entry.runtime_data diff --git a/homeassistant/components/twentemilieu/calendar.py b/homeassistant/components/twentemilieu/calendar.py index 606fb4913d1..19e3f4f3337 100644 --- a/homeassistant/components/twentemilieu/calendar.py +++ b/homeassistant/components/twentemilieu/calendar.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.const import CONF_ID from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import WASTE_TYPE_TO_DESCRIPTION @@ -18,7 +18,7 @@ from .entity import TwenteMilieuEntity async def async_setup_entry( hass: HomeAssistant, entry: TwenteMilieuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Twente Milieu calendar based on a config entry.""" async_add_entities([TwenteMilieuCalendar(entry)]) diff --git a/homeassistant/components/twentemilieu/sensor.py b/homeassistant/components/twentemilieu/sensor.py index 4605ede1f87..81751d10a81 100644 --- a/homeassistant/components/twentemilieu/sensor.py +++ b/homeassistant/components/twentemilieu/sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import CONF_ID from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import TwenteMilieuConfigEntry @@ -65,7 +65,7 @@ SENSORS: tuple[TwenteMilieuSensorDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: TwenteMilieuConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Twente Milieu sensor based on a config entry.""" async_add_entities( diff --git a/homeassistant/components/twinkly/__init__.py b/homeassistant/components/twinkly/__init__.py index cd29ffaf423..e3b53bba6c9 100644 --- a/homeassistant/components/twinkly/__init__.py +++ b/homeassistant/components/twinkly/__init__.py @@ -5,23 +5,19 @@ import logging from aiohttp import ClientError from ttls.client import Twinkly -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN -from .coordinator import TwinklyCoordinator +from .coordinator import TwinklyConfigEntry, TwinklyCoordinator PLATFORMS = [Platform.LIGHT, Platform.SELECT] _LOGGER = logging.getLogger(__name__) -type TwinklyConfigEntry = ConfigEntry[TwinklyCoordinator] - - async def async_setup_entry(hass: HomeAssistant, entry: TwinklyConfigEntry) -> bool: """Set up entries from config flow.""" # We setup the client here so if at some point we add any other entity for this device, @@ -30,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TwinklyConfigEntry) -> b client = Twinkly(host, async_get_clientsession(hass)) - coordinator = TwinklyCoordinator(hass, client) + coordinator = TwinklyCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/twinkly/coordinator.py b/homeassistant/components/twinkly/coordinator.py index 627fb0b39ba..2c2fc2a41d4 100644 --- a/homeassistant/components/twinkly/coordinator.py +++ b/homeassistant/components/twinkly/coordinator.py @@ -9,6 +9,7 @@ from aiohttp import ClientError from awesomeversion import AwesomeVersion from ttls.client import Twinkly, TwinklyError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -17,6 +18,8 @@ from .const import DEV_NAME, DOMAIN, MIN_EFFECT_VERSION _LOGGER = logging.getLogger(__name__) +type TwinklyConfigEntry = ConfigEntry[TwinklyCoordinator] + @dataclass class TwinklyData: @@ -33,15 +36,19 @@ class TwinklyData: class TwinklyCoordinator(DataUpdateCoordinator[TwinklyData]): """Class to manage fetching Twinkly data from API.""" + config_entry: TwinklyConfigEntry software_version: str supports_effects: bool device_name: str - def __init__(self, hass: HomeAssistant, client: Twinkly) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: TwinklyConfigEntry, client: Twinkly + ) -> None: """Initialize global Twinkly data updater.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=30), ) diff --git a/homeassistant/components/twinkly/diagnostics.py b/homeassistant/components/twinkly/diagnostics.py index d732ce14929..2bf46a208e8 100644 --- a/homeassistant/components/twinkly/diagnostics.py +++ b/homeassistant/components/twinkly/diagnostics.py @@ -10,8 +10,8 @@ from homeassistant.const import ATTR_SW_VERSION, CONF_HOST, CONF_IP_ADDRESS, CON from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from . import TwinklyConfigEntry from .const import DOMAIN +from .coordinator import TwinklyConfigEntry TO_REDACT = [CONF_HOST, CONF_IP_ADDRESS, CONF_MAC] diff --git a/homeassistant/components/twinkly/light.py b/homeassistant/components/twinkly/light.py index 31e95d70fc0..c270421d8cd 100644 --- a/homeassistant/components/twinkly/light.py +++ b/homeassistant/components/twinkly/light.py @@ -15,10 +15,10 @@ from homeassistant.components.light import ( LightEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TwinklyConfigEntry, TwinklyCoordinator from .const import DEV_LED_PROFILE, DEV_PROFILE_RGB, DEV_PROFILE_RGBW +from .coordinator import TwinklyConfigEntry, TwinklyCoordinator from .entity import TwinklyEntity _LOGGER = logging.getLogger(__name__) @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: TwinklyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Setups an entity from a config entry (UI config flow).""" entity = TwinklyLight(config_entry.runtime_data) diff --git a/homeassistant/components/twinkly/select.py b/homeassistant/components/twinkly/select.py index 38e5c9a6fc7..86d9732b8cc 100644 --- a/homeassistant/components/twinkly/select.py +++ b/homeassistant/components/twinkly/select.py @@ -8,9 +8,9 @@ from ttls.client import TWINKLY_MODES from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import TwinklyConfigEntry, TwinklyCoordinator +from .coordinator import TwinklyConfigEntry, TwinklyCoordinator from .entity import TwinklyEntity _LOGGER = logging.getLogger(__name__) @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: TwinklyConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a mode select from a config entry.""" entity = TwinklyModeSelect(config_entry.runtime_data) diff --git a/homeassistant/components/twitch/sensor.py b/homeassistant/components/twitch/sensor.py index b407eae0319..deec319e5cf 100644 --- a/homeassistant/components/twitch/sensor.py +++ b/homeassistant/components/twitch/sensor.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -32,7 +32,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: TwitchConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize entries.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/ukraine_alarm/__init__.py b/homeassistant/components/ukraine_alarm/__init__.py index d850ed6eba8..3658b821625 100644 --- a/homeassistant/components/ukraine_alarm/__init__.py +++ b/homeassistant/components/ukraine_alarm/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_REGION from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -13,11 +12,9 @@ from .coordinator import UkraineAlarmDataUpdateCoordinator async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Ukraine Alarm as config entry.""" - region_id = entry.data[CONF_REGION] - websession = async_get_clientsession(hass) - coordinator = UkraineAlarmDataUpdateCoordinator(hass, websession, region_id) + coordinator = UkraineAlarmDataUpdateCoordinator(hass, entry, websession) await coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator diff --git a/homeassistant/components/ukraine_alarm/binary_sensor.py b/homeassistant/components/ukraine_alarm/binary_sensor.py index 30cb8e0f553..9009031ea14 100644 --- a/homeassistant/components/ukraine_alarm/binary_sensor.py +++ b/homeassistant/components/ukraine_alarm/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( @@ -64,7 +64,7 @@ BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Ukraine Alarm binary sensor entities based on a config entry.""" name = config_entry.data[CONF_NAME] diff --git a/homeassistant/components/ukraine_alarm/coordinator.py b/homeassistant/components/ukraine_alarm/coordinator.py index fbf7c9f81c2..267358e4aa6 100644 --- a/homeassistant/components/ukraine_alarm/coordinator.py +++ b/homeassistant/components/ukraine_alarm/coordinator.py @@ -10,6 +10,8 @@ import aiohttp from aiohttp import ClientSession from uasiren.client import Client +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_REGION from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -23,17 +25,25 @@ UPDATE_INTERVAL = timedelta(seconds=10) class UkraineAlarmDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching Ukraine Alarm API.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, + config_entry: ConfigEntry, session: ClientSession, - region_id: str, ) -> None: """Initialize.""" - self.region_id = region_id + self.region_id = config_entry.data[CONF_REGION] self.uasiren = Client(session) - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=UPDATE_INTERVAL, + ) async def _async_update_data(self) -> dict[str, Any]: """Update data via library.""" diff --git a/homeassistant/components/unifi/button.py b/homeassistant/components/unifi/button.py index 25c6816d794..3e5ef62f49e 100644 --- a/homeassistant/components/unifi/button.py +++ b/homeassistant/components/unifi/button.py @@ -31,7 +31,7 @@ from homeassistant.components.button import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import UnifiConfigEntry from .entity import ( @@ -135,7 +135,7 @@ ENTITY_DESCRIPTIONS: tuple[UnifiButtonEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up button platform for UniFi Network integration.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/unifi/device_tracker.py b/homeassistant/components/unifi/device_tracker.py index da5ca74fc37..a26232664a8 100644 --- a/homeassistant/components/unifi/device_tracker.py +++ b/homeassistant/components/unifi/device_tracker.py @@ -26,7 +26,7 @@ from homeassistant.components.device_tracker import ( from homeassistant.core import Event as core_Event, HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import UnifiConfigEntry @@ -222,7 +222,7 @@ def async_update_unique_id(hass: HomeAssistant, config_entry: UnifiConfigEntry) async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for UniFi Network integration.""" async_update_unique_id(hass, config_entry) diff --git a/homeassistant/components/unifi/image.py b/homeassistant/components/unifi/image.py index f1ada9a01e0..f3045d5fc1c 100644 --- a/homeassistant/components/unifi/image.py +++ b/homeassistant/components/unifi/image.py @@ -16,7 +16,7 @@ from aiounifi.models.wlan import Wlan from homeassistant.components.image import ImageEntity, ImageEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import UnifiConfigEntry @@ -67,7 +67,7 @@ ENTITY_DESCRIPTIONS: tuple[UnifiImageEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up image platform for UniFi Network integration.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/unifi/sensor.py b/homeassistant/components/unifi/sensor.py index fd78c606043..47a2c2ba62e 100644 --- a/homeassistant/components/unifi/sensor.py +++ b/homeassistant/components/unifi/sensor.py @@ -46,7 +46,7 @@ from homeassistant.const import ( ) from homeassistant.core import Event as core_Event, HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util, slugify @@ -644,7 +644,7 @@ ENTITY_DESCRIPTIONS += make_wan_latency_sensors() + make_device_temperatur_senso async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for UniFi Network integration.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/unifi/switch.py b/homeassistant/components/unifi/switch.py index 91e4a0222f6..de0e8d3f412 100644 --- a/homeassistant/components/unifi/switch.py +++ b/homeassistant/components/unifi/switch.py @@ -46,7 +46,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import UnifiConfigEntry from .const import ATTR_MANUFACTURER, DOMAIN as UNIFI_DOMAIN @@ -352,7 +352,7 @@ def async_update_unique_id(hass: HomeAssistant, config_entry: UnifiConfigEntry) async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches for UniFi Network integration.""" async_update_unique_id(hass, config_entry) diff --git a/homeassistant/components/unifi/update.py b/homeassistant/components/unifi/update.py index 65202045a05..589b2ff1215 100644 --- a/homeassistant/components/unifi/update.py +++ b/homeassistant/components/unifi/update.py @@ -19,7 +19,7 @@ from homeassistant.components.update import ( UpdateEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import UnifiConfigEntry from .entity import ( @@ -68,7 +68,7 @@ ENTITY_DESCRIPTIONS: tuple[UnifiUpdateEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: UnifiConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up update entities for UniFi Network integration.""" config_entry.runtime_data.entity_loader.register_platform( diff --git a/homeassistant/components/unifiprotect/binary_sensor.py b/homeassistant/components/unifiprotect/binary_sensor.py index a88d4b65678..0d904d3c3ba 100644 --- a/homeassistant/components/unifiprotect/binary_sensor.py +++ b/homeassistant/components/unifiprotect/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectData, ProtectDeviceType, UFPConfigEntry from .entity import ( @@ -769,7 +769,7 @@ def _async_nvr_entities( async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensors for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/button.py b/homeassistant/components/unifiprotect/button.py index b24c90be3ec..7b766299946 100644 --- a/homeassistant/components/unifiprotect/button.py +++ b/homeassistant/components/unifiprotect/button.py @@ -19,7 +19,7 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEVICES_THAT_ADOPT, DOMAIN from .data import ProtectDeviceType, UFPConfigEntry @@ -120,7 +120,7 @@ def _async_remove_adopt_button( async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Discover devices on a UniFi Protect NVR.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/camera.py b/homeassistant/components/unifiprotect/camera.py index 0b1c03b8dd6..3947324fd73 100644 --- a/homeassistant/components/unifiprotect/camera.py +++ b/homeassistant/components/unifiprotect/camera.py @@ -16,7 +16,7 @@ from homeassistant.components.camera import Camera, CameraEntityFeature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import issue_registry as ir from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.issue_registry import IssueSeverity from .const import ( @@ -138,7 +138,7 @@ def _async_camera_entities( async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Discover cameras on a UniFi Protect NVR.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/event.py b/homeassistant/components/unifiprotect/event.py index 78fdf7746de..cb9090dd530 100644 --- a/homeassistant/components/unifiprotect/event.py +++ b/homeassistant/components/unifiprotect/event.py @@ -10,7 +10,7 @@ from homeassistant.components.event import ( EventEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import Bootstrap from .const import ( @@ -218,7 +218,7 @@ def _async_event_entities( async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up event entities for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/light.py b/homeassistant/components/unifiprotect/light.py index fcdfe5e85b8..873f715de58 100644 --- a/homeassistant/components/unifiprotect/light.py +++ b/homeassistant/components/unifiprotect/light.py @@ -9,7 +9,7 @@ from uiprotect.data import Light, ModelType, ProtectAdoptableDeviceModel from homeassistant.components.light import ColorMode, LightEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectDeviceType, UFPConfigEntry from .entity import ProtectDeviceEntity @@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lights for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/lock.py b/homeassistant/components/unifiprotect/lock.py index 3e9372db0e5..79ed47a6c3b 100644 --- a/homeassistant/components/unifiprotect/lock.py +++ b/homeassistant/components/unifiprotect/lock.py @@ -14,7 +14,7 @@ from uiprotect.data import ( from homeassistant.components.lock import LockEntity, LockEntityDescription from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectDeviceType, UFPConfigEntry from .entity import ProtectDeviceEntity @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up locks on a UniFi Protect NVR.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/media_player.py b/homeassistant/components/unifiprotect/media_player.py index 5f9991b257b..a1e60931026 100644 --- a/homeassistant/components/unifiprotect/media_player.py +++ b/homeassistant/components/unifiprotect/media_player.py @@ -21,7 +21,7 @@ from homeassistant.components.media_player import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectDeviceType, UFPConfigEntry from .entity import ProtectDeviceEntity @@ -36,7 +36,7 @@ _SPEAKER_DESCRIPTION = MediaPlayerEntityDescription( async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Discover cameras with speakers on a UniFi Protect NVR.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/number.py b/homeassistant/components/unifiprotect/number.py index 767128337ba..5dbf9f2b00e 100644 --- a/homeassistant/components/unifiprotect/number.py +++ b/homeassistant/components/unifiprotect/number.py @@ -17,7 +17,7 @@ from uiprotect.data import ( from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectData, ProtectDeviceType, UFPConfigEntry from .entity import ( @@ -227,7 +227,7 @@ _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = { async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/select.py b/homeassistant/components/unifiprotect/select.py index 00c277c957e..054c9430387 100644 --- a/homeassistant/components/unifiprotect/select.py +++ b/homeassistant/components/unifiprotect/select.py @@ -29,7 +29,7 @@ from uiprotect.data import ( from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TYPE_EMPTY_VALUE from .data import ProtectData, ProtectDeviceType, UFPConfigEntry @@ -334,7 +334,9 @@ _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = { async def async_setup_entry( - hass: HomeAssistant, entry: UFPConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: UFPConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/sensor.py b/homeassistant/components/unifiprotect/sensor.py index 09187e023a1..a719f36c2b3 100644 --- a/homeassistant/components/unifiprotect/sensor.py +++ b/homeassistant/components/unifiprotect/sensor.py @@ -38,7 +38,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectData, ProtectDeviceType, UFPConfigEntry from .entity import ( @@ -640,7 +640,7 @@ _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = { async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/switch.py b/homeassistant/components/unifiprotect/switch.py index fa960261cf2..fce92912a52 100644 --- a/homeassistant/components/unifiprotect/switch.py +++ b/homeassistant/components/unifiprotect/switch.py @@ -18,7 +18,7 @@ from uiprotect.data import ( from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from .data import ProtectData, ProtectDeviceType, UFPConfigEntry @@ -568,7 +568,7 @@ class ProtectPrivacyModeSwitch(RestoreEntity, ProtectSwitch): async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/unifiprotect/text.py b/homeassistant/components/unifiprotect/text.py index 0c7e1322f23..1c468d44cc6 100644 --- a/homeassistant/components/unifiprotect/text.py +++ b/homeassistant/components/unifiprotect/text.py @@ -15,7 +15,7 @@ from uiprotect.data import ( from homeassistant.components.text import TextEntity, TextEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .data import ProtectDeviceType, UFPConfigEntry from .entity import ( @@ -63,7 +63,7 @@ _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = { async def async_setup_entry( hass: HomeAssistant, entry: UFPConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up sensors for UniFi Protect integration.""" data = entry.runtime_data diff --git a/homeassistant/components/upb/light.py b/homeassistant/components/upb/light.py index 07bd50b7d9f..0838ec3ef01 100644 --- a/homeassistant/components/upb/light.py +++ b/homeassistant/components/upb/light.py @@ -13,7 +13,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, UPB_BLINK_RATE_SCHEMA, UPB_BRIGHTNESS_RATE_SCHEMA from .entity import UpbAttachedEntity @@ -26,7 +26,7 @@ SERVICE_LIGHT_BLINK = "light_blink" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UPB light based on a config entry.""" diff --git a/homeassistant/components/upb/scene.py b/homeassistant/components/upb/scene.py index 5a5e17b3e4c..45a1d664b15 100644 --- a/homeassistant/components/upb/scene.py +++ b/homeassistant/components/upb/scene.py @@ -6,7 +6,7 @@ from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, UPB_BLINK_RATE_SCHEMA, UPB_BRIGHTNESS_RATE_SCHEMA from .entity import UpbEntity @@ -21,7 +21,7 @@ SERVICE_LINK_BLINK = "link_blink" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UPB link based on a config entry.""" upb = hass.data[DOMAIN][config_entry.entry_id]["upb"] diff --git a/homeassistant/components/upcloud/binary_sensor.py b/homeassistant/components/upcloud/binary_sensor.py index bca313d306f..923d8f2d896 100644 --- a/homeassistant/components/upcloud/binary_sensor.py +++ b/homeassistant/components/upcloud/binary_sensor.py @@ -5,7 +5,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import UpCloudConfigEntry from .entity import UpCloudServerEntity @@ -14,7 +14,7 @@ from .entity import UpCloudServerEntity async def async_setup_entry( hass: HomeAssistant, config_entry: UpCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UpCloud server binary sensor.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/upcloud/switch.py b/homeassistant/components/upcloud/switch.py index 97c08b19188..de180907919 100644 --- a/homeassistant/components/upcloud/switch.py +++ b/homeassistant/components/upcloud/switch.py @@ -6,7 +6,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.const import STATE_OFF from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import dispatcher_send -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import UpCloudConfigEntry from .entity import UpCloudServerEntity @@ -17,7 +17,7 @@ SIGNAL_UPDATE_UPCLOUD = "upcloud_update" async def async_setup_entry( hass: HomeAssistant, config_entry: UpCloudConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UpCloud server switch.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/upnp/binary_sensor.py b/homeassistant/components/upnp/binary_sensor.py index 1576cccac6a..0c7b7aa5dc2 100644 --- a/homeassistant/components/upnp/binary_sensor.py +++ b/homeassistant/components/upnp/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import LOGGER, WAN_STATUS from .coordinator import UpnpConfigEntry, UpnpDataUpdateCoordinator @@ -38,7 +38,7 @@ SENSOR_DESCRIPTIONS: tuple[UpnpBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: UpnpConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UPnP/IGD sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/upnp/sensor.py b/homeassistant/components/upnp/sensor.py index c0e77315f77..c7e343d36b5 100644 --- a/homeassistant/components/upnp/sensor.py +++ b/homeassistant/components/upnp/sensor.py @@ -18,7 +18,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( BYTES_RECEIVED, @@ -153,7 +153,7 @@ SENSOR_DESCRIPTIONS: tuple[UpnpSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: UpnpConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UPnP/IGD sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/uptime/sensor.py b/homeassistant/components/uptime/sensor.py index 25917d09096..488682a79c6 100644 --- a/homeassistant/components/uptime/sensor.py +++ b/homeassistant/components/uptime/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import DOMAIN @@ -15,7 +15,7 @@ from .const import DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config_entry.""" async_add_entities([UptimeSensor(entry)]) diff --git a/homeassistant/components/uptimerobot/binary_sensor.py b/homeassistant/components/uptimerobot/binary_sensor.py index 0c1bd972387..73f9400c013 100644 --- a/homeassistant/components/uptimerobot/binary_sensor.py +++ b/homeassistant/components/uptimerobot/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import UptimeRobotDataUpdateCoordinator @@ -19,7 +19,7 @@ from .entity import UptimeRobotEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UptimeRobot binary_sensors.""" coordinator: UptimeRobotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/uptimerobot/sensor.py b/homeassistant/components/uptimerobot/sensor.py index c5ff8abf5d9..724c3075a3b 100644 --- a/homeassistant/components/uptimerobot/sensor.py +++ b/homeassistant/components/uptimerobot/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import UptimeRobotDataUpdateCoordinator @@ -28,7 +28,7 @@ SENSORS_INFO = { async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UptimeRobot sensors.""" coordinator: UptimeRobotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/uptimerobot/switch.py b/homeassistant/components/uptimerobot/switch.py index aa7d07e10fd..31401ac7eb4 100644 --- a/homeassistant/components/uptimerobot/switch.py +++ b/homeassistant/components/uptimerobot/switch.py @@ -13,7 +13,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import API_ATTR_OK, DOMAIN, LOGGER from .coordinator import UptimeRobotDataUpdateCoordinator @@ -21,7 +21,9 @@ from .entity import UptimeRobotEntity async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the UptimeRobot switches.""" coordinator: UptimeRobotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/utility_meter/select.py b/homeassistant/components/utility_meter/select.py index 5815ce7ec95..0c818525c8d 100644 --- a/homeassistant/components/utility_meter/select.py +++ b/homeassistant/components/utility_meter/select.py @@ -10,7 +10,10 @@ from homeassistant.const import CONF_NAME, CONF_UNIQUE_ID from homeassistant.core import HomeAssistant from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -22,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Utility Meter config entry.""" name = config_entry.title diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index cd65c42b22a..425dfa2c3fd 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -41,7 +41,10 @@ from homeassistant.core import ( from homeassistant.helpers import entity_platform, entity_registry as er from homeassistant.helpers.device import async_device_info_to_link_from_entity from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.event import ( async_track_point_in_time, async_track_state_change_event, @@ -116,7 +119,7 @@ def validate_is_number(value): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize Utility Meter config entry.""" entry_id = config_entry.entry_id diff --git a/homeassistant/components/v2c/binary_sensor.py b/homeassistant/components/v2c/binary_sensor.py index 18724a4eada..85f03d6b4fb 100644 --- a/homeassistant/components/v2c/binary_sensor.py +++ b/homeassistant/components/v2c/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import V2CConfigEntry, V2CUpdateCoordinator from .entity import V2CBaseEntity @@ -50,7 +50,7 @@ TRYDAN_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: V2CConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up V2C binary sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/v2c/number.py b/homeassistant/components/v2c/number.py index 0d6401d194f..e52242f0ce0 100644 --- a/homeassistant/components/v2c/number.py +++ b/homeassistant/components/v2c/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfElectricCurrent from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import V2CConfigEntry, V2CUpdateCoordinator from .entity import V2CBaseEntity @@ -71,7 +71,7 @@ TRYDAN_NUMBER_SETTINGS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: V2CConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up V2C Trydan number platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/v2c/sensor.py b/homeassistant/components/v2c/sensor.py index 5b02928385b..cfccaacda18 100644 --- a/homeassistant/components/v2c/sensor.py +++ b/homeassistant/components/v2c/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import V2CConfigEntry, V2CUpdateCoordinator @@ -142,7 +142,7 @@ TRYDAN_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: V2CConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up V2C sensor platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/v2c/switch.py b/homeassistant/components/v2c/switch.py index d6ba6a3b13e..20bc3419757 100644 --- a/homeassistant/components/v2c/switch.py +++ b/homeassistant/components/v2c/switch.py @@ -18,7 +18,7 @@ from pytrydan.models.trydan import ( from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import V2CConfigEntry, V2CUpdateCoordinator from .entity import V2CBaseEntity @@ -79,7 +79,7 @@ TRYDAN_SWITCHES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: V2CConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up V2C switch platform.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/vallox/__init__.py b/homeassistant/components/vallox/__init__.py index ceb34bc6ff9..785ecd09fb1 100644 --- a/homeassistant/components/vallox/__init__.py +++ b/homeassistant/components/vallox/__init__.py @@ -111,7 +111,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: client = Vallox(host) - coordinator = ValloxDataUpdateCoordinator(hass, name, client) + coordinator = ValloxDataUpdateCoordinator(hass, entry, client) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/vallox/binary_sensor.py b/homeassistant/components/vallox/binary_sensor.py index 4a0efc7b101..a205dd2039e 100644 --- a/homeassistant/components/vallox/binary_sensor.py +++ b/homeassistant/components/vallox/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ValloxDataUpdateCoordinator @@ -62,7 +62,7 @@ BINARY_SENSOR_ENTITIES: tuple[ValloxBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" diff --git a/homeassistant/components/vallox/coordinator.py b/homeassistant/components/vallox/coordinator.py index c2485c7b4fd..2fe7fa533db 100644 --- a/homeassistant/components/vallox/coordinator.py +++ b/homeassistant/components/vallox/coordinator.py @@ -6,6 +6,8 @@ import logging from vallox_websocket_api import MetricData, Vallox, ValloxApiException +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -17,17 +19,20 @@ _LOGGER = logging.getLogger(__name__) class ValloxDataUpdateCoordinator(DataUpdateCoordinator[MetricData]): """The DataUpdateCoordinator for Vallox.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - name: str, + config_entry: ConfigEntry, client: Vallox, ) -> None: """Initialize Vallox data coordinator.""" super().__init__( hass, _LOGGER, - name=f"{name} DataUpdateCoordinator", + config_entry=config_entry, + name=f"{config_entry.data[CONF_NAME]} DataUpdateCoordinator", update_interval=STATE_SCAN_INTERVAL, ) self.client = client diff --git a/homeassistant/components/vallox/date.py b/homeassistant/components/vallox/date.py index 33c3ebb253c..da2906c02c2 100644 --- a/homeassistant/components/vallox/date.py +++ b/homeassistant/components/vallox/date.py @@ -10,7 +10,7 @@ from homeassistant.components.date import DateEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ValloxDataUpdateCoordinator @@ -51,7 +51,7 @@ class ValloxFilterChangeDateEntity(ValloxEntity, DateEntity): async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vallox filter change date entity.""" diff --git a/homeassistant/components/vallox/fan.py b/homeassistant/components/vallox/fan.py index 3a21ef060a7..8519b4cb913 100644 --- a/homeassistant/components/vallox/fan.py +++ b/homeassistant/components/vallox/fan.py @@ -11,7 +11,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -57,7 +57,9 @@ def _convert_to_int(value: StateType) -> int | None: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fan device.""" data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/vallox/number.py b/homeassistant/components/vallox/number.py index 96bc07b5a93..ce3b9c72a6d 100644 --- a/homeassistant/components/vallox/number.py +++ b/homeassistant/components/vallox/number.py @@ -14,7 +14,7 @@ from homeassistant.components.number import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ValloxDataUpdateCoordinator @@ -102,7 +102,9 @@ NUMBER_ENTITIES: tuple[ValloxNumberEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" data = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/vallox/sensor.py b/homeassistant/components/vallox/sensor.py index 7165947861a..e9194a8254c 100644 --- a/homeassistant/components/vallox/sensor.py +++ b/homeassistant/components/vallox/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -278,7 +278,9 @@ SENSOR_ENTITIES: tuple[ValloxSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" name = hass.data[DOMAIN][entry.entry_id]["name"] diff --git a/homeassistant/components/vallox/strings.json b/homeassistant/components/vallox/strings.json index 8a30ed4ad01..f00206826d3 100644 --- a/homeassistant/components/vallox/strings.json +++ b/homeassistant/components/vallox/strings.json @@ -110,7 +110,7 @@ "fields": { "fan_speed": { "name": "Fan speed", - "description": "Fan speed." + "description": "Relative speed of the built-in fans." } } }, @@ -119,7 +119,7 @@ "description": "Sets the fan speed of the Away profile.", "fields": { "fan_speed": { - "name": "Fan speed", + "name": "[%key:component::vallox::services::set_profile_fan_speed_home::fields::fan_speed::name%]", "description": "[%key:component::vallox::services::set_profile_fan_speed_home::fields::fan_speed::description%]" } } @@ -129,7 +129,7 @@ "description": "Sets the fan speed of the Boost profile.", "fields": { "fan_speed": { - "name": "Fan speed", + "name": "[%key:component::vallox::services::set_profile_fan_speed_home::fields::fan_speed::name%]", "description": "[%key:component::vallox::services::set_profile_fan_speed_home::fields::fan_speed::description%]" } } diff --git a/homeassistant/components/vallox/switch.py b/homeassistant/components/vallox/switch.py index 20b270f8f18..9386f914f58 100644 --- a/homeassistant/components/vallox/switch.py +++ b/homeassistant/components/vallox/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ValloxDataUpdateCoordinator @@ -82,7 +82,7 @@ SWITCH_ENTITIES: tuple[ValloxSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switches.""" diff --git a/homeassistant/components/velbus/binary_sensor.py b/homeassistant/components/velbus/binary_sensor.py index 88dc994efe8..2ddf6605c19 100644 --- a/homeassistant/components/velbus/binary_sensor.py +++ b/homeassistant/components/velbus/binary_sensor.py @@ -4,7 +4,7 @@ from velbusaio.channels import Button as VelbusButton from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity @@ -15,7 +15,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/button.py b/homeassistant/components/velbus/button.py index fc943159123..8f736dcd35b 100644 --- a/homeassistant/components/velbus/button.py +++ b/homeassistant/components/velbus/button.py @@ -10,7 +10,7 @@ from velbusaio.channels import ( from homeassistant.components.button import ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity, api_call @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/climate.py b/homeassistant/components/velbus/climate.py index b2f3077ecee..e31d9a97416 100644 --- a/homeassistant/components/velbus/climate.py +++ b/homeassistant/components/velbus/climate.py @@ -14,7 +14,7 @@ from homeassistant.components.climate import ( from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .const import DOMAIN, PRESET_MODES @@ -26,7 +26,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/cover.py b/homeassistant/components/velbus/cover.py index 2ddea37f2d6..995b7e9d59c 100644 --- a/homeassistant/components/velbus/cover.py +++ b/homeassistant/components/velbus/cover.py @@ -12,7 +12,7 @@ from homeassistant.components.cover import ( CoverEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity, api_call @@ -23,7 +23,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/light.py b/homeassistant/components/velbus/light.py index c134095c2ff..5037e2b1ced 100644 --- a/homeassistant/components/velbus/light.py +++ b/homeassistant/components/velbus/light.py @@ -23,7 +23,7 @@ from homeassistant.components.light import ( from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity, api_call @@ -34,7 +34,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/select.py b/homeassistant/components/velbus/select.py index 6c2dfe0a3b1..1d52b8d4afc 100644 --- a/homeassistant/components/velbus/select.py +++ b/homeassistant/components/velbus/select.py @@ -5,7 +5,7 @@ from velbusaio.channels import SelectedProgram from homeassistant.components.select import SelectEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity, api_call @@ -16,7 +16,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus select based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/sensor.py b/homeassistant/components/velbus/sensor.py index 77833da3ee1..96ef91e8174 100644 --- a/homeassistant/components/velbus/sensor.py +++ b/homeassistant/components/velbus/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity @@ -21,7 +21,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velbus/switch.py b/homeassistant/components/velbus/switch.py index 8256e716d4f..40dc3c09f73 100644 --- a/homeassistant/components/velbus/switch.py +++ b/homeassistant/components/velbus/switch.py @@ -6,7 +6,7 @@ from velbusaio.channels import Relay as VelbusRelay from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VelbusConfigEntry from .entity import VelbusEntity, api_call @@ -17,7 +17,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: VelbusConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Velbus switch based on config_entry.""" await entry.runtime_data.scan_task diff --git a/homeassistant/components/velux/cover.py b/homeassistant/components/velux/cover.py index 90745f601b4..d6bf8905d91 100644 --- a/homeassistant/components/velux/cover.py +++ b/homeassistant/components/velux/cover.py @@ -16,7 +16,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import VeluxEntity @@ -25,7 +25,9 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up cover(s) for Velux platform.""" module = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/velux/light.py b/homeassistant/components/velux/light.py index 14f12a01060..b991239b7a4 100644 --- a/homeassistant/components/velux/light.py +++ b/homeassistant/components/velux/light.py @@ -9,7 +9,7 @@ from pyvlx import Intensity, LighteningDevice from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import VeluxEntity @@ -18,7 +18,9 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up light(s) for Velux platform.""" module = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/velux/scene.py b/homeassistant/components/velux/scene.py index 54888413613..636ab82e819 100644 --- a/homeassistant/components/velux/scene.py +++ b/homeassistant/components/velux/scene.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN @@ -15,7 +15,9 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( - hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + config: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the scenes for Velux platform.""" module = hass.data[DOMAIN][config.entry_id] diff --git a/homeassistant/components/venstar/__init__.py b/homeassistant/components/venstar/__init__.py index 3243c7a6f47..faa47bfc8e4 100644 --- a/homeassistant/components/venstar/__init__.py +++ b/homeassistant/components/venstar/__init__.py @@ -21,14 +21,14 @@ from .coordinator import VenstarDataUpdateCoordinator PLATFORMS = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.SENSOR] -async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up the Venstar thermostat.""" - username = config.data.get(CONF_USERNAME) - password = config.data.get(CONF_PASSWORD) - pin = config.data.get(CONF_PIN) - host = config.data[CONF_HOST] + username = config_entry.data.get(CONF_USERNAME) + password = config_entry.data.get(CONF_PASSWORD) + pin = config_entry.data.get(CONF_PIN) + host = config_entry.data[CONF_HOST] timeout = VENSTAR_TIMEOUT - protocol = "https" if config.data[CONF_SSL] else "http" + protocol = "https" if config_entry.data[CONF_SSL] else "http" client = VenstarColorTouch( addr=host, @@ -41,19 +41,22 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: venstar_data_coordinator = VenstarDataUpdateCoordinator( hass, + config_entry, venstar_connection=client, ) await venstar_data_coordinator.async_config_entry_first_refresh() - hass.data.setdefault(DOMAIN, {})[config.entry_id] = venstar_data_coordinator - await hass.config_entries.async_forward_entry_setups(config, PLATFORMS) + hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = venstar_data_coordinator + await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Unload the config and platforms.""" - unload_ok = await hass.config_entries.async_unload_platforms(config, PLATFORMS) + unload_ok = await hass.config_entries.async_unload_platforms( + config_entry, PLATFORMS + ) if unload_ok: - hass.data[DOMAIN].pop(config.entry_id) + hass.data[DOMAIN].pop(config_entry.entry_id) return unload_ok diff --git a/homeassistant/components/venstar/binary_sensor.py b/homeassistant/components/venstar/binary_sensor.py index 315df09b625..672db463791 100644 --- a/homeassistant/components/venstar/binary_sensor.py +++ b/homeassistant/components/venstar/binary_sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import VenstarEntity @@ -15,7 +15,7 @@ from .entity import VenstarEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vensar device binary_sensors based on a config entry.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/venstar/climate.py b/homeassistant/components/venstar/climate.py index 50f6508e7ed..ade86e8dd71 100644 --- a/homeassistant/components/venstar/climate.py +++ b/homeassistant/components/venstar/climate.py @@ -33,7 +33,10 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import ( @@ -66,7 +69,7 @@ PLATFORM_SCHEMA = CLIMATE_PLATFORM_SCHEMA.extend( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Venstar thermostat.""" venstar_data_coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/venstar/coordinator.py b/homeassistant/components/venstar/coordinator.py index b825775de7f..1d0ff60c1e0 100644 --- a/homeassistant/components/venstar/coordinator.py +++ b/homeassistant/components/venstar/coordinator.py @@ -8,6 +8,7 @@ from datetime import timedelta from requests import RequestException from venstarcolortouch import VenstarColorTouch +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import update_coordinator @@ -17,16 +18,19 @@ from .const import _LOGGER, DOMAIN, VENSTAR_SLEEP class VenstarDataUpdateCoordinator(update_coordinator.DataUpdateCoordinator[None]): """Class to manage fetching Venstar data.""" + config_entry: ConfigEntry + def __init__( self, hass: HomeAssistant, - *, + config_entry: ConfigEntry, venstar_connection: VenstarColorTouch, ) -> None: """Initialize global Venstar data updater.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=timedelta(seconds=60), ) diff --git a/homeassistant/components/venstar/sensor.py b/homeassistant/components/venstar/sensor.py index 94180f6ad79..14e7103a83f 100644 --- a/homeassistant/components/venstar/sensor.py +++ b/homeassistant/components/venstar/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import VenstarDataUpdateCoordinator @@ -81,7 +81,7 @@ class VenstarSensorEntityDescription(SensorEntityDescription): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Venstar device sensors based on a config entry.""" coordinator: VenstarDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/vera/binary_sensor.py b/homeassistant/components/vera/binary_sensor.py index 3438ee81d4a..00780fec8ce 100644 --- a/homeassistant/components/vera/binary_sensor.py +++ b/homeassistant/components/vera/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT, BinarySenso from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -17,7 +17,7 @@ from .entity import VeraEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/climate.py b/homeassistant/components/vera/climate.py index eb2a5206f30..084725f484e 100644 --- a/homeassistant/components/vera/climate.py +++ b/homeassistant/components/vera/climate.py @@ -17,7 +17,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -30,7 +30,7 @@ SUPPORT_HVAC = [HVACMode.COOL, HVACMode.HEAT, HVACMode.HEAT_COOL, HVACMode.OFF] async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/cover.py b/homeassistant/components/vera/cover.py index b5b57f43c0c..8256804b8a3 100644 --- a/homeassistant/components/vera/cover.py +++ b/homeassistant/components/vera/cover.py @@ -10,7 +10,7 @@ from homeassistant.components.cover import ATTR_POSITION, ENTITY_ID_FORMAT, Cove from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -19,7 +19,7 @@ from .entity import VeraEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/light.py b/homeassistant/components/vera/light.py index 9b8ae42f620..f573fcd94ea 100644 --- a/homeassistant/components/vera/light.py +++ b/homeassistant/components/vera/light.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .common import ControllerData, get_controller_data @@ -26,7 +26,7 @@ from .entity import VeraEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/lock.py b/homeassistant/components/vera/lock.py index 18f0b9de3e2..3f76f3a6106 100644 --- a/homeassistant/components/vera/lock.py +++ b/homeassistant/components/vera/lock.py @@ -10,7 +10,7 @@ from homeassistant.components.lock import ENTITY_ID_FORMAT, LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -22,7 +22,7 @@ ATTR_LOW_BATTERY = "low_battery" async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/scene.py b/homeassistant/components/vera/scene.py index 22061f98929..0e504b12303 100644 --- a/homeassistant/components/vera/scene.py +++ b/homeassistant/components/vera/scene.py @@ -9,7 +9,7 @@ import pyvera as veraApi from homeassistant.components.scene import Scene from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import slugify from .common import ControllerData, get_controller_data @@ -19,7 +19,7 @@ from .const import VERA_ID_FORMAT async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/sensor.py b/homeassistant/components/vera/sensor.py index 95f1fa0bd89..d778b4c2e5d 100644 --- a/homeassistant/components/vera/sensor.py +++ b/homeassistant/components/vera/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -32,7 +32,7 @@ SCAN_INTERVAL = timedelta(seconds=5) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/vera/switch.py b/homeassistant/components/vera/switch.py index ad7fbe68458..67be4a7849a 100644 --- a/homeassistant/components/vera/switch.py +++ b/homeassistant/components/vera/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import ControllerData, get_controller_data from .entity import VeraEntity @@ -19,7 +19,7 @@ from .entity import VeraEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" controller_data = get_controller_data(hass, entry) diff --git a/homeassistant/components/verisure/alarm_control_panel.py b/homeassistant/components/verisure/alarm_control_panel.py index 2b9ae7b60b6..7ead1f014c8 100644 --- a/homeassistant/components/verisure/alarm_control_panel.py +++ b/homeassistant/components/verisure/alarm_control_panel.py @@ -13,7 +13,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ALARM_STATE_TO_HA, CONF_GIID, DOMAIN, LOGGER @@ -23,7 +23,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure alarm control panel from a config entry.""" async_add_entities([VerisureAlarm(coordinator=hass.data[DOMAIN][entry.entry_id])]) diff --git a/homeassistant/components/verisure/binary_sensor.py b/homeassistant/components/verisure/binary_sensor.py index 94a44550d47..4d9221c3ca9 100644 --- a/homeassistant/components/verisure/binary_sensor.py +++ b/homeassistant/components/verisure/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.const import ATTR_LAST_TRIP_TIME, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util @@ -22,7 +22,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure binary sensors based on a config entry.""" coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/verisure/camera.py b/homeassistant/components/verisure/camera.py index 7f49f917d83..1f5d48ea197 100644 --- a/homeassistant/components/verisure/camera.py +++ b/homeassistant/components/verisure/camera.py @@ -13,7 +13,7 @@ from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -25,7 +25,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure sensors based on a config entry.""" coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/verisure/lock.py b/homeassistant/components/verisure/lock.py index 16c69ecf2e2..76aeedd05fa 100644 --- a/homeassistant/components/verisure/lock.py +++ b/homeassistant/components/verisure/lock.py @@ -13,7 +13,7 @@ from homeassistant.const import ATTR_CODE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -33,7 +33,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure alarm control panel from a config entry.""" coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/verisure/sensor.py b/homeassistant/components/verisure/sensor.py index 77a576caad8..6ed4784bffb 100644 --- a/homeassistant/components/verisure/sensor.py +++ b/homeassistant/components/verisure/sensor.py @@ -12,7 +12,7 @@ from homeassistant.const import PERCENTAGE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_GIID, DEVICE_TYPE_NAME, DOMAIN @@ -22,7 +22,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure sensors based on a config entry.""" coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/verisure/switch.py b/homeassistant/components/verisure/switch.py index 838e0222087..0deb1da5e95 100644 --- a/homeassistant/components/verisure/switch.py +++ b/homeassistant/components/verisure/switch.py @@ -9,7 +9,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import CONF_GIID, DOMAIN @@ -19,7 +19,7 @@ from .coordinator import VerisureDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Verisure alarm control panel from a config entry.""" coordinator: VerisureDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/version/__init__.py b/homeassistant/components/version/__init__.py index cf13821dc8a..6fabf97c8dd 100644 --- a/homeassistant/components/version/__init__.py +++ b/homeassistant/components/version/__init__.py @@ -6,7 +6,6 @@ import logging from pyhaversion import HaVersion -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -18,12 +17,10 @@ from .const import ( CONF_SOURCE, PLATFORMS, ) -from .coordinator import VersionDataUpdateCoordinator +from .coordinator import VersionConfigEntry, VersionDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) -type VersionConfigEntry = ConfigEntry[VersionDataUpdateCoordinator] - async def async_setup_entry(hass: HomeAssistant, entry: VersionConfigEntry) -> bool: """Set up the version integration from a config entry.""" @@ -40,6 +37,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: VersionConfigEntry) -> b coordinator = VersionDataUpdateCoordinator( hass=hass, + config_entry=entry, api=HaVersion( session=async_get_clientsession(hass), source=entry.data[CONF_SOURCE], diff --git a/homeassistant/components/version/binary_sensor.py b/homeassistant/components/version/binary_sensor.py index 827029e1d8c..900daa7aba1 100644 --- a/homeassistant/components/version/binary_sensor.py +++ b/homeassistant/components/version/binary_sensor.py @@ -11,10 +11,10 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import CONF_NAME, EntityCategory, __version__ as HA_VERSION from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import VersionConfigEntry from .const import CONF_SOURCE, DEFAULT_NAME +from .coordinator import VersionConfigEntry from .entity import VersionEntity HA_VERSION_OBJECT = AwesomeVersion(HA_VERSION) @@ -23,7 +23,7 @@ HA_VERSION_OBJECT = AwesomeVersion(HA_VERSION) async def async_setup_entry( hass: HomeAssistant, config_entry: VersionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up version binary_sensors.""" coordinator = config_entry.runtime_data diff --git a/homeassistant/components/version/coordinator.py b/homeassistant/components/version/coordinator.py index 05adf07642b..349ede53d33 100644 --- a/homeassistant/components/version/coordinator.py +++ b/homeassistant/components/version/coordinator.py @@ -14,21 +14,25 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import DOMAIN, LOGGER, UPDATE_COORDINATOR_UPDATE_INTERVAL +type VersionConfigEntry = ConfigEntry[VersionDataUpdateCoordinator] + class VersionDataUpdateCoordinator(DataUpdateCoordinator[None]): """Data update coordinator for Version entities.""" - config_entry: ConfigEntry + config_entry: VersionConfigEntry def __init__( self, hass: HomeAssistant, + config_entry: VersionConfigEntry, api: HaVersion, ) -> None: """Initialize the coordinator.""" super().__init__( hass=hass, logger=LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=UPDATE_COORDINATOR_UPDATE_INTERVAL, ) diff --git a/homeassistant/components/version/diagnostics.py b/homeassistant/components/version/diagnostics.py index ca7318f468b..bcc94bd8da4 100644 --- a/homeassistant/components/version/diagnostics.py +++ b/homeassistant/components/version/diagnostics.py @@ -9,7 +9,7 @@ from attr import asdict from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er -from . import VersionConfigEntry +from .coordinator import VersionConfigEntry async def async_get_config_entry_diagnostics( diff --git a/homeassistant/components/version/sensor.py b/homeassistant/components/version/sensor.py index e1d552bcd36..7e173b46d36 100644 --- a/homeassistant/components/version/sensor.py +++ b/homeassistant/components/version/sensor.py @@ -7,18 +7,18 @@ from typing import Any from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType -from . import VersionConfigEntry from .const import CONF_SOURCE, DEFAULT_NAME +from .coordinator import VersionConfigEntry from .entity import VersionEntity async def async_setup_entry( hass: HomeAssistant, entry: VersionConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up version sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/vesync/binary_sensor.py b/homeassistant/components/vesync/binary_sensor.py index dd1b6398c06..620222e4d2f 100644 --- a/homeassistant/components/vesync/binary_sensor.py +++ b/homeassistant/components/vesync/binary_sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import rgetattr from .const import DOMAIN, VS_COORDINATOR, VS_DEVICES, VS_DISCOVERY @@ -52,7 +52,7 @@ SENSOR_DESCRIPTIONS: tuple[VeSyncBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary_sensor platform.""" diff --git a/homeassistant/components/vesync/fan.py b/homeassistant/components/vesync/fan.py index 21a92a22db2..daf734d50a8 100644 --- a/homeassistant/components/vesync/fan.py +++ b/homeassistant/components/vesync/fan.py @@ -12,7 +12,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -72,7 +72,7 @@ SPEED_RANGE = { # off is not included async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the VeSync fan platform.""" diff --git a/homeassistant/components/vesync/humidifier.py b/homeassistant/components/vesync/humidifier.py index 5afe7360673..9a98a39aa8c 100644 --- a/homeassistant/components/vesync/humidifier.py +++ b/homeassistant/components/vesync/humidifier.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import is_humidifier from .const import ( @@ -50,7 +50,7 @@ VS_TO_HA_MODE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the VeSync humidifier platform.""" @@ -71,7 +71,7 @@ async def async_setup_entry( @callback def _setup_entities( devices: list[VeSyncBaseDevice], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: VeSyncDataCoordinator, ): """Add humidifier entities.""" diff --git a/homeassistant/components/vesync/light.py b/homeassistant/components/vesync/light.py index 40f68986145..887400b2cf0 100644 --- a/homeassistant/components/vesync/light.py +++ b/homeassistant/components/vesync/light.py @@ -14,7 +14,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import DEV_TYPE_TO_HA, DOMAIN, VS_COORDINATOR, VS_DEVICES, VS_DISCOVERY @@ -29,7 +29,7 @@ MIN_MIREDS = 153 # 1,000,000 divided by 6500 Kelvin = 153 Mireds async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up lights.""" diff --git a/homeassistant/components/vesync/number.py b/homeassistant/components/vesync/number.py index 3c43cce28cf..707dd6ab30e 100644 --- a/homeassistant/components/vesync/number.py +++ b/homeassistant/components/vesync/number.py @@ -14,7 +14,7 @@ from homeassistant.components.number import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import is_humidifier from .const import DOMAIN, VS_COORDINATOR, VS_DEVICES, VS_DISCOVERY @@ -51,7 +51,7 @@ NUMBER_DESCRIPTIONS: list[VeSyncNumberEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up number entities.""" @@ -72,7 +72,7 @@ async def async_setup_entry( @callback def _setup_entities( devices: list[VeSyncBaseDevice], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: VeSyncDataCoordinator, ): """Add number entities.""" diff --git a/homeassistant/components/vesync/sensor.py b/homeassistant/components/vesync/sensor.py index bf52050d745..3bc6608989a 100644 --- a/homeassistant/components/vesync/sensor.py +++ b/homeassistant/components/vesync/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .common import is_humidifier @@ -194,7 +194,7 @@ SENSORS: tuple[VeSyncSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switches.""" @@ -215,7 +215,7 @@ async def async_setup_entry( @callback def _setup_entities( devices: list[VeSyncBaseDevice], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: VeSyncDataCoordinator, ): """Check if device is online and add entity.""" diff --git a/homeassistant/components/vesync/switch.py b/homeassistant/components/vesync/switch.py index 3d2dc8a8e96..3e8deedb4ad 100644 --- a/homeassistant/components/vesync/switch.py +++ b/homeassistant/components/vesync/switch.py @@ -15,7 +15,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import is_outlet, is_wall_switch from .const import DOMAIN, VS_COORDINATOR, VS_DEVICES, VS_DISCOVERY @@ -51,7 +51,7 @@ SENSOR_DESCRIPTIONS: Final[tuple[VeSyncSwitchEntityDescription, ...]] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up switch platform.""" diff --git a/homeassistant/components/vicare/binary_sensor.py b/homeassistant/components/vicare/binary_sensor.py index 9d216404156..902dfd18d30 100644 --- a/homeassistant/components/vicare/binary_sensor.py +++ b/homeassistant/components/vicare/binary_sensor.py @@ -25,7 +25,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ViCareEntity from .types import ViCareConfigEntry, ViCareDevice, ViCareRequiredKeysMixin @@ -157,7 +157,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the ViCare binary sensor devices.""" async_add_entities( diff --git a/homeassistant/components/vicare/button.py b/homeassistant/components/vicare/button.py index 65182990bfb..9c30a9e68ee 100644 --- a/homeassistant/components/vicare/button.py +++ b/homeassistant/components/vicare/button.py @@ -18,7 +18,7 @@ import requests from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ViCareEntity from .types import ViCareConfigEntry, ViCareDevice, ViCareRequiredKeysMixinWithSet @@ -66,7 +66,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the ViCare button entities.""" async_add_entities( diff --git a/homeassistant/components/vicare/climate.py b/homeassistant/components/vicare/climate.py index f62fdc363a6..9fba83c5700 100644 --- a/homeassistant/components/vicare/climate.py +++ b/homeassistant/components/vicare/climate.py @@ -33,7 +33,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import ViCareEntity @@ -98,7 +98,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ViCare climate platform.""" diff --git a/homeassistant/components/vicare/entity.py b/homeassistant/components/vicare/entity.py index 11955a94b94..7b73d2e5ba3 100644 --- a/homeassistant/components/vicare/entity.py +++ b/homeassistant/components/vicare/entity.py @@ -28,6 +28,7 @@ class ViCareEntity(Entity): """Initialize the entity.""" gateway_serial = device_config.getConfig().serial device_id = device_config.getId() + model = device_config.getModel().replace("_", " ") identifier = ( f"{gateway_serial}_{device_serial.replace('zigbee-', 'zigbee_')}" @@ -45,8 +46,8 @@ class ViCareEntity(Entity): self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, identifier)}, serial_number=device_serial, - name=device_config.getModel(), + name=model, manufacturer="Viessmann", - model=device_config.getModel(), + model=model, configuration_url="https://developer.viessmann.com/", ) diff --git a/homeassistant/components/vicare/fan.py b/homeassistant/components/vicare/fan.py index c5e24f46c33..26136260a4b 100644 --- a/homeassistant/components/vicare/fan.py +++ b/homeassistant/components/vicare/fan.py @@ -18,7 +18,7 @@ from requests.exceptions import ConnectionError as RequestConnectionError from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -111,7 +111,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ViCare fan platform.""" async_add_entities( diff --git a/homeassistant/components/vicare/number.py b/homeassistant/components/vicare/number.py index 534c0752cc1..04c4088bd3e 100644 --- a/homeassistant/components/vicare/number.py +++ b/homeassistant/components/vicare/number.py @@ -27,7 +27,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ViCareEntity from .types import ( @@ -374,7 +374,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the ViCare number devices.""" async_add_entities( diff --git a/homeassistant/components/vicare/sensor.py b/homeassistant/components/vicare/sensor.py index c99e7857d9b..cc79812b504 100644 --- a/homeassistant/components/vicare/sensor.py +++ b/homeassistant/components/vicare/sensor.py @@ -37,7 +37,7 @@ from homeassistant.const import ( UnitOfVolumeFlowRate, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( VICARE_CUBIC_METER, @@ -883,6 +883,14 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = ( entity_category=EntityCategory.DIAGNOSTIC, value_getter=lambda api: api.getSeasonalPerformanceFactorHeating(), ), + ViCareSensorEntityDescription( + key="battery_level", + native_unit_of_measurement=PERCENTAGE, + state_class=SensorStateClass.MEASUREMENT, + device_class=SensorDeviceClass.BATTERY, + entity_category=EntityCategory.DIAGNOSTIC, + value_getter=lambda api: api.getBatteryLevel(), + ), ) CIRCUIT_SENSORS: tuple[ViCareSensorEntityDescription, ...] = ( @@ -1033,7 +1041,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the ViCare sensor devices.""" async_add_entities( diff --git a/homeassistant/components/vicare/water_heater.py b/homeassistant/components/vicare/water_heater.py index 114ff620c3f..f92c9e3e1af 100644 --- a/homeassistant/components/vicare/water_heater.py +++ b/homeassistant/components/vicare/water_heater.py @@ -22,7 +22,7 @@ from homeassistant.components.water_heater import ( ) from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ViCareEntity from .types import ViCareConfigEntry, ViCareDevice @@ -80,7 +80,7 @@ def _build_entities( async def async_setup_entry( hass: HomeAssistant, config_entry: ViCareConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ViCare water heater platform.""" async_add_entities( diff --git a/homeassistant/components/vilfo/sensor.py b/homeassistant/components/vilfo/sensor.py index 77a7df7a0a8..fa2d5cae196 100644 --- a/homeassistant/components/vilfo/sensor.py +++ b/homeassistant/components/vilfo/sensor.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_API_DATA_FIELD_BOOT_TIME, @@ -51,7 +51,7 @@ SENSOR_TYPES: tuple[VilfoSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add Vilfo Router entities from a config_entry.""" vilfo = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/vizio/media_player.py b/homeassistant/components/vizio/media_player.py index 5711d8fbac9..d44db5e45ee 100644 --- a/homeassistant/components/vizio/media_player.py +++ b/homeassistant/components/vizio/media_player.py @@ -32,7 +32,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_ADDITIONAL_CONFIGS, @@ -63,7 +63,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Vizio media player entry.""" host = config_entry.data[CONF_HOST] diff --git a/homeassistant/components/vlc_telnet/media_player.py b/homeassistant/components/vlc_telnet/media_player.py index 9597c706570..6ae9fbb9f5a 100644 --- a/homeassistant/components/vlc_telnet/media_player.py +++ b/homeassistant/components/vlc_telnet/media_player.py @@ -22,7 +22,7 @@ from homeassistant.config_entries import SOURCE_HASSIO, ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import VlcConfigEntry @@ -39,7 +39,9 @@ def _get_str(data: dict, key: str) -> str | None: async def async_setup_entry( - hass: HomeAssistant, entry: VlcConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: VlcConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the vlc platform.""" # CONF_NAME is only present in imported YAML. diff --git a/homeassistant/components/vodafone_station/button.py b/homeassistant/components/vodafone_station/button.py index efea011a541..9812cef48d6 100644 --- a/homeassistant/components/vodafone_station/button.py +++ b/homeassistant/components/vodafone_station/button.py @@ -14,7 +14,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import _LOGGER, DOMAIN @@ -67,7 +67,9 @@ BUTTON_TYPES: Final = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" _LOGGER.debug("Setting up Vodafone Station buttons") diff --git a/homeassistant/components/vodafone_station/device_tracker.py b/homeassistant/components/vodafone_station/device_tracker.py index 4af0b85e003..ece4bd05a02 100644 --- a/homeassistant/components/vodafone_station/device_tracker.py +++ b/homeassistant/components/vodafone_station/device_tracker.py @@ -6,7 +6,7 @@ from homeassistant.components.device_tracker import ScannerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import _LOGGER, DOMAIN @@ -14,7 +14,9 @@ from .coordinator import VodafoneStationDeviceInfo, VodafoneStationRouter async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device tracker for Vodafone Station component.""" @@ -40,7 +42,7 @@ async def async_setup_entry( @callback def async_add_new_tracked_entities( coordinator: VodafoneStationRouter, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, tracked: set[str], ) -> None: """Add new tracker entities from the router.""" diff --git a/homeassistant/components/vodafone_station/sensor.py b/homeassistant/components/vodafone_station/sensor.py index 307fcaf0ea8..d29fb7f21e9 100644 --- a/homeassistant/components/vodafone_station/sensor.py +++ b/homeassistant/components/vodafone_station/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfDataRate from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import _LOGGER, DOMAIN, LINE_TYPES @@ -165,7 +165,9 @@ SENSOR_TYPES: Final = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" _LOGGER.debug("Setting up Vodafone Station sensors") diff --git a/homeassistant/components/voip/assist_satellite.py b/homeassistant/components/voip/assist_satellite.py index 1877b8c655c..a0aeaaf38d3 100644 --- a/homeassistant/components/voip/assist_satellite.py +++ b/homeassistant/components/voip/assist_satellite.py @@ -28,9 +28,17 @@ from homeassistant.components.assist_satellite import ( from homeassistant.components.network import async_get_source_ip from homeassistant.config_entries import ConfigEntry from homeassistant.core import Context, HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import CHANNELS, CONF_SIP_PORT, DOMAIN, RATE, RTP_AUDIO_SETTINGS, WIDTH +from .const import ( + CHANNELS, + CONF_SIP_PORT, + CONF_SIP_USER, + DOMAIN, + RATE, + RTP_AUDIO_SETTINGS, + WIDTH, +) from .devices import VoIPDevice from .entity import VoIPEntity @@ -64,7 +72,7 @@ _TONE_FILENAMES: dict[Tones, str] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up VoIP Assist satellite entity.""" domain_data: DomainData = hass.data[DOMAIN] @@ -199,7 +207,10 @@ class VoipAssistSatellite(VoIPEntity, AssistSatelliteEntity, RtpDatagramProtocol # HA SIP server source_ip = await async_get_source_ip(self.hass) sip_port = self.config_entry.options.get(CONF_SIP_PORT, SIP_PORT) - source_endpoint = get_sip_endpoint(host=source_ip, port=sip_port) + sip_user = self.config_entry.options.get(CONF_SIP_USER) + source_endpoint = get_sip_endpoint( + host=source_ip, port=sip_port, username=sip_user + ) try: # VoIP ID is SIP header diff --git a/homeassistant/components/voip/binary_sensor.py b/homeassistant/components/voip/binary_sensor.py index f38b228c46c..34dac4b6068 100644 --- a/homeassistant/components/voip/binary_sensor.py +++ b/homeassistant/components/voip/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import issue_registry as ir -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .devices import VoIPDevice @@ -24,7 +24,7 @@ if TYPE_CHECKING: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up VoIP binary sensor entities.""" domain_data: DomainData = hass.data[DOMAIN] diff --git a/homeassistant/components/voip/config_flow.py b/homeassistant/components/voip/config_flow.py index 63dcb8f86ee..7ae603f0f6a 100644 --- a/homeassistant/components/voip/config_flow.py +++ b/homeassistant/components/voip/config_flow.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ( from homeassistant.core import callback from homeassistant.helpers import config_validation as cv -from .const import CONF_SIP_PORT, DOMAIN +from .const import CONF_SIP_PORT, CONF_SIP_USER, DOMAIN class VoIPConfigFlow(ConfigFlow, domain=DOMAIN): @@ -58,7 +58,15 @@ class VoipOptionsFlowHandler(OptionsFlow): ) -> ConfigFlowResult: """Manage the options.""" if user_input is not None: - return self.async_create_entry(title="", data=user_input) + if CONF_SIP_USER in user_input and not user_input[CONF_SIP_USER]: + del user_input[CONF_SIP_USER] + self.hass.config_entries.async_update_entry( + self.config_entry, options=user_input + ) + return self.async_create_entry( + title="", + data=user_input, + ) return self.async_show_form( step_id="init", @@ -70,7 +78,15 @@ class VoipOptionsFlowHandler(OptionsFlow): CONF_SIP_PORT, SIP_PORT, ), - ): cv.port + ): cv.port, + vol.Optional( + CONF_SIP_USER, + description={ + "suggested_value": self.config_entry.options.get( + CONF_SIP_USER, None + ) + }, + ): vol.Any(None, cv.string), } ), ) diff --git a/homeassistant/components/voip/const.py b/homeassistant/components/voip/const.py index b4ee5d8ce7a..9a4403f9df2 100644 --- a/homeassistant/components/voip/const.py +++ b/homeassistant/components/voip/const.py @@ -13,3 +13,4 @@ RTP_AUDIO_SETTINGS = { } CONF_SIP_PORT = "sip_port" +CONF_SIP_USER = "sip_user" diff --git a/homeassistant/components/voip/select.py b/homeassistant/components/voip/select.py index f145f866ae3..bfce112d0c5 100644 --- a/homeassistant/components/voip/select.py +++ b/homeassistant/components/voip/select.py @@ -10,7 +10,7 @@ from homeassistant.components.assist_pipeline.select import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .devices import VoIPDevice @@ -23,7 +23,7 @@ if TYPE_CHECKING: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up VoIP switch entities.""" domain_data: DomainData = hass.data[DOMAIN] diff --git a/homeassistant/components/voip/strings.json b/homeassistant/components/voip/strings.json index c25c22f3f80..96c902bf39a 100644 --- a/homeassistant/components/voip/strings.json +++ b/homeassistant/components/voip/strings.json @@ -53,7 +53,8 @@ "step": { "init": { "data": { - "sip_port": "SIP port" + "sip_port": "SIP port", + "sip_user": "SIP user" } } } diff --git a/homeassistant/components/voip/switch.py b/homeassistant/components/voip/switch.py index f8484241fc5..7690b8f125c 100644 --- a/homeassistant/components/voip/switch.py +++ b/homeassistant/components/voip/switch.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import restore_state -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .devices import VoIPDevice @@ -22,7 +22,7 @@ if TYPE_CHECKING: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up VoIP switch entities.""" domain_data: DomainData = hass.data[DOMAIN] diff --git a/homeassistant/components/volumio/media_player.py b/homeassistant/components/volumio/media_player.py index 5ba67d7974f..514f1ad9221 100644 --- a/homeassistant/components/volumio/media_player.py +++ b/homeassistant/components/volumio/media_player.py @@ -21,7 +21,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import Throttle from .browse_media import browse_node, browse_top_level @@ -33,7 +33,7 @@ PLAYLIST_UPDATE_INTERVAL = timedelta(seconds=15) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Volumio media player platform.""" diff --git a/homeassistant/components/volvooncall/binary_sensor.py b/homeassistant/components/volvooncall/binary_sensor.py index e6104f8d87c..2ba8d19e3db 100644 --- a/homeassistant/components/volvooncall/binary_sensor.py +++ b/homeassistant/components/volvooncall/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, VOLVO_DISCOVERY_NEW from .coordinator import VolvoUpdateCoordinator @@ -24,7 +24,7 @@ from .entity import VolvoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure binary_sensors from a config entry created in the integrations UI.""" coordinator: VolvoUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/volvooncall/device_tracker.py b/homeassistant/components/volvooncall/device_tracker.py index 96fe5a644bb..018acb02d49 100644 --- a/homeassistant/components/volvooncall/device_tracker.py +++ b/homeassistant/components/volvooncall/device_tracker.py @@ -8,7 +8,7 @@ from homeassistant.components.device_tracker import TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, VOLVO_DISCOVERY_NEW from .coordinator import VolvoUpdateCoordinator @@ -18,7 +18,7 @@ from .entity import VolvoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure device_trackers from a config entry created in the integrations UI.""" coordinator: VolvoUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/volvooncall/lock.py b/homeassistant/components/volvooncall/lock.py index cff5df35750..75b54e9dbbc 100644 --- a/homeassistant/components/volvooncall/lock.py +++ b/homeassistant/components/volvooncall/lock.py @@ -10,7 +10,7 @@ from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, VOLVO_DISCOVERY_NEW from .coordinator import VolvoUpdateCoordinator @@ -20,7 +20,7 @@ from .entity import VolvoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure locks from a config entry created in the integrations UI.""" coordinator: VolvoUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/volvooncall/sensor.py b/homeassistant/components/volvooncall/sensor.py index 9916d37197b..feb7248ccaf 100644 --- a/homeassistant/components/volvooncall/sensor.py +++ b/homeassistant/components/volvooncall/sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, VOLVO_DISCOVERY_NEW from .coordinator import VolvoUpdateCoordinator @@ -18,7 +18,7 @@ from .entity import VolvoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure sensors from a config entry created in the integrations UI.""" coordinator: VolvoUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/volvooncall/switch.py b/homeassistant/components/volvooncall/switch.py index 7e60f47fb44..ff321577348 100644 --- a/homeassistant/components/volvooncall/switch.py +++ b/homeassistant/components/volvooncall/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, VOLVO_DISCOVERY_NEW from .coordinator import VolvoUpdateCoordinator @@ -20,7 +20,7 @@ from .entity import VolvoEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Configure binary_sensors from a config entry created in the integrations UI.""" coordinator: VolvoUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/vulcan/calendar.py b/homeassistant/components/vulcan/calendar.py index a89b6b4a116..c2ef8b70d46 100644 --- a/homeassistant/components/vulcan/calendar.py +++ b/homeassistant/components/vulcan/calendar.py @@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity import generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN from .fetch_data import get_lessons, get_student_info @@ -31,7 +31,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the calendar platform for entity.""" client = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wake_on_lan/button.py b/homeassistant/components/wake_on_lan/button.py index 4d6b19bdd8e..e9cf69b1fe7 100644 --- a/homeassistant/components/wake_on_lan/button.py +++ b/homeassistant/components/wake_on_lan/button.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_BROADCAST_ADDRESS, CONF_BROADCAST_PORT, CONF_MAC from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback _LOGGER = logging.getLogger(__name__) @@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Wake on LAN button entry.""" broadcast_address: str | None = entry.options.get(CONF_BROADCAST_ADDRESS) diff --git a/homeassistant/components/wallbox/lock.py b/homeassistant/components/wallbox/lock.py index 4853a9104f2..ef35734ed7e 100644 --- a/homeassistant/components/wallbox/lock.py +++ b/homeassistant/components/wallbox/lock.py @@ -8,7 +8,7 @@ from homeassistant.components.lock import LockEntity, LockEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CHARGER_DATA_KEY, @@ -28,7 +28,9 @@ LOCK_TYPES: dict[str, LockEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create wallbox lock entities in HASS.""" coordinator: WallboxCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wallbox/number.py b/homeassistant/components/wallbox/number.py index 24cdd16f99d..462266636d7 100644 --- a/homeassistant/components/wallbox/number.py +++ b/homeassistant/components/wallbox/number.py @@ -13,7 +13,7 @@ from homeassistant.components.number import NumberEntity, NumberEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( BIDIRECTIONAL_MODEL_PREFIXES, @@ -82,7 +82,9 @@ NUMBER_TYPES: dict[str, WallboxNumberEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create wallbox number entities in HASS.""" coordinator: WallboxCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wallbox/sensor.py b/homeassistant/components/wallbox/sensor.py index 18d8afb5612..78b26520bec 100644 --- a/homeassistant/components/wallbox/sensor.py +++ b/homeassistant/components/wallbox/sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -157,7 +157,9 @@ SENSOR_TYPES: dict[str, WallboxSensorEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create wallbox sensor entities in HASS.""" coordinator: WallboxCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wallbox/switch.py b/homeassistant/components/wallbox/switch.py index 06c2674579d..30275951ab2 100644 --- a/homeassistant/components/wallbox/switch.py +++ b/homeassistant/components/wallbox/switch.py @@ -7,7 +7,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CHARGER_DATA_KEY, @@ -29,7 +29,9 @@ SWITCH_TYPES: dict[str, SwitchEntityDescription] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create wallbox sensor entities in HASS.""" coordinator: WallboxCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/waqi/sensor.py b/homeassistant/components/waqi/sensor.py index 4c921c68336..59daf60392e 100644 --- a/homeassistant/components/waqi/sensor.py +++ b/homeassistant/components/waqi/sensor.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PERCENTAGE, UnitOfPressure, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -138,7 +138,9 @@ SENSORS: list[WAQISensorEntityDescription] = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WAQI sensor.""" coordinator: WAQIDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/watergate/sensor.py b/homeassistant/components/watergate/sensor.py index 44630d2f587..5aced8b7488 100644 --- a/homeassistant/components/watergate/sensor.py +++ b/homeassistant/components/watergate/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfVolume, UnitOfVolumeFlowRate, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -182,7 +182,7 @@ DESCRIPTIONS: list[WatergateSensorEntityDescription] = [ async def async_setup_entry( hass: HomeAssistant, config_entry: WatergateConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all entries for Watergate Platform.""" diff --git a/homeassistant/components/watergate/valve.py b/homeassistant/components/watergate/valve.py index ce914ebbb55..cb6bfa7bd59 100644 --- a/homeassistant/components/watergate/valve.py +++ b/homeassistant/components/watergate/valve.py @@ -8,7 +8,7 @@ from homeassistant.components.valve import ( ValveState, ) from homeassistant.core import callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .coordinator import WatergateConfigEntry, WatergateDataCoordinator from .entity import WatergateEntity @@ -20,7 +20,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: WatergateConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all entries for Watergate Platform.""" diff --git a/homeassistant/components/watttime/sensor.py b/homeassistant/components/watttime/sensor.py index c6cc81580d7..d3aa9d8f895 100644 --- a/homeassistant/components/watttime/sensor.py +++ b/homeassistant/components/watttime/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, @@ -52,7 +52,9 @@ REALTIME_EMISSIONS_SENSOR_DESCRIPTIONS = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WattTime sensors based on a config entry.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/waze_travel_time/sensor.py b/homeassistant/components/waze_travel_time/sensor.py index a216a02f61e..1f21cc2ea78 100644 --- a/homeassistant/components/waze_travel_time/sensor.py +++ b/homeassistant/components/waze_travel_time/sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( ) from homeassistant.core import CoreState, HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.location import find_coordinates @@ -57,7 +57,7 @@ SECONDS_BETWEEN_API_CALLS = 0.5 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a Waze travel time sensor entry.""" destination = config_entry.data[CONF_DESTINATION] diff --git a/homeassistant/components/weatherflow/sensor.py b/homeassistant/components/weatherflow/sensor.py index cacede55c42..683413236c1 100644 --- a/homeassistant/components/weatherflow/sensor.py +++ b/homeassistant/components/weatherflow/sensor.py @@ -40,7 +40,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.unit_system import METRIC_SYSTEM @@ -285,7 +285,7 @@ SENSORS: tuple[WeatherFlowSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeatherFlow sensors using config entry.""" diff --git a/homeassistant/components/weatherflow_cloud/sensor.py b/homeassistant/components/weatherflow_cloud/sensor.py index aeab955878f..d2c62b5f281 100644 --- a/homeassistant/components/weatherflow_cloud/sensor.py +++ b/homeassistant/components/weatherflow_cloud/sensor.py @@ -17,7 +17,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfLength, UnitOfPressure, UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN @@ -172,7 +172,7 @@ WF_SENSORS: tuple[WeatherFlowCloudSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeatherFlow sensors based on a config entry.""" diff --git a/homeassistant/components/weatherflow_cloud/weather.py b/homeassistant/components/weatherflow_cloud/weather.py index c475f2974a9..3cb1f477095 100644 --- a/homeassistant/components/weatherflow_cloud/weather.py +++ b/homeassistant/components/weatherflow_cloud/weather.py @@ -17,7 +17,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, STATE_MAP from .coordinator import WeatherFlowCloudDataUpdateCoordinator @@ -27,7 +27,7 @@ from .entity import WeatherFlowCloudEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" coordinator: WeatherFlowCloudDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/weatherkit/sensor.py b/homeassistant/components/weatherkit/sensor.py index d9c17bb855a..b3639fa5356 100644 --- a/homeassistant/components/weatherkit/sensor.py +++ b/homeassistant/components/weatherkit/sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfVolumetricFlux from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -36,7 +36,7 @@ SENSORS = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add sensor entities from a config_entry.""" coordinator: WeatherKitDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/weatherkit/weather.py b/homeassistant/components/weatherkit/weather.py index 98816d520ba..b57e488d06a 100644 --- a/homeassistant/components/weatherkit/weather.py +++ b/homeassistant/components/weatherkit/weather.py @@ -29,7 +29,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_CURRENT_WEATHER, @@ -45,7 +45,7 @@ from .entity import WeatherKitEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" coordinator: WeatherKitDataUpdateCoordinator = hass.data[DOMAIN][ diff --git a/homeassistant/components/webmin/sensor.py b/homeassistant/components/webmin/sensor.py index 785140393a2..a21c73bed13 100644 --- a/homeassistant/components/webmin/sensor.py +++ b/homeassistant/components/webmin/sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import PERCENTAGE, UnitOfInformation from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import WebminConfigEntry @@ -200,7 +200,7 @@ def generate_filesystem_sensor_description( async def async_setup_entry( hass: HomeAssistant, entry: WebminConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Webmin sensors based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/webostv/const.py b/homeassistant/components/webostv/const.py index e505611db52..118ea7b32db 100644 --- a/homeassistant/components/webostv/const.py +++ b/homeassistant/components/webostv/const.py @@ -31,6 +31,7 @@ WEBOSTV_EXCEPTIONS = ( WebOsTvCommandError, aiohttp.ClientConnectorError, aiohttp.ServerDisconnectedError, + aiohttp.WSMessageTypeError, asyncio.CancelledError, asyncio.TimeoutError, ) diff --git a/homeassistant/components/webostv/media_player.py b/homeassistant/components/webostv/media_player.py index 5c47a5e775f..33c09aa8708 100644 --- a/homeassistant/components/webostv/media_player.py +++ b/homeassistant/components/webostv/media_player.py @@ -28,7 +28,7 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.trigger import PluggableAction from homeassistant.helpers.typing import VolDictType @@ -102,7 +102,7 @@ SERVICES = ( async def async_setup_entry( hass: HomeAssistant, entry: WebOsTvConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the LG webOS TV platform.""" platform = entity_platform.async_get_current_platform() diff --git a/homeassistant/components/weheat/binary_sensor.py b/homeassistant/components/weheat/binary_sensor.py index 0ffa876ad0f..6a4a03a1e48 100644 --- a/homeassistant/components/weheat/binary_sensor.py +++ b/homeassistant/components/weheat/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntityDescription, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .coordinator import WeheatConfigEntry, WeheatDataUpdateCoordinator @@ -64,7 +64,7 @@ BINARY_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: WeheatConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors for weheat heat pump.""" entities = [ diff --git a/homeassistant/components/weheat/sensor.py b/homeassistant/components/weheat/sensor.py index 5d948c6d565..615bfd30d18 100644 --- a/homeassistant/components/weheat/sensor.py +++ b/homeassistant/components/weheat/sensor.py @@ -19,7 +19,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( @@ -200,7 +200,7 @@ DHW_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, entry: WeheatConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors for weheat heat pump.""" entities = [ diff --git a/homeassistant/components/wemo/binary_sensor.py b/homeassistant/components/wemo/binary_sensor.py index f2bcb04d96f..4ed361b18ba 100644 --- a/homeassistant/components/wemo/binary_sensor.py +++ b/homeassistant/components/wemo/binary_sensor.py @@ -5,7 +5,7 @@ from pywemo import Insight, Maker, StandbyState from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import async_wemo_dispatcher_connect from .coordinator import DeviceCoordinator @@ -15,7 +15,7 @@ from .entity import WemoBinaryStateEntity, WemoEntity async def async_setup_entry( hass: HomeAssistant, _config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeMo binary sensors.""" diff --git a/homeassistant/components/wemo/coordinator.py b/homeassistant/components/wemo/coordinator.py index 1f25c12f7ca..0aaedf598d2 100644 --- a/homeassistant/components/wemo/coordinator.py +++ b/homeassistant/components/wemo/coordinator.py @@ -88,13 +88,17 @@ class Options: class DeviceCoordinator(DataUpdateCoordinator[None]): """Home Assistant wrapper for a pyWeMo device.""" + config_entry: ConfigEntry options: Options | None = None - def __init__(self, hass: HomeAssistant, wemo: WeMoDevice) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, wemo: WeMoDevice + ) -> None: """Initialize DeviceCoordinator.""" super().__init__( hass, _LOGGER, + config_entry=config_entry, name=wemo.name, update_interval=timedelta(seconds=30), ) @@ -285,7 +289,7 @@ async def async_register_device( hass: HomeAssistant, config_entry: ConfigEntry, wemo: WeMoDevice ) -> DeviceCoordinator: """Register a device with home assistant and enable pywemo event callbacks.""" - device = DeviceCoordinator(hass, wemo) + device = DeviceCoordinator(hass, config_entry, wemo) await device.async_refresh() if not device.last_update_success and device.last_exception: raise device.last_exception diff --git a/homeassistant/components/wemo/fan.py b/homeassistant/components/wemo/fan.py index 42dae679aa5..edfdfc1c78c 100644 --- a/homeassistant/components/wemo/fan.py +++ b/homeassistant/components/wemo/fan.py @@ -13,7 +13,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.util.percentage import ( percentage_to_ranged_value, @@ -48,7 +48,7 @@ SET_HUMIDITY_SCHEMA: VolDictType = { async def async_setup_entry( hass: HomeAssistant, _config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeMo binary sensors.""" diff --git a/homeassistant/components/wemo/light.py b/homeassistant/components/wemo/light.py index 619e0952457..838073be84a 100644 --- a/homeassistant/components/wemo/light.py +++ b/homeassistant/components/wemo/light.py @@ -20,7 +20,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from . import async_wemo_dispatcher_connect @@ -35,7 +35,7 @@ WEMO_OFF = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeMo lights.""" @@ -53,7 +53,7 @@ async def async_setup_entry( def async_setup_bridge( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, coordinator: DeviceCoordinator, ) -> None: """Set up a WeMo link.""" diff --git a/homeassistant/components/wemo/sensor.py b/homeassistant/components/wemo/sensor.py index 90e3546eaf7..76a0265d7da 100644 --- a/homeassistant/components/wemo/sensor.py +++ b/homeassistant/components/wemo/sensor.py @@ -15,7 +15,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import async_wemo_dispatcher_connect @@ -59,7 +59,7 @@ ATTRIBUTE_SENSORS = ( async def async_setup_entry( hass: HomeAssistant, _config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeMo sensors.""" diff --git a/homeassistant/components/wemo/switch.py b/homeassistant/components/wemo/switch.py index 3f7bb08b704..7b87b3147d0 100644 --- a/homeassistant/components/wemo/switch.py +++ b/homeassistant/components/wemo/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON, STATE_STANDBY, STATE_UNKNOWN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import async_wemo_dispatcher_connect from .coordinator import DeviceCoordinator @@ -36,7 +36,7 @@ MAKER_SWITCH_TOGGLE = "toggle" async def async_setup_entry( hass: HomeAssistant, _config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WeMo switches.""" diff --git a/homeassistant/components/whirlpool/climate.py b/homeassistant/components/whirlpool/climate.py index 943c5d1c956..6baf738e54e 100644 --- a/homeassistant/components/whirlpool/climate.py +++ b/homeassistant/components/whirlpool/climate.py @@ -28,7 +28,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import generate_entity_id -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WhirlpoolConfigEntry from .const import DOMAIN @@ -70,7 +70,7 @@ SUPPORTED_TARGET_TEMPERATURE_STEP = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: WhirlpoolConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry.""" whirlpool_data = config_entry.runtime_data diff --git a/homeassistant/components/whirlpool/sensor.py b/homeassistant/components/whirlpool/sensor.py index 9180164c272..f4811feb2c9 100644 --- a/homeassistant/components/whirlpool/sensor.py +++ b/homeassistant/components/whirlpool/sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.sensor import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow @@ -132,7 +132,7 @@ SENSOR_TIMER: tuple[SensorEntityDescription] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: WhirlpoolConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Config flow entry for Whrilpool Laundry.""" entities: list = [] diff --git a/homeassistant/components/whois/sensor.py b/homeassistant/components/whois/sensor.py index fe193b16eea..8098e052575 100644 --- a/homeassistant/components/whois/sensor.py +++ b/homeassistant/components/whois/sensor.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DOMAIN, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -127,7 +127,7 @@ SENSORS: tuple[WhoisSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the platform from config_entry.""" coordinator: DataUpdateCoordinator[Domain | None] = hass.data[DOMAIN][ diff --git a/homeassistant/components/wiffi/binary_sensor.py b/homeassistant/components/wiffi/binary_sensor.py index b7431b2555c..93fdb7cce1c 100644 --- a/homeassistant/components/wiffi/binary_sensor.py +++ b/homeassistant/components/wiffi/binary_sensor.py @@ -4,7 +4,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CREATE_ENTITY_SIGNAL from .entity import WiffiEntity @@ -13,7 +13,7 @@ from .entity import WiffiEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform for a new integration. diff --git a/homeassistant/components/wiffi/sensor.py b/homeassistant/components/wiffi/sensor.py index 699a760685a..9afcc719c9b 100644 --- a/homeassistant/components/wiffi/sensor.py +++ b/homeassistant/components/wiffi/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import DEGREE, LIGHT_LUX, UnitOfPressure, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CREATE_ENTITY_SIGNAL from .entity import WiffiEntity @@ -41,7 +41,7 @@ UOM_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up platform for a new integration. diff --git a/homeassistant/components/wilight/cover.py b/homeassistant/components/wilight/cover.py index 8a5cb45d909..2e9b92e7a21 100644 --- a/homeassistant/components/wilight/cover.py +++ b/homeassistant/components/wilight/cover.py @@ -18,7 +18,7 @@ from pywilight.const import ( from homeassistant.components.cover import ATTR_POSITION, CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WiLightDevice @@ -26,7 +26,9 @@ from .parent_device import WiLightParent async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WiLight covers from a config entry.""" parent: WiLightParent = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wilight/fan.py b/homeassistant/components/wilight/fan.py index a14198e3b5d..6a22da5879e 100644 --- a/homeassistant/components/wilight/fan.py +++ b/homeassistant/components/wilight/fan.py @@ -19,7 +19,7 @@ from pywilight.wilight_device import PyWiLightDevice from homeassistant.components.fan import DIRECTION_FORWARD, FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, @@ -33,7 +33,9 @@ ORDERED_NAMED_FAN_SPEEDS = [WL_SPEED_LOW, WL_SPEED_MEDIUM, WL_SPEED_HIGH] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WiLight lights from a config entry.""" parent: WiLightParent = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wilight/light.py b/homeassistant/components/wilight/light.py index fbe2499798d..7df0eb1a4c6 100644 --- a/homeassistant/components/wilight/light.py +++ b/homeassistant/components/wilight/light.py @@ -15,7 +15,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WiLightDevice @@ -41,7 +41,9 @@ def entities_from_discovered_wilight(api_device: PyWiLightDevice) -> list[LightE async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WiLight lights from a config entry.""" parent: WiLightParent = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/wilight/switch.py b/homeassistant/components/wilight/switch.py index f2a1ce8b0c5..148ea65dd94 100644 --- a/homeassistant/components/wilight/switch.py +++ b/homeassistant/components/wilight/switch.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WiLightDevice @@ -75,7 +75,9 @@ def entities_from_discovered_wilight(api_device: PyWiLightDevice) -> tuple[Any]: async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WiLight switches from a config entry.""" parent: WiLightParent = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/withings/__init__.py b/homeassistant/components/withings/__init__.py index 59c3ed8433f..1392b72f16b 100644 --- a/homeassistant/components/withings/__init__.py +++ b/homeassistant/components/withings/__init__.py @@ -120,13 +120,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: WithingsConfigEntry) -> client.refresh_token_function = _refresh_token withings_data = WithingsData( client=client, - measurement_coordinator=WithingsMeasurementDataUpdateCoordinator(hass, client), - sleep_coordinator=WithingsSleepDataUpdateCoordinator(hass, client), - bed_presence_coordinator=WithingsBedPresenceDataUpdateCoordinator(hass, client), - goals_coordinator=WithingsGoalsDataUpdateCoordinator(hass, client), - activity_coordinator=WithingsActivityDataUpdateCoordinator(hass, client), - workout_coordinator=WithingsWorkoutDataUpdateCoordinator(hass, client), - device_coordinator=WithingsDeviceDataUpdateCoordinator(hass, client), + measurement_coordinator=WithingsMeasurementDataUpdateCoordinator( + hass, entry, client + ), + sleep_coordinator=WithingsSleepDataUpdateCoordinator(hass, entry, client), + bed_presence_coordinator=WithingsBedPresenceDataUpdateCoordinator( + hass, entry, client + ), + goals_coordinator=WithingsGoalsDataUpdateCoordinator(hass, entry, client), + activity_coordinator=WithingsActivityDataUpdateCoordinator(hass, entry, client), + workout_coordinator=WithingsWorkoutDataUpdateCoordinator(hass, entry, client), + device_coordinator=WithingsDeviceDataUpdateCoordinator(hass, entry, client), ) for coordinator in withings_data.coordinators: diff --git a/homeassistant/components/withings/binary_sensor.py b/homeassistant/components/withings/binary_sensor.py index 856aeeffc5c..457bbe59bcc 100644 --- a/homeassistant/components/withings/binary_sensor.py +++ b/homeassistant/components/withings/binary_sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WithingsConfigEntry from .const import DOMAIN @@ -22,7 +22,7 @@ from .entity import WithingsEntity async def async_setup_entry( hass: HomeAssistant, entry: WithingsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" coordinator = entry.runtime_data.bed_presence_coordinator diff --git a/homeassistant/components/withings/calendar.py b/homeassistant/components/withings/calendar.py index ac867fbfdca..8dcad9d73ba 100644 --- a/homeassistant/components/withings/calendar.py +++ b/homeassistant/components/withings/calendar.py @@ -11,7 +11,7 @@ from homeassistant.components.calendar import CalendarEntity, CalendarEvent from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, WithingsConfigEntry from .coordinator import WithingsWorkoutDataUpdateCoordinator @@ -21,7 +21,7 @@ from .entity import WithingsEntity async def async_setup_entry( hass: HomeAssistant, entry: WithingsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the calendar platform for entity.""" ent_reg = er.async_get(hass) diff --git a/homeassistant/components/withings/coordinator.py b/homeassistant/components/withings/coordinator.py index 79419ae23ff..13789816d85 100644 --- a/homeassistant/components/withings/coordinator.py +++ b/homeassistant/components/withings/coordinator.py @@ -44,11 +44,17 @@ class WithingsDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): webhooks_connected: bool = False coordinator_name: str = "" - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" super().__init__( hass, LOGGER, + config_entry=config_entry, name="", update_interval=self._default_update_interval, ) @@ -95,9 +101,14 @@ class WithingsMeasurementDataUpdateCoordinator( coordinator_name: str = "measurements" - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" - super().__init__(hass, client) + super().__init__(hass, config_entry, client) self.notification_categories = { NotificationCategory.WEIGHT, NotificationCategory.PRESSURE, @@ -133,9 +144,14 @@ class WithingsSleepDataUpdateCoordinator( coordinator_name: str = "sleep" - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" - super().__init__(hass, client) + super().__init__(hass, config_entry, client) self.notification_categories = { NotificationCategory.SLEEP, } @@ -184,9 +200,14 @@ class WithingsBedPresenceDataUpdateCoordinator(WithingsDataUpdateCoordinator[Non in_bed: bool | None = None _default_update_interval = None - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" - super().__init__(hass, client) + super().__init__(hass, config_entry, client) self.notification_categories = { NotificationCategory.IN_BED, NotificationCategory.OUT_BED, @@ -226,9 +247,14 @@ class WithingsActivityDataUpdateCoordinator( coordinator_name: str = "activity" _previous_data: Activity | None = None - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" - super().__init__(hass, client) + super().__init__(hass, config_entry, client) self.notification_categories = { NotificationCategory.ACTIVITY, } @@ -265,9 +291,14 @@ class WithingsWorkoutDataUpdateCoordinator( coordinator_name: str = "workout" _previous_data: Workout | None = None - def __init__(self, hass: HomeAssistant, client: WithingsClient) -> None: + def __init__( + self, + hass: HomeAssistant, + config_entry: WithingsConfigEntry, + client: WithingsClient, + ) -> None: """Initialize the Withings data coordinator.""" - super().__init__(hass, client) + super().__init__(hass, config_entry, client) self.notification_categories = { NotificationCategory.ACTIVITY, } diff --git a/homeassistant/components/withings/sensor.py b/homeassistant/components/withings/sensor.py index 1005b5995a5..96cb433deba 100644 --- a/homeassistant/components/withings/sensor.py +++ b/homeassistant/components/withings/sensor.py @@ -36,7 +36,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util @@ -683,7 +683,7 @@ def get_current_goals(goals: Goals) -> set[str]: async def async_setup_entry( hass: HomeAssistant, entry: WithingsConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor config entry.""" ent_reg = er.async_get(hass) diff --git a/homeassistant/components/wiz/binary_sensor.py b/homeassistant/components/wiz/binary_sensor.py index 3411ee200b9..385e6827d77 100644 --- a/homeassistant/components/wiz/binary_sensor.py +++ b/homeassistant/components/wiz/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WizConfigEntry from .const import DOMAIN, SIGNAL_WIZ_PIR @@ -27,7 +27,7 @@ OCCUPANCY_UNIQUE_ID = "{}_occupancy" async def async_setup_entry( hass: HomeAssistant, entry: WizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WiZ binary sensor platform.""" mac = entry.runtime_data.bulb.mac diff --git a/homeassistant/components/wiz/light.py b/homeassistant/components/wiz/light.py index 9ef4cd57b3d..e38d518f6bc 100644 --- a/homeassistant/components/wiz/light.py +++ b/homeassistant/components/wiz/light.py @@ -20,7 +20,7 @@ from homeassistant.components.light import ( filter_supported_color_modes, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WizConfigEntry from .entity import WizToggleEntity @@ -57,7 +57,7 @@ def _async_pilot_builder(**kwargs: Any) -> PilotBuilder: async def async_setup_entry( hass: HomeAssistant, entry: WizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WiZ Platform from config_flow.""" if entry.runtime_data.bulb.bulbtype.bulb_type != BulbClass.SOCKET: diff --git a/homeassistant/components/wiz/number.py b/homeassistant/components/wiz/number.py index 0591e854d7d..0c8ee3f2bf4 100644 --- a/homeassistant/components/wiz/number.py +++ b/homeassistant/components/wiz/number.py @@ -15,7 +15,7 @@ from homeassistant.components.number import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WizConfigEntry from .entity import WizEntity @@ -68,7 +68,7 @@ NUMBERS: tuple[WizNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: WizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the wiz speed number.""" async_add_entities( diff --git a/homeassistant/components/wiz/sensor.py b/homeassistant/components/wiz/sensor.py index eb77686a5cf..217dae9e8fb 100644 --- a/homeassistant/components/wiz/sensor.py +++ b/homeassistant/components/wiz/sensor.py @@ -14,7 +14,7 @@ from homeassistant.const import ( UnitOfPower, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WizConfigEntry from .entity import WizEntity @@ -45,7 +45,7 @@ POWER_SENSORS: tuple[SensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: WizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the wiz sensor.""" entities = [ diff --git a/homeassistant/components/wiz/switch.py b/homeassistant/components/wiz/switch.py index 4c089d2d6d2..a57834bc18d 100644 --- a/homeassistant/components/wiz/switch.py +++ b/homeassistant/components/wiz/switch.py @@ -9,7 +9,7 @@ from pywizlight.bulblibrary import BulbClass from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WizConfigEntry from .entity import WizToggleEntity @@ -19,7 +19,7 @@ from .models import WizData async def async_setup_entry( hass: HomeAssistant, entry: WizConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WiZ switch platform.""" if entry.runtime_data.bulb.bulbtype.bulb_type == BulbClass.SOCKET: diff --git a/homeassistant/components/wled/button.py b/homeassistant/components/wled/button.py index 74799b4dcc4..119b2dc9b9f 100644 --- a/homeassistant/components/wled/button.py +++ b/homeassistant/components/wled/button.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.button import ButtonDeviceClass, ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLEDConfigEntry from .coordinator import WLEDDataUpdateCoordinator @@ -16,7 +16,7 @@ from .helpers import wled_exception_handler async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED button based on a config entry.""" async_add_entities([WLEDRestartButton(entry.runtime_data)]) diff --git a/homeassistant/components/wled/light.py b/homeassistant/components/wled/light.py index b4edf10dc58..5e2ff117580 100644 --- a/homeassistant/components/wled/light.py +++ b/homeassistant/components/wled/light.py @@ -17,7 +17,7 @@ from homeassistant.components.light import ( LightEntityFeature, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLEDConfigEntry from .const import ( @@ -39,7 +39,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED light based on a config entry.""" coordinator = entry.runtime_data @@ -284,7 +284,7 @@ class WLEDSegmentLight(WLEDEntity, LightEntity): def async_update_segments( coordinator: WLEDDataUpdateCoordinator, current_ids: set[int], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Update segments.""" segment_ids = { diff --git a/homeassistant/components/wled/number.py b/homeassistant/components/wled/number.py index 225d783bfdb..e4ff184fd4b 100644 --- a/homeassistant/components/wled/number.py +++ b/homeassistant/components/wled/number.py @@ -11,7 +11,7 @@ from wled import Segment from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLEDConfigEntry from .const import ATTR_INTENSITY, ATTR_SPEED @@ -25,7 +25,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED number based on a config entry.""" coordinator = entry.runtime_data @@ -130,7 +130,7 @@ class WLEDNumber(WLEDEntity, NumberEntity): def async_update_segments( coordinator: WLEDDataUpdateCoordinator, current_ids: set[int], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Update segments.""" segment_ids = { diff --git a/homeassistant/components/wled/select.py b/homeassistant/components/wled/select.py index a645b04573c..e340c323151 100644 --- a/homeassistant/components/wled/select.py +++ b/homeassistant/components/wled/select.py @@ -9,7 +9,7 @@ from wled import LiveDataOverride from homeassistant.components.select import SelectEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLEDConfigEntry from .coordinator import WLEDDataUpdateCoordinator @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED select based on a config entry.""" coordinator = entry.runtime_data @@ -191,7 +191,7 @@ class WLEDPaletteSelect(WLEDEntity, SelectEntity): def async_update_segments( coordinator: WLEDDataUpdateCoordinator, current_ids: set[int], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Update segments.""" segment_ids = { diff --git a/homeassistant/components/wled/sensor.py b/homeassistant/components/wled/sensor.py index 4f97c367612..06f96782019 100644 --- a/homeassistant/components/wled/sensor.py +++ b/homeassistant/components/wled/sensor.py @@ -22,7 +22,7 @@ from homeassistant.const import ( UnitOfInformation, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util.dt import utcnow @@ -128,7 +128,7 @@ SENSORS: tuple[WLEDSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED sensor based on a config entry.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/wled/switch.py b/homeassistant/components/wled/switch.py index 643834dcdec..8ed6ed56114 100644 --- a/homeassistant/components/wled/switch.py +++ b/homeassistant/components/wled/switch.py @@ -8,7 +8,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLEDConfigEntry from .const import ATTR_DURATION, ATTR_TARGET_BRIGHTNESS, ATTR_UDP_PORT @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED switch based on a config entry.""" coordinator = entry.runtime_data @@ -195,7 +195,7 @@ class WLEDReverseSwitch(WLEDEntity, SwitchEntity): def async_update_segments( coordinator: WLEDDataUpdateCoordinator, current_ids: set[int], - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Update segments.""" segment_ids = { diff --git a/homeassistant/components/wled/update.py b/homeassistant/components/wled/update.py index 384b394ac50..ccf72425b77 100644 --- a/homeassistant/components/wled/update.py +++ b/homeassistant/components/wled/update.py @@ -10,7 +10,7 @@ from homeassistant.components.update import ( UpdateEntityFeature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WLED_KEY, WLEDConfigEntry from .coordinator import WLEDDataUpdateCoordinator, WLEDReleasesDataUpdateCoordinator @@ -21,7 +21,7 @@ from .helpers import wled_exception_handler async def async_setup_entry( hass: HomeAssistant, entry: WLEDConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up WLED update based on a config entry.""" async_add_entities([WLEDUpdateEntity(entry.runtime_data, hass.data[WLED_KEY])]) diff --git a/homeassistant/components/wmspro/cover.py b/homeassistant/components/wmspro/cover.py index a36b34642b7..715add3023f 100644 --- a/homeassistant/components/wmspro/cover.py +++ b/homeassistant/components/wmspro/cover.py @@ -12,7 +12,7 @@ from wmspro.const import ( from homeassistant.components.cover import ATTR_POSITION, CoverDeviceClass, CoverEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WebControlProConfigEntry from .entity import WebControlProGenericEntity @@ -24,7 +24,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: WebControlProConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WMS based covers from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/wmspro/light.py b/homeassistant/components/wmspro/light.py index 9242982bcf9..d181beb1eaa 100644 --- a/homeassistant/components/wmspro/light.py +++ b/homeassistant/components/wmspro/light.py @@ -9,7 +9,7 @@ from wmspro.const import WMS_WebControl_pro_API_actionDescription from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.color import brightness_to_value, value_to_brightness from . import WebControlProConfigEntry @@ -23,7 +23,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: WebControlProConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WMS based lights from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/wmspro/scene.py b/homeassistant/components/wmspro/scene.py index de18106b7f0..7edd7a2b186 100644 --- a/homeassistant/components/wmspro/scene.py +++ b/homeassistant/components/wmspro/scene.py @@ -9,7 +9,7 @@ from wmspro.scene import Scene as WMS_Scene from homeassistant.components.scene import Scene from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import WebControlProConfigEntry from .const import ATTRIBUTION, DOMAIN, MANUFACTURER @@ -18,7 +18,7 @@ from .const import ATTRIBUTION, DOMAIN, MANUFACTURER async def async_setup_entry( hass: HomeAssistant, config_entry: WebControlProConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WMS based scenes from a config entry.""" hub = config_entry.runtime_data diff --git a/homeassistant/components/wolflink/sensor.py b/homeassistant/components/wolflink/sensor.py index 1f6e6c42464..cf6d712dd0d 100644 --- a/homeassistant/components/wolflink/sensor.py +++ b/homeassistant/components/wolflink/sensor.py @@ -17,7 +17,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfPressure, UnitOfTemperature, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import COORDINATOR, DEVICE_ID, DOMAIN, MANUFACTURER, PARAMETERS, STATES @@ -26,7 +26,7 @@ from .const import COORDINATOR, DEVICE_ID, DOMAIN, MANUFACTURER, PARAMETERS, STA async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up all entries for Wolf Platform.""" diff --git a/homeassistant/components/workday/binary_sensor.py b/homeassistant/components/workday/binary_sensor.py index 3aad6d805d0..6b878db8159 100644 --- a/homeassistant/components/workday/binary_sensor.py +++ b/homeassistant/components/workday/binary_sensor.py @@ -26,7 +26,7 @@ from homeassistant.core import ( from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) from homeassistant.helpers.event import async_track_point_in_utc_time @@ -113,7 +113,9 @@ def _get_obj_holidays( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Workday sensor.""" add_holidays: list[str] = entry.options[CONF_ADD_HOLIDAYS] diff --git a/homeassistant/components/worldclock/sensor.py b/homeassistant/components/worldclock/sensor.py index 88e5a317cdd..9b52993919c 100644 --- a/homeassistant/components/worldclock/sensor.py +++ b/homeassistant/components/worldclock/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME, CONF_TIME_ZONE from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import CONF_TIME_FORMAT, DOMAIN @@ -18,7 +18,7 @@ from .const import CONF_TIME_FORMAT, DOMAIN async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the World clock sensor entry.""" time_zone = await dt_util.async_get_time_zone(entry.options[CONF_TIME_ZONE]) diff --git a/homeassistant/components/ws66i/media_player.py b/homeassistant/components/ws66i/media_player.py index a2cd7ba471b..fb8ba5ae996 100644 --- a/homeassistant/components/ws66i/media_player.py +++ b/homeassistant/components/ws66i/media_player.py @@ -10,7 +10,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MAX_VOL @@ -23,7 +23,7 @@ PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the WS66i 6-zone amplifier platform from a config entry.""" ws66i_data: Ws66iData = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/assist_satellite.py b/homeassistant/components/wyoming/assist_satellite.py index 615084bcbf3..5440b2bebeb 100644 --- a/homeassistant/components/wyoming/assist_satellite.py +++ b/homeassistant/components/wyoming/assist_satellite.py @@ -24,18 +24,20 @@ from wyoming.tts import Synthesize, SynthesizeVoice from wyoming.vad import VoiceStarted, VoiceStopped from wyoming.wake import Detect, Detection -from homeassistant.components import assist_pipeline, intent, tts +from homeassistant.components import assist_pipeline, ffmpeg, intent, tts from homeassistant.components.assist_pipeline import PipelineEvent from homeassistant.components.assist_satellite import ( + AssistSatelliteAnnouncement, AssistSatelliteConfiguration, AssistSatelliteEntity, AssistSatelliteEntityDescription, + AssistSatelliteEntityFeature, ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN +from .const import DOMAIN, SAMPLE_CHANNELS, SAMPLE_WIDTH from .data import WyomingService from .devices import SatelliteDevice from .entity import WyomingSatelliteEntity @@ -49,6 +51,8 @@ _RESTART_SECONDS: Final = 3 _PING_TIMEOUT: Final = 5 _PING_SEND_DELAY: Final = 2 _PIPELINE_FINISH_TIMEOUT: Final = 1 +_TTS_SAMPLE_RATE: Final = 22050 +_ANNOUNCE_CHUNK_BYTES: Final = 2048 # 1024 samples # Wyoming stage -> Assist stage _STAGES: dict[PipelineStage, assist_pipeline.PipelineStage] = { @@ -62,7 +66,7 @@ _STAGES: dict[PipelineStage, assist_pipeline.PipelineStage] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming Assist satellite entity.""" domain_data: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] @@ -83,6 +87,7 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity): entity_description = AssistSatelliteEntityDescription(key="assist_satellite") _attr_translation_key = "assist_satellite" _attr_name = None + _attr_supported_features = AssistSatelliteEntityFeature.ANNOUNCE def __init__( self, @@ -116,6 +121,10 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity): self.device.set_pipeline_listener(self._pipeline_changed) self.device.set_audio_settings_listener(self._audio_settings_changed) + # For announcements + self._ffmpeg_manager: ffmpeg.FFmpegManager | None = None + self._played_event_received: asyncio.Event | None = None + @property def pipeline_entity_id(self) -> str | None: """Return the entity ID of the pipeline to use for the next conversation.""" @@ -131,9 +140,9 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity): """Options passed for text-to-speech.""" return { tts.ATTR_PREFERRED_FORMAT: "wav", - tts.ATTR_PREFERRED_SAMPLE_RATE: 16000, - tts.ATTR_PREFERRED_SAMPLE_CHANNELS: 1, - tts.ATTR_PREFERRED_SAMPLE_BYTES: 2, + tts.ATTR_PREFERRED_SAMPLE_RATE: _TTS_SAMPLE_RATE, + tts.ATTR_PREFERRED_SAMPLE_CHANNELS: SAMPLE_CHANNELS, + tts.ATTR_PREFERRED_SAMPLE_BYTES: SAMPLE_WIDTH, } async def async_added_to_hass(self) -> None: @@ -244,6 +253,76 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity): ) ) + async def async_announce(self, announcement: AssistSatelliteAnnouncement) -> None: + """Announce media on the satellite. + + Should block until the announcement is done playing. + """ + assert self._client is not None + + if self._ffmpeg_manager is None: + self._ffmpeg_manager = ffmpeg.get_ffmpeg_manager(self.hass) + + if self._played_event_received is None: + self._played_event_received = asyncio.Event() + + self._played_event_received.clear() + await self._client.write_event( + AudioStart( + rate=_TTS_SAMPLE_RATE, + width=SAMPLE_WIDTH, + channels=SAMPLE_CHANNELS, + timestamp=0, + ).event() + ) + + timestamp = 0 + try: + # Use ffmpeg to convert to raw PCM audio with the appropriate format + proc = await asyncio.create_subprocess_exec( + self._ffmpeg_manager.binary, + "-i", + announcement.media_id, + "-f", + "s16le", + "-ac", + str(SAMPLE_CHANNELS), + "-ar", + str(_TTS_SAMPLE_RATE), + "-nostats", + "pipe:", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + close_fds=False, # use posix_spawn in CPython < 3.13 + ) + assert proc.stdout is not None + while True: + chunk_bytes = await proc.stdout.read(_ANNOUNCE_CHUNK_BYTES) + if not chunk_bytes: + break + + chunk = AudioChunk( + rate=_TTS_SAMPLE_RATE, + width=SAMPLE_WIDTH, + channels=SAMPLE_CHANNELS, + audio=chunk_bytes, + timestamp=timestamp, + ) + await self._client.write_event(chunk.event()) + + timestamp += chunk.milliseconds + finally: + await self._client.write_event(AudioStop().event()) + if timestamp > 0: + # Wait the length of the audio or until we receive a played event + audio_seconds = timestamp / 1000 + try: + async with asyncio.timeout(audio_seconds + 0.5): + await self._played_event_received.wait() + except TimeoutError: + # Older satellite clients will wait longer than necessary + _LOGGER.debug("Did not receive played event for announcement") + # ------------------------------------------------------------------------- def start_satellite(self) -> None: @@ -511,6 +590,9 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity): elif Played.is_type(client_event.type): # TTS response has finished playing on satellite self.tts_response_finished() + + if self._played_event_received is not None: + self._played_event_received.set() else: _LOGGER.debug("Unexpected event from satellite: %s", client_event) diff --git a/homeassistant/components/wyoming/binary_sensor.py b/homeassistant/components/wyoming/binary_sensor.py index 24ee073ec4d..a3652e7f70f 100644 --- a/homeassistant/components/wyoming/binary_sensor.py +++ b/homeassistant/components/wyoming/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WyomingSatelliteEntity @@ -22,7 +22,7 @@ if TYPE_CHECKING: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up binary sensor entities.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/conversation.py b/homeassistant/components/wyoming/conversation.py index 988d47925ac..5760d04bfc2 100644 --- a/homeassistant/components/wyoming/conversation.py +++ b/homeassistant/components/wyoming/conversation.py @@ -12,7 +12,7 @@ from homeassistant.components import conversation from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import intent -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import ulid as ulid_util from .const import DOMAIN @@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming conversation.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/manifest.json b/homeassistant/components/wyoming/manifest.json index b837d2a9e76..d75b70dffa8 100644 --- a/homeassistant/components/wyoming/manifest.json +++ b/homeassistant/components/wyoming/manifest.json @@ -7,7 +7,8 @@ "assist_satellite", "assist_pipeline", "intent", - "conversation" + "conversation", + "ffmpeg" ], "documentation": "https://www.home-assistant.io/integrations/wyoming", "integration_type": "service", diff --git a/homeassistant/components/wyoming/number.py b/homeassistant/components/wyoming/number.py index d9a58cc3333..96ec5877545 100644 --- a/homeassistant/components/wyoming/number.py +++ b/homeassistant/components/wyoming/number.py @@ -8,7 +8,7 @@ from homeassistant.components.number import NumberEntityDescription, RestoreNumb from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WyomingSatelliteEntity @@ -24,7 +24,7 @@ _MAX_VOLUME_MULTIPLIER: Final = 10.0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming number entities.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/select.py b/homeassistant/components/wyoming/select.py index bbcaab81710..2af0438e35f 100644 --- a/homeassistant/components/wyoming/select.py +++ b/homeassistant/components/wyoming/select.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers import restore_state -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .devices import SatelliteDevice @@ -36,7 +36,7 @@ _DEFAULT_NOISE_SUPPRESSION_LEVEL: Final = "off" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming select entities.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/stt.py b/homeassistant/components/wyoming/stt.py index a28e5fdb527..2851004a854 100644 --- a/homeassistant/components/wyoming/stt.py +++ b/homeassistant/components/wyoming/stt.py @@ -10,7 +10,7 @@ from wyoming.client import AsyncTcpClient from homeassistant.components import stt from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, SAMPLE_CHANNELS, SAMPLE_RATE, SAMPLE_WIDTH from .data import WyomingService @@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming speech-to-text.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/switch.py b/homeassistant/components/wyoming/switch.py index 308429331c3..9eb91d5ef39 100644 --- a/homeassistant/components/wyoming/switch.py +++ b/homeassistant/components/wyoming/switch.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers import restore_state -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .entity import WyomingSatelliteEntity @@ -21,7 +21,7 @@ if TYPE_CHECKING: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up VoIP switch entities.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/tts.py b/homeassistant/components/wyoming/tts.py index 65ce4d942f1..79e431fee98 100644 --- a/homeassistant/components/wyoming/tts.py +++ b/homeassistant/components/wyoming/tts.py @@ -12,7 +12,7 @@ from wyoming.tts import Synthesize, SynthesizeVoice from homeassistant.components import tts from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_SPEAKER, DOMAIN from .data import WyomingService @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming speech-to-text.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/wyoming/wake_word.py b/homeassistant/components/wyoming/wake_word.py index 64dfd60c068..2a21b7303e5 100644 --- a/homeassistant/components/wyoming/wake_word.py +++ b/homeassistant/components/wyoming/wake_word.py @@ -11,7 +11,7 @@ from wyoming.wake import Detect, Detection from homeassistant.components import wake_word from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .data import WyomingService, load_wyoming_info @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Wyoming wake-word-detection.""" item: DomainDataItem = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/xbox/binary_sensor.py b/homeassistant/components/xbox/binary_sensor.py index af95834425a..5339c4d7a8e 100644 --- a/homeassistant/components/xbox/binary_sensor.py +++ b/homeassistant/components/xbox/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import XboxUpdateCoordinator @@ -18,7 +18,9 @@ PRESENCE_ATTRIBUTES = ["online", "in_party", "in_game", "in_multiplayer"] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Xbox Live friends.""" coordinator: XboxUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/xbox/media_player.py b/homeassistant/components/xbox/media_player.py index 7298c7e2da3..6464b2417cc 100644 --- a/homeassistant/components/xbox/media_player.py +++ b/homeassistant/components/xbox/media_player.py @@ -24,7 +24,7 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .browse_media import build_item_response @@ -56,7 +56,9 @@ XBOX_STATE_MAP: dict[PlaybackState | PowerState, MediaPlayerState | None] = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Xbox media_player from a config entry.""" client: XboxLiveClient = hass.data[DOMAIN][entry.entry_id]["client"] diff --git a/homeassistant/components/xbox/remote.py b/homeassistant/components/xbox/remote.py index 1b4ffdf35cc..4e5893ddb13 100644 --- a/homeassistant/components/xbox/remote.py +++ b/homeassistant/components/xbox/remote.py @@ -24,7 +24,7 @@ from homeassistant.components.remote import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN @@ -32,7 +32,9 @@ from .coordinator import ConsoleData, XboxUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Xbox media_player from a config entry.""" client: XboxLiveClient = hass.data[DOMAIN][entry.entry_id]["client"] diff --git a/homeassistant/components/xbox/sensor.py b/homeassistant/components/xbox/sensor.py index f269e0a5bb9..da53557a2d3 100644 --- a/homeassistant/components/xbox/sensor.py +++ b/homeassistant/components/xbox/sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import XboxUpdateCoordinator @@ -20,7 +20,7 @@ SENSOR_ATTRIBUTES = ["status", "gamer_score", "account_tier", "gold_tenure"] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Xbox Live friends.""" coordinator: XboxUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id][ diff --git a/homeassistant/components/xiaomi_aqara/binary_sensor.py b/homeassistant/components/xiaomi_aqara/binary_sensor.py index ad91dda2173..47cc823ad7f 100644 --- a/homeassistant/components/xiaomi_aqara/binary_sensor.py +++ b/homeassistant/components/xiaomi_aqara/binary_sensor.py @@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import RestoreEntity @@ -32,7 +32,7 @@ ATTR_DENSITY = "Density" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" entities: list[XiaomiBinarySensor] = [] diff --git a/homeassistant/components/xiaomi_aqara/cover.py b/homeassistant/components/xiaomi_aqara/cover.py index e073ef6b683..82d5129ac5e 100644 --- a/homeassistant/components/xiaomi_aqara/cover.py +++ b/homeassistant/components/xiaomi_aqara/cover.py @@ -5,7 +5,7 @@ from typing import Any from homeassistant.components.cover import ATTR_POSITION, CoverEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, GATEWAYS_KEY from .entity import XiaomiDevice @@ -19,7 +19,7 @@ DATA_KEY_PROTO_V2 = "curtain_status" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" entities = [] diff --git a/homeassistant/components/xiaomi_aqara/light.py b/homeassistant/components/xiaomi_aqara/light.py index 11ce7a0107b..ef1f06695f9 100644 --- a/homeassistant/components/xiaomi_aqara/light.py +++ b/homeassistant/components/xiaomi_aqara/light.py @@ -13,7 +13,7 @@ from homeassistant.components.light import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import DOMAIN, GATEWAYS_KEY @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" entities = [] diff --git a/homeassistant/components/xiaomi_aqara/lock.py b/homeassistant/components/xiaomi_aqara/lock.py index 5e538f25699..b3f4e9f4caf 100644 --- a/homeassistant/components/xiaomi_aqara/lock.py +++ b/homeassistant/components/xiaomi_aqara/lock.py @@ -5,7 +5,7 @@ from __future__ import annotations from homeassistant.components.lock import LockEntity, LockState from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from .const import DOMAIN, GATEWAYS_KEY @@ -24,7 +24,7 @@ UNLOCK_MAINTAIN_TIME = 5 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" gateway = hass.data[DOMAIN][GATEWAYS_KEY][config_entry.entry_id] diff --git a/homeassistant/components/xiaomi_aqara/sensor.py b/homeassistant/components/xiaomi_aqara/sensor.py index 49358276a48..59ccee5a1a8 100644 --- a/homeassistant/components/xiaomi_aqara/sensor.py +++ b/homeassistant/components/xiaomi_aqara/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import BATTERY_MODELS, DOMAIN, GATEWAYS_KEY, POWER_MODELS from .entity import XiaomiDevice @@ -85,7 +85,7 @@ SENSOR_TYPES: dict[str, SensorEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" entities: list[XiaomiSensor | XiaomiBatterySensor] = [] diff --git a/homeassistant/components/xiaomi_aqara/switch.py b/homeassistant/components/xiaomi_aqara/switch.py index f66cf8c7603..7d3abf47bd1 100644 --- a/homeassistant/components/xiaomi_aqara/switch.py +++ b/homeassistant/components/xiaomi_aqara/switch.py @@ -6,7 +6,7 @@ from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, GATEWAYS_KEY from .entity import XiaomiDevice @@ -29,7 +29,7 @@ IN_USE = "inuse" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Perform the setup for Xiaomi devices.""" entities = [] diff --git a/homeassistant/components/xiaomi_ble/binary_sensor.py b/homeassistant/components/xiaomi_ble/binary_sensor.py index b853f83b967..8956e207253 100644 --- a/homeassistant/components/xiaomi_ble/binary_sensor.py +++ b/homeassistant/components/xiaomi_ble/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothProcessorEntity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import XiaomiPassiveBluetoothDataProcessor @@ -135,7 +135,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: XiaomiBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/xiaomi_ble/event.py b/homeassistant/components/xiaomi_ble/event.py index 7265bcd112c..c5f6e01e575 100644 --- a/homeassistant/components/xiaomi_ble/event.py +++ b/homeassistant/components/xiaomi_ble/event.py @@ -12,7 +12,7 @@ from homeassistant.components.event import ( from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import format_discovered_event_class, format_event_dispatcher_name from .const import ( @@ -183,7 +183,7 @@ class XiaomiEventEntity(EventEntity): async def async_setup_entry( hass: HomeAssistant, entry: XiaomiBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Xiaomi event.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/xiaomi_ble/sensor.py b/homeassistant/components/xiaomi_ble/sensor.py index ba8f64383ee..01f15ff09b8 100644 --- a/homeassistant/components/xiaomi_ble/sensor.py +++ b/homeassistant/components/xiaomi_ble/sensor.py @@ -31,7 +31,7 @@ from homeassistant.const import ( UnitOfTime, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info from .coordinator import XiaomiPassiveBluetoothDataProcessor @@ -208,7 +208,7 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, entry: XiaomiBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi BLE sensors.""" coordinator = entry.runtime_data diff --git a/homeassistant/components/xiaomi_miio/air_quality.py b/homeassistant/components/xiaomi_miio/air_quality.py index 199d9161353..1ce37c661a2 100644 --- a/homeassistant/components/xiaomi_miio/air_quality.py +++ b/homeassistant/components/xiaomi_miio/air_quality.py @@ -9,7 +9,7 @@ from homeassistant.components.air_quality import AirQualityEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_TOKEN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_FLOW_TYPE, @@ -242,7 +242,7 @@ DEVICE_MAP: dict[str, dict[str, Callable]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi Air Quality from a config entry.""" entities = [] diff --git a/homeassistant/components/xiaomi_miio/alarm_control_panel.py b/homeassistant/components/xiaomi_miio/alarm_control_panel.py index 9c06198bc7e..ecab5228f6e 100644 --- a/homeassistant/components/xiaomi_miio/alarm_control_panel.py +++ b/homeassistant/components/xiaomi_miio/alarm_control_panel.py @@ -15,7 +15,7 @@ from homeassistant.components.alarm_control_panel import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONF_GATEWAY, DOMAIN @@ -29,7 +29,7 @@ XIAOMI_STATE_ARMING_VALUE = "oning" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi Gateway Alarm from a config entry.""" entities = [] diff --git a/homeassistant/components/xiaomi_miio/binary_sensor.py b/homeassistant/components/xiaomi_miio/binary_sensor.py index a5ab7e56e6b..213886691f0 100644 --- a/homeassistant/components/xiaomi_miio/binary_sensor.py +++ b/homeassistant/components/xiaomi_miio/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE, CONF_MODEL, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import VacuumCoordinatorDataAttributes from .const import ( @@ -171,7 +171,7 @@ def _setup_vacuum_sensors(hass, config_entry, async_add_entities): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi sensor from a config entry.""" entities = [] diff --git a/homeassistant/components/xiaomi_miio/button.py b/homeassistant/components/xiaomi_miio/button.py index 9a64941f398..a5d1b4b69c6 100644 --- a/homeassistant/components/xiaomi_miio/button.py +++ b/homeassistant/components/xiaomi_miio/button.py @@ -14,7 +14,7 @@ from homeassistant.components.button import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_MODEL, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( DOMAIN, @@ -124,7 +124,7 @@ MODEL_TO_BUTTON_MAP: dict[str, tuple[str, ...]] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the button from a config entry.""" model = config_entry.data[CONF_MODEL] diff --git a/homeassistant/components/xiaomi_miio/fan.py b/homeassistant/components/xiaomi_miio/fan.py index 12ed9f7195b..31d5dd9de2c 100644 --- a/homeassistant/components/xiaomi_miio/fan.py +++ b/homeassistant/components/xiaomi_miio/fan.py @@ -34,7 +34,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ENTITY_ID, CONF_DEVICE, CONF_MODEL from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -205,7 +205,7 @@ FAN_DIRECTIONS_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Fan from a config entry.""" entities: list[FanEntity] = [] diff --git a/homeassistant/components/xiaomi_miio/humidifier.py b/homeassistant/components/xiaomi_miio/humidifier.py index 4701345756a..f19fbec5e78 100644 --- a/homeassistant/components/xiaomi_miio/humidifier.py +++ b/homeassistant/components/xiaomi_miio/humidifier.py @@ -23,7 +23,7 @@ from homeassistant.components.humidifier import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_MODE, CONF_DEVICE, CONF_MODEL from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import percentage_to_ranged_value from .const import ( @@ -71,7 +71,7 @@ AVAILABLE_MODES_OTHER = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Humidifier from a config entry.""" if config_entry.data[CONF_FLOW_TYPE] != CONF_DEVICE: diff --git a/homeassistant/components/xiaomi_miio/light.py b/homeassistant/components/xiaomi_miio/light.py index c1f778928d9..81f68306cbc 100644 --- a/homeassistant/components/xiaomi_miio/light.py +++ b/homeassistant/components/xiaomi_miio/light.py @@ -44,7 +44,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util, dt as dt_util from .const import ( @@ -132,7 +132,7 @@ SERVICE_TO_METHOD = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi light from a config entry.""" entities: list[LightEntity] = [] diff --git a/homeassistant/components/xiaomi_miio/number.py b/homeassistant/components/xiaomi_miio/number.py index a3c501aad3f..f30d4728275 100644 --- a/homeassistant/components/xiaomi_miio/number.py +++ b/homeassistant/components/xiaomi_miio/number.py @@ -23,7 +23,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( @@ -289,7 +289,7 @@ FAVORITE_LEVEL_VALUES = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Selectors from a config entry.""" entities = [] diff --git a/homeassistant/components/xiaomi_miio/select.py b/homeassistant/components/xiaomi_miio/select.py index 6729ce2e0f4..94a93fc1fae 100644 --- a/homeassistant/components/xiaomi_miio/select.py +++ b/homeassistant/components/xiaomi_miio/select.py @@ -32,7 +32,7 @@ from homeassistant.components.select import SelectEntity, SelectEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE, CONF_MODEL, EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_FLOW_TYPE, @@ -205,7 +205,7 @@ SELECTOR_TYPES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Selectors from a config entry.""" if config_entry.data[CONF_FLOW_TYPE] != CONF_DEVICE: diff --git a/homeassistant/components/xiaomi_miio/sensor.py b/homeassistant/components/xiaomi_miio/sensor.py index aafcba97487..6f623c46af8 100644 --- a/homeassistant/components/xiaomi_miio/sensor.py +++ b/homeassistant/components/xiaomi_miio/sensor.py @@ -45,7 +45,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from . import VacuumCoordinatorDataAttributes @@ -755,7 +755,7 @@ def _setup_vacuum_sensors(hass, config_entry, async_add_entities): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi sensor from a config entry.""" entities: list[SensorEntity] = [] diff --git a/homeassistant/components/xiaomi_miio/strings.json b/homeassistant/components/xiaomi_miio/strings.json index dd49ba502f0..75563b07559 100644 --- a/homeassistant/components/xiaomi_miio/strings.json +++ b/homeassistant/components/xiaomi_miio/strings.json @@ -509,7 +509,7 @@ }, "vacuum_remote_control_start": { "name": "Vacuum remote control start", - "description": "Starts remote control of the vacuum cleaner. You can then move it with `remote_control_move`, when done call `remote_control_stop`." + "description": "Starts remote control of the vacuum cleaner. You can then move it with the 'Vacuum remote control move' action, when done use 'Vacuum remote control stop'." }, "vacuum_remote_control_stop": { "name": "Vacuum remote control stop", @@ -517,7 +517,7 @@ }, "vacuum_remote_control_move": { "name": "Vacuum remote control move", - "description": "Remote controls the vacuum cleaner, make sure you first set it in remote control mode with `remote_control_start`.", + "description": "Remote controls the vacuum cleaner, make sure you first set it in remote control mode with the 'Vacuum remote control start' action.", "fields": { "velocity": { "name": "Velocity", diff --git a/homeassistant/components/xiaomi_miio/switch.py b/homeassistant/components/xiaomi_miio/switch.py index b4c4300dbe8..e4b94aebc20 100644 --- a/homeassistant/components/xiaomi_miio/switch.py +++ b/homeassistant/components/xiaomi_miio/switch.py @@ -30,7 +30,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( CONF_FLOW_TYPE, @@ -341,7 +341,7 @@ SWITCH_TYPES = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch from a config entry.""" model = config_entry.data[CONF_MODEL] diff --git a/homeassistant/components/xiaomi_miio/vacuum.py b/homeassistant/components/xiaomi_miio/vacuum.py index 532eb9581cd..1cbc79b89f3 100644 --- a/homeassistant/components/xiaomi_miio/vacuum.py +++ b/homeassistant/components/xiaomi_miio/vacuum.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util.dt import as_utc @@ -79,7 +79,7 @@ STATE_CODE_TO_STATE = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Xiaomi vacuum cleaner robot from a config entry.""" entities = [] diff --git a/homeassistant/components/yale/binary_sensor.py b/homeassistant/components/yale/binary_sensor.py index dbb00ad7d42..bb9acb16644 100644 --- a/homeassistant/components/yale/binary_sensor.py +++ b/homeassistant/components/yale/binary_sensor.py @@ -21,7 +21,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from . import YaleConfigEntry, YaleData @@ -92,7 +92,7 @@ SENSOR_TYPES_DOORBELL: tuple[YaleDoorbellBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale binary sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale/button.py b/homeassistant/components/yale/button.py index b04ad638f0c..005d477e4ca 100644 --- a/homeassistant/components/yale/button.py +++ b/homeassistant/components/yale/button.py @@ -2,7 +2,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .entity import YaleEntity @@ -11,7 +11,7 @@ from .entity import YaleEntity async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Yale lock wake buttons.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale/camera.py b/homeassistant/components/yale/camera.py index 217e8f5f6fd..acabba23b59 100644 --- a/homeassistant/components/yale/camera.py +++ b/homeassistant/components/yale/camera.py @@ -12,7 +12,7 @@ from yalexs.util import update_doorbell_image_from_activity from homeassistant.components.camera import Camera from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import aiohttp_client -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry, YaleData from .const import DEFAULT_NAME, DEFAULT_TIMEOUT @@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Yale cameras.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale/event.py b/homeassistant/components/yale/event.py index 935ba7376f8..0ea7694be6d 100644 --- a/homeassistant/components/yale/event.py +++ b/homeassistant/components/yale/event.py @@ -16,7 +16,7 @@ from homeassistant.components.event import ( EventEntityDescription, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry, YaleData from .entity import YaleDescriptionEntity @@ -59,7 +59,7 @@ TYPES_DOORBELL: tuple[YaleEventEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the yale event platform.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale/lock.py b/homeassistant/components/yale/lock.py index 7fdad118cde..079c1dcd3dd 100644 --- a/homeassistant/components/yale/lock.py +++ b/homeassistant/components/yale/lock.py @@ -14,7 +14,7 @@ from yalexs.util import get_latest_activity, update_lock_detail_from_activity from homeassistant.components.lock import ATTR_CHANGED_BY, LockEntity, LockEntityFeature from homeassistant.const import ATTR_BATTERY_LEVEL from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.util import dt as dt_util @@ -29,7 +29,7 @@ LOCK_JAMMED_ERR = 531 async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Yale locks.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale/sensor.py b/homeassistant/components/yale/sensor.py index bb3d4317277..91ecbea704d 100644 --- a/homeassistant/components/yale/sensor.py +++ b/homeassistant/components/yale/sensor.py @@ -25,7 +25,7 @@ from homeassistant.const import ( EntityCategory, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .const import ( @@ -82,7 +82,7 @@ SENSOR_TYPE_KEYPAD_BATTERY = YaleSensorEntityDescription[KeypadDetail]( async def async_setup_entry( hass: HomeAssistant, config_entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale sensors.""" data = config_entry.runtime_data diff --git a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py index 8244d96064a..b443ba016d6 100644 --- a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py +++ b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py @@ -17,7 +17,7 @@ from homeassistant.components.alarm_control_panel import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .const import DOMAIN, STATE_MAP, YALE_ALL_ERRORS @@ -26,7 +26,9 @@ from .entity import YaleAlarmEntity async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the alarm entry.""" diff --git a/homeassistant/components/yale_smart_alarm/binary_sensor.py b/homeassistant/components/yale_smart_alarm/binary_sensor.py index fa9584505e2..20fe3648eed 100644 --- a/homeassistant/components/yale_smart_alarm/binary_sensor.py +++ b/homeassistant/components/yale_smart_alarm/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .coordinator import YaleDataUpdateCoordinator @@ -44,7 +44,9 @@ SENSOR_TYPES = ( async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale binary sensor entry.""" diff --git a/homeassistant/components/yale_smart_alarm/button.py b/homeassistant/components/yale_smart_alarm/button.py index 0e53c814fd4..0875ab4514d 100644 --- a/homeassistant/components/yale_smart_alarm/button.py +++ b/homeassistant/components/yale_smart_alarm/button.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .const import DOMAIN, YALE_ALL_ERRORS @@ -25,7 +25,7 @@ BUTTON_TYPES = ( async def async_setup_entry( hass: HomeAssistant, entry: YaleConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the button from a config entry.""" diff --git a/homeassistant/components/yale_smart_alarm/lock.py b/homeassistant/components/yale_smart_alarm/lock.py index 7a93baf0827..f4fae531b67 100644 --- a/homeassistant/components/yale_smart_alarm/lock.py +++ b/homeassistant/components/yale_smart_alarm/lock.py @@ -10,7 +10,7 @@ from homeassistant.components.lock import LockEntity, LockState from homeassistant.const import ATTR_CODE from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .const import ( @@ -30,7 +30,9 @@ LOCK_STATE_MAP = { async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale lock entry.""" diff --git a/homeassistant/components/yale_smart_alarm/select.py b/homeassistant/components/yale_smart_alarm/select.py index 55b56dd8e54..0b443e762e6 100644 --- a/homeassistant/components/yale_smart_alarm/select.py +++ b/homeassistant/components/yale_smart_alarm/select.py @@ -6,7 +6,7 @@ from yalesmartalarmclient import YaleLock, YaleLockVolume from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .coordinator import YaleDataUpdateCoordinator @@ -16,7 +16,9 @@ VOLUME_OPTIONS = {value.name.lower(): str(value.value) for value in YaleLockVolu async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale select entry.""" diff --git a/homeassistant/components/yale_smart_alarm/sensor.py b/homeassistant/components/yale_smart_alarm/sensor.py index 50343f2e41f..14301d0c6b5 100644 --- a/homeassistant/components/yale_smart_alarm/sensor.py +++ b/homeassistant/components/yale_smart_alarm/sensor.py @@ -7,7 +7,7 @@ from typing import cast from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import YaleConfigEntry @@ -15,7 +15,9 @@ from .entity import YaleEntity async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale sensor entry.""" diff --git a/homeassistant/components/yale_smart_alarm/switch.py b/homeassistant/components/yale_smart_alarm/switch.py index e8c0817c2de..e4523a66802 100644 --- a/homeassistant/components/yale_smart_alarm/switch.py +++ b/homeassistant/components/yale_smart_alarm/switch.py @@ -8,7 +8,7 @@ from yalesmartalarmclient import YaleLock from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YaleConfigEntry from .coordinator import YaleDataUpdateCoordinator @@ -16,7 +16,9 @@ from .entity import YaleLockEntity async def async_setup_entry( - hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: YaleConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Yale switch entry.""" diff --git a/homeassistant/components/yalexs_ble/binary_sensor.py b/homeassistant/components/yalexs_ble/binary_sensor.py index 7cd142bb9ba..dc924486df2 100644 --- a/homeassistant/components/yalexs_ble/binary_sensor.py +++ b/homeassistant/components/yalexs_ble/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YALEXSBLEConfigEntry from .entity import YALEXSBLEEntity @@ -18,7 +18,7 @@ from .entity import YALEXSBLEEntity async def async_setup_entry( hass: HomeAssistant, entry: YALEXSBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YALE XS binary sensors.""" data = entry.runtime_data diff --git a/homeassistant/components/yalexs_ble/lock.py b/homeassistant/components/yalexs_ble/lock.py index 6eb32e3f78a..78b92ab9eb1 100644 --- a/homeassistant/components/yalexs_ble/lock.py +++ b/homeassistant/components/yalexs_ble/lock.py @@ -8,7 +8,7 @@ from yalexs_ble import ConnectionInfo, LockInfo, LockState, LockStatus from homeassistant.components.lock import LockEntity from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YALEXSBLEConfigEntry from .entity import YALEXSBLEEntity @@ -17,7 +17,7 @@ from .entity import YALEXSBLEEntity async def async_setup_entry( hass: HomeAssistant, entry: YALEXSBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up locks.""" async_add_entities([YaleXSBLELock(entry.runtime_data)]) diff --git a/homeassistant/components/yalexs_ble/sensor.py b/homeassistant/components/yalexs_ble/sensor.py index 90f61219e0b..bc9312effe3 100644 --- a/homeassistant/components/yalexs_ble/sensor.py +++ b/homeassistant/components/yalexs_ble/sensor.py @@ -20,7 +20,7 @@ from homeassistant.const import ( UnitOfElectricPotential, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import YALEXSBLEConfigEntry from .entity import YALEXSBLEEntity @@ -75,7 +75,7 @@ SENSORS: tuple[YaleXSBLESensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, entry: YALEXSBLEConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YALE XS Bluetooth sensors.""" data = entry.runtime_data diff --git a/homeassistant/components/yamaha_musiccast/__init__.py b/homeassistant/components/yamaha_musiccast/__init__.py index a2ce98dde56..3e890c8b943 100644 --- a/homeassistant/components/yamaha_musiccast/__init__.py +++ b/homeassistant/components/yamaha_musiccast/__init__.py @@ -55,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async_get_clientsession(hass), entry.data[CONF_UPNP_DESC], ) - coordinator = MusicCastDataUpdateCoordinator(hass, client=client) + coordinator = MusicCastDataUpdateCoordinator(hass, entry, client=client) await coordinator.async_config_entry_first_refresh() coordinator.musiccast.build_capabilities() diff --git a/homeassistant/components/yamaha_musiccast/coordinator.py b/homeassistant/components/yamaha_musiccast/coordinator.py index d5e0c67310a..13afbe3aa5e 100644 --- a/homeassistant/components/yamaha_musiccast/coordinator.py +++ b/homeassistant/components/yamaha_musiccast/coordinator.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING from aiomusiccast import MusicCastConnectionException from aiomusiccast.musiccast_device import MusicCastData, MusicCastDevice +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -25,11 +26,21 @@ SCAN_INTERVAL = timedelta(seconds=60) class MusicCastDataUpdateCoordinator(DataUpdateCoordinator[MusicCastData]): """Class to manage fetching data from the API.""" - def __init__(self, hass: HomeAssistant, client: MusicCastDevice) -> None: + config_entry: ConfigEntry + + def __init__( + self, hass: HomeAssistant, config_entry: ConfigEntry, client: MusicCastDevice + ) -> None: """Initialize.""" self.musiccast = client - super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL) + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) self.entities: list[MusicCastDeviceEntity] = [] async def _async_update_data(self) -> MusicCastData: diff --git a/homeassistant/components/yamaha_musiccast/media_player.py b/homeassistant/components/yamaha_musiccast/media_player.py index cff14f2b67d..7bf139e9c3b 100644 --- a/homeassistant/components/yamaha_musiccast/media_player.py +++ b/homeassistant/components/yamaha_musiccast/media_player.py @@ -24,7 +24,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import uuid as uuid_util from .const import ( @@ -55,7 +55,7 @@ MUSIC_PLAYER_BASE_SUPPORT = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MusicCast sensor based on a config entry.""" coordinator: MusicCastDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/yamaha_musiccast/number.py b/homeassistant/components/yamaha_musiccast/number.py index 02dd6720d91..0de14ef142d 100644 --- a/homeassistant/components/yamaha_musiccast/number.py +++ b/homeassistant/components/yamaha_musiccast/number.py @@ -7,7 +7,7 @@ from aiomusiccast.capabilities import NumberSetter from homeassistant.components.number import NumberEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MusicCastDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import MusicCastCapabilityEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MusicCast number entities based on a config entry.""" coordinator: MusicCastDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/yamaha_musiccast/select.py b/homeassistant/components/yamaha_musiccast/select.py index 3a4649b9ae5..133cb4c4d7b 100644 --- a/homeassistant/components/yamaha_musiccast/select.py +++ b/homeassistant/components/yamaha_musiccast/select.py @@ -7,7 +7,7 @@ from aiomusiccast.capabilities import OptionSetter from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, TRANSLATION_KEY_MAPPING from .coordinator import MusicCastDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import MusicCastCapabilityEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MusicCast select entities based on a config entry.""" coordinator: MusicCastDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/yamaha_musiccast/switch.py b/homeassistant/components/yamaha_musiccast/switch.py index 49d031a02b5..148f09930f3 100644 --- a/homeassistant/components/yamaha_musiccast/switch.py +++ b/homeassistant/components/yamaha_musiccast/switch.py @@ -7,7 +7,7 @@ from aiomusiccast.capabilities import BinarySetter from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import MusicCastDataUpdateCoordinator @@ -17,7 +17,7 @@ from .entity import MusicCastCapabilityEntity async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up MusicCast sensor based on a config entry.""" coordinator: MusicCastDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/yardian/switch.py b/homeassistant/components/yardian/switch.py index 910bacc1c2e..6531a48dc82 100644 --- a/homeassistant/components/yardian/switch.py +++ b/homeassistant/components/yardian/switch.py @@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, entity_platform -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -26,7 +26,7 @@ SERVICE_SCHEMA_START_IRRIGATION: VolDictType = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entry for a Yardian irrigation switches.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] diff --git a/homeassistant/components/yeelight/binary_sensor.py b/homeassistant/components/yeelight/binary_sensor.py index 9993272d510..69427c65fd5 100644 --- a/homeassistant/components/yeelight/binary_sensor.py +++ b/homeassistant/components/yeelight/binary_sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CONFIG_ENTRIES, DATA_DEVICE, DATA_UPDATED, DOMAIN from .entity import YeelightEntity @@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Yeelight from a config entry.""" device = hass.data[DOMAIN][DATA_CONFIG_ENTRIES][config_entry.entry_id][DATA_DEVICE] diff --git a/homeassistant/components/yeelight/light.py b/homeassistant/components/yeelight/light.py index 92ee3976f7f..a2f705298c9 100644 --- a/homeassistant/components/yeelight/light.py +++ b/homeassistant/components/yeelight/light.py @@ -34,7 +34,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.typing import VolDictType from homeassistant.util import color as color_util @@ -278,7 +278,7 @@ def _async_cmd[_YeelightBaseLightT: YeelightBaseLight, **_P, _R]( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Yeelight from a config entry.""" custom_effects = _parse_custom_effects(hass.data[DOMAIN][DATA_CUSTOM_EFFECTS]) diff --git a/homeassistant/components/yolink/binary_sensor.py b/homeassistant/components/yolink/binary_sensor.py index fa4c2202b03..30c04d3a424 100644 --- a/homeassistant/components/yolink/binary_sensor.py +++ b/homeassistant/components/yolink/binary_sensor.py @@ -23,7 +23,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -101,7 +101,7 @@ SENSOR_TYPES: tuple[YoLinkBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink Sensor from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/climate.py b/homeassistant/components/yolink/climate.py index ff3bbf0d93b..65253094fa9 100644 --- a/homeassistant/components/yolink/climate.py +++ b/homeassistant/components/yolink/climate.py @@ -22,7 +22,7 @@ from homeassistant.components.climate import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -47,7 +47,7 @@ YOLINK_ACTION_2_HA = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink Thermostat from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/cover.py b/homeassistant/components/yolink/cover.py index b2454bd0d4a..b1cfc3681cc 100644 --- a/homeassistant/components/yolink/cover.py +++ b/homeassistant/components/yolink/cover.py @@ -14,7 +14,7 @@ from homeassistant.components.cover import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -24,7 +24,7 @@ from .entity import YoLinkEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink garage door from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/light.py b/homeassistant/components/yolink/light.py index e07d17f7d74..54470673fa5 100644 --- a/homeassistant/components/yolink/light.py +++ b/homeassistant/components/yolink/light.py @@ -10,7 +10,7 @@ from yolink.const import ATTR_DEVICE_DIMMER from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -20,7 +20,7 @@ from .entity import YoLinkEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink Dimmer from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/lock.py b/homeassistant/components/yolink/lock.py index d675fd8cf06..135d0e26d04 100644 --- a/homeassistant/components/yolink/lock.py +++ b/homeassistant/components/yolink/lock.py @@ -10,7 +10,7 @@ from yolink.const import ATTR_DEVICE_LOCK, ATTR_DEVICE_LOCK_V2 from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -20,7 +20,7 @@ from .entity import YoLinkEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink lock from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/number.py b/homeassistant/components/yolink/number.py index 7b7b582382b..c643a20d0ea 100644 --- a/homeassistant/components/yolink/number.py +++ b/homeassistant/components/yolink/number.py @@ -17,7 +17,7 @@ from homeassistant.components.number import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -66,7 +66,7 @@ DEVICE_CONFIG_DESCRIPTIONS: tuple[YoLinkNumberTypeConfigEntityDescription, ...] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up device number type config option entity from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/sensor.py b/homeassistant/components/yolink/sensor.py index 8f263cdae07..511b7718e26 100644 --- a/homeassistant/components/yolink/sensor.py +++ b/homeassistant/components/yolink/sensor.py @@ -47,7 +47,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import percentage from .const import ( @@ -280,7 +280,7 @@ SENSOR_TYPES: tuple[YoLinkSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink Sensor from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/siren.py b/homeassistant/components/yolink/siren.py index 9e02f50bb70..d13e2dc6573 100644 --- a/homeassistant/components/yolink/siren.py +++ b/homeassistant/components/yolink/siren.py @@ -17,7 +17,7 @@ from homeassistant.components.siren import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import YoLinkCoordinator @@ -46,7 +46,7 @@ DEVICE_TYPE = [ATTR_DEVICE_SIREN] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink siren from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/switch.py b/homeassistant/components/yolink/switch.py index c999f04d90d..f2b3c83711c 100644 --- a/homeassistant/components/yolink/switch.py +++ b/homeassistant/components/yolink/switch.py @@ -23,7 +23,7 @@ from homeassistant.components.switch import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEV_MODEL_MULTI_OUTLET_YS6801, DOMAIN from .coordinator import YoLinkCoordinator @@ -116,7 +116,7 @@ DEVICE_TYPE = [ async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink switch from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/yolink/valve.py b/homeassistant/components/yolink/valve.py index d8c199697c3..26ce72a53d1 100644 --- a/homeassistant/components/yolink/valve.py +++ b/homeassistant/components/yolink/valve.py @@ -17,7 +17,7 @@ from homeassistant.components.valve import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DEV_MODEL_WATER_METER_YS5007, DOMAIN from .coordinator import YoLinkCoordinator @@ -50,7 +50,7 @@ DEVICE_TYPE = [ATTR_DEVICE_WATER_METER_CONTROLLER] async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up YoLink valve from a config entry.""" device_coordinators = hass.data[DOMAIN][config_entry.entry_id].device_coordinators diff --git a/homeassistant/components/youless/sensor.py b/homeassistant/components/youless/sensor.py index db8244c0b06..be17bed4352 100644 --- a/homeassistant/components/youless/sensor.py +++ b/homeassistant/components/youless/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import DOMAIN @@ -302,7 +302,9 @@ SENSOR_TYPES: tuple[YouLessSensorEntityDescription, ...] = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize the integration.""" coordinator: YouLessCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/youtube/sensor.py b/homeassistant/components/youtube/sensor.py index 8832382508c..128c23f7082 100644 --- a/homeassistant/components/youtube/sensor.py +++ b/homeassistant/components/youtube/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import SensorEntity, SensorEntityDescriptio from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ICON from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from . import YouTubeDataUpdateCoordinator @@ -72,7 +72,9 @@ SENSOR_TYPES = [ async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the YouTube sensor.""" coordinator: YouTubeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ diff --git a/homeassistant/components/zamg/sensor.py b/homeassistant/components/zamg/sensor.py index 7c7f5fd6c16..5846092e555 100644 --- a/homeassistant/components/zamg/sensor.py +++ b/homeassistant/components/zamg/sensor.py @@ -23,7 +23,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -163,7 +163,9 @@ API_FIELDS: list[str] = [desc.para_name for desc in SENSOR_TYPES] async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ZAMG sensor platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/zamg/weather.py b/homeassistant/components/zamg/weather.py index 286a6460f19..ac376577ade 100644 --- a/homeassistant/components/zamg/weather.py +++ b/homeassistant/components/zamg/weather.py @@ -12,7 +12,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTRIBUTION, CONF_STATION_ID, DOMAIN, MANUFACTURER_URL @@ -20,7 +20,9 @@ from .coordinator import ZamgDataUpdateCoordinator async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the ZAMG weather platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/zerproc/light.py b/homeassistant/components/zerproc/light.py index 36a964a46ab..19175ae3084 100644 --- a/homeassistant/components/zerproc/light.py +++ b/homeassistant/components/zerproc/light.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_time_interval from homeassistant.util import color as color_util @@ -51,7 +51,7 @@ async def discover_entities(hass: HomeAssistant) -> list[ZerprocLight]: async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Zerproc light devices.""" warned = False diff --git a/homeassistant/components/zeversolar/sensor.py b/homeassistant/components/zeversolar/sensor.py index 5023e274267..330e5bb72d8 100644 --- a/homeassistant/components/zeversolar/sensor.py +++ b/homeassistant/components/zeversolar/sensor.py @@ -16,7 +16,7 @@ from homeassistant.components.sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN from .coordinator import ZeversolarCoordinator @@ -52,7 +52,9 @@ SENSOR_TYPES = ( async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zeversolar sensor.""" coordinator: ZeversolarCoordinator = hass.data[DOMAIN][entry.entry_id] diff --git a/homeassistant/components/zha/alarm_control_panel.py b/homeassistant/components/zha/alarm_control_panel.py index 734683e5497..ff61ce07d23 100644 --- a/homeassistant/components/zha/alarm_control_panel.py +++ b/homeassistant/components/zha/alarm_control_panel.py @@ -18,7 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -46,7 +46,7 @@ ZHA_STATE_TO_ALARM_STATE_MAP = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation alarm control panel from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/binary_sensor.py b/homeassistant/components/zha/binary_sensor.py index f45ebf0c5a5..f8146026384 100644 --- a/homeassistant/components/zha/binary_sensor.py +++ b/homeassistant/components/zha/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -26,7 +26,7 @@ from .helpers import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation binary sensor from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/button.py b/homeassistant/components/zha/button.py index ecd5cd51f61..dd90bcd29b1 100644 --- a/homeassistant/components/zha/button.py +++ b/homeassistant/components/zha/button.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation button from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/climate.py b/homeassistant/components/zha/climate.py index af9f56cd7dc..a3f60420a38 100644 --- a/homeassistant/components/zha/climate.py +++ b/homeassistant/components/zha/climate.py @@ -30,7 +30,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import PRECISION_TENTHS, Platform, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -66,7 +66,7 @@ ZHA_TO_HA_HVAC_ACTION = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation sensor from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/cover.py b/homeassistant/components/zha/cover.py index 0d6be2dbb35..d058f37ff6b 100644 --- a/homeassistant/components/zha/cover.py +++ b/homeassistant/components/zha/cover.py @@ -23,7 +23,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -40,7 +40,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation cover from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/device_tracker.py b/homeassistant/components/zha/device_tracker.py index 7bdfc54c986..c86bb3352b5 100644 --- a/homeassistant/components/zha/device_tracker.py +++ b/homeassistant/components/zha/device_tracker.py @@ -10,7 +10,7 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -23,7 +23,7 @@ from .helpers import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation device tracker from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/fan.py b/homeassistant/components/zha/fan.py index 73b23e97387..81206f8819e 100644 --- a/homeassistant/components/zha/fan.py +++ b/homeassistant/components/zha/fan.py @@ -12,7 +12,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -27,7 +27,7 @@ from .helpers import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation fan from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/light.py b/homeassistant/components/zha/light.py index 2f5d9e9e4c9..a2fb61dc019 100644 --- a/homeassistant/components/zha/light.py +++ b/homeassistant/components/zha/light.py @@ -28,7 +28,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_ON, Platform from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .entity import ZHAEntity @@ -59,7 +59,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation light from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/lock.py b/homeassistant/components/zha/lock.py index ebac03eb7b8..dc27ec7a6fa 100644 --- a/homeassistant/components/zha/lock.py +++ b/homeassistant/components/zha/lock.py @@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import ( - AddEntitiesCallback, + AddConfigEntryEntitiesCallback, async_get_current_platform, ) @@ -33,7 +33,7 @@ SERVICE_CLEAR_LOCK_USER_CODE = "clear_lock_user_code" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation Door Lock from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/number.py b/homeassistant/components/zha/number.py index 263f5262994..567e2a5b37a 100644 --- a/homeassistant/components/zha/number.py +++ b/homeassistant/components/zha/number.py @@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UndefinedType from .entity import ZHAEntity @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation Analog Output from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/select.py b/homeassistant/components/zha/select.py index fdb47b550fe..4a38738b7dd 100644 --- a/homeassistant/components/zha/select.py +++ b/homeassistant/components/zha/select.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation siren from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index 0506496f447..a8383857e57 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .entity import ZHAEntity @@ -80,7 +80,7 @@ _EXTRA_STATE_ATTRIBUTES: set[str] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation sensor from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/siren.py b/homeassistant/components/zha/siren.py index 9d876d9ca4d..0c8b447cb37 100644 --- a/homeassistant/components/zha/siren.py +++ b/homeassistant/components/zha/siren.py @@ -26,7 +26,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -41,7 +41,7 @@ from .helpers import ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation siren from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/switch.py b/homeassistant/components/zha/switch.py index cb0268f98e0..dc150e2407d 100644 --- a/homeassistant/components/zha/switch.py +++ b/homeassistant/components/zha/switch.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .entity import ZHAEntity from .helpers import ( @@ -27,7 +27,7 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation switch from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zha/update.py b/homeassistant/components/zha/update.py index 2f540da5ea7..062581fd259 100644 --- a/homeassistant/components/zha/update.py +++ b/homeassistant/components/zha/update.py @@ -19,7 +19,7 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -52,7 +52,7 @@ OTA_MESSAGE_RELIABILITY = ( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Zigbee Home Automation update from config entry.""" zha_data = get_zha_data(hass) diff --git a/homeassistant/components/zodiac/sensor.py b/homeassistant/components/zodiac/sensor.py index d7cac07a322..41f200366ae 100644 --- a/homeassistant/components/zodiac/sensor.py +++ b/homeassistant/components/zodiac/sensor.py @@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import as_local, utcnow from .const import ( @@ -150,7 +150,7 @@ ZODIAC_BY_DATE = ( async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize the entries.""" diff --git a/homeassistant/components/zwave_js/binary_sensor.py b/homeassistant/components/zwave_js/binary_sensor.py index 0f1495fc6e6..d07846c8dcc 100644 --- a/homeassistant/components/zwave_js/binary_sensor.py +++ b/homeassistant/components/zwave_js/binary_sensor.py @@ -22,7 +22,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -261,7 +261,7 @@ def is_valid_notification_binary_sensor( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave binary sensor from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/button.py b/homeassistant/components/zwave_js/button.py index 7fd42700a05..f3a1d5af04d 100644 --- a/homeassistant/components/zwave_js/button.py +++ b/homeassistant/components/zwave_js/button.py @@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN, LOGGER from .discovery import ZwaveDiscoveryInfo @@ -24,7 +24,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave button from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/climate.py b/homeassistant/components/zwave_js/climate.py index 580694cae11..b27dbdad1a0 100644 --- a/homeassistant/components/zwave_js/climate.py +++ b/homeassistant/components/zwave_js/climate.py @@ -35,7 +35,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, UnitOfTemperature from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter from .const import DATA_CLIENT, DOMAIN @@ -97,7 +97,7 @@ ATTR_FAN_STATE = "fan_state" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave climate from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/cover.py b/homeassistant/components/zwave_js/cover.py index 218c5cc82fe..dc44f46a3ce 100644 --- a/homeassistant/components/zwave_js/cover.py +++ b/homeassistant/components/zwave_js/cover.py @@ -37,7 +37,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( COVER_POSITION_PROPERTY_KEYS, @@ -55,7 +55,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Cover from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/event.py b/homeassistant/components/zwave_js/event.py index 8dae66c26ac..66959aa9b75 100644 --- a/homeassistant/components/zwave_js/event.py +++ b/homeassistant/components/zwave_js/event.py @@ -10,7 +10,7 @@ from homeassistant.components.event import DOMAIN as EVENT_DOMAIN, EventEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_VALUE, DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Event entity from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/fan.py b/homeassistant/components/zwave_js/fan.py index d83132e4b95..ae36e0afb42 100644 --- a/homeassistant/components/zwave_js/fan.py +++ b/homeassistant/components/zwave_js/fan.py @@ -24,7 +24,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.percentage import ( percentage_to_ranged_value, ranged_value_to_percentage, @@ -46,7 +46,7 @@ ATTR_FAN_STATE = "fan_state" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Fan from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/humidifier.py b/homeassistant/components/zwave_js/humidifier.py index e883858036b..2b85bd4449f 100644 --- a/homeassistant/components/zwave_js/humidifier.py +++ b/homeassistant/components/zwave_js/humidifier.py @@ -26,7 +26,7 @@ from homeassistant.components.humidifier import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -70,7 +70,7 @@ DEHUMIDIFIER_ENTITY_DESCRIPTION = ZwaveHumidifierEntityDescription( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave humidifier from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/light.py b/homeassistant/components/zwave_js/light.py index 0a2ca95a2b0..a610bbcb91e 100644 --- a/homeassistant/components/zwave_js/light.py +++ b/homeassistant/components/zwave_js/light.py @@ -41,7 +41,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import color as color_util from .const import DATA_CLIENT, DOMAIN @@ -67,7 +67,7 @@ MAX_MIREDS = 370 # 2700K as a safe default async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Light from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/lock.py b/homeassistant/components/zwave_js/lock.py index c14517f4b03..f609084955c 100644 --- a/homeassistant/components/zwave_js/lock.py +++ b/homeassistant/components/zwave_js/lock.py @@ -25,7 +25,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ( ATTR_AUTO_RELOCK_TIME, @@ -62,7 +62,7 @@ UNIT16_SCHEMA = vol.All(vol.Coerce(int), vol.Range(min=0, max=65535)) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave lock from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/number.py b/homeassistant/components/zwave_js/number.py index 54162488d89..2e2d93bbdbe 100644 --- a/homeassistant/components/zwave_js/number.py +++ b/homeassistant/components/zwave_js/number.py @@ -16,7 +16,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ATTR_RESERVED_VALUES, DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -28,7 +28,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Number entity from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/select.py b/homeassistant/components/zwave_js/select.py index 49ad1868005..8a6ccc57c17 100644 --- a/homeassistant/components/zwave_js/select.py +++ b/homeassistant/components/zwave_js/select.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -27,7 +27,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Select entity from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/sensor.py b/homeassistant/components/zwave_js/sensor.py index b259711d21b..4db14d003b1 100644 --- a/homeassistant/components/zwave_js/sensor.py +++ b/homeassistant/components/zwave_js/sensor.py @@ -48,7 +48,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED, StateType from .binary_sensor import is_valid_notification_binary_sensor @@ -552,7 +552,7 @@ def get_entity_description( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave sensor from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/siren.py b/homeassistant/components/zwave_js/siren.py index 3a09049def3..f0526171a70 100644 --- a/homeassistant/components/zwave_js/siren.py +++ b/homeassistant/components/zwave_js/siren.py @@ -18,7 +18,7 @@ from homeassistant.components.siren import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -30,7 +30,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave Siren entity from Config Entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/strings.json b/homeassistant/components/zwave_js/strings.json index e2d7720189d..e845cc28707 100644 --- a/homeassistant/components/zwave_js/strings.json +++ b/homeassistant/components/zwave_js/strings.json @@ -344,8 +344,8 @@ "name": "[%key:component::zwave_js::services::set_value::fields::area_id::name%]" }, "broadcast": { - "description": "Whether command should be broadcast to all devices on the network.", - "name": "Broadcast?" + "description": "Whether the command should be broadcast to all devices on the network.", + "name": "Broadcast" }, "command_class": { "description": "[%key:component::zwave_js::services::set_value::fields::command_class::description%]", @@ -434,8 +434,8 @@ "name": "Entities" }, "refresh_all_values": { - "description": "Whether to refresh all values (true) or just the primary value (false).", - "name": "Refresh all values?" + "description": "Whether to refresh all values or just the primary value.", + "name": "Refresh all values" } }, "name": "Refresh values" @@ -592,8 +592,8 @@ "name": "[%key:component::zwave_js::services::set_config_parameter::fields::value::name%]" }, "wait_for_result": { - "description": "Whether or not to wait for a response from the node. If not included in the payload, the integration will decide whether to wait or not. If set to `true`, note that the action can take a while if setting a value on an asleep battery device.", - "name": "Wait for result?" + "description": "Whether to wait for a response from the node. If not included in the payload, the integration will decide whether to wait or not. If enabled, the action can take a while if setting a value on an asleep battery device.", + "name": "Wait for result" } }, "name": "Set a value (advanced)" diff --git a/homeassistant/components/zwave_js/switch.py b/homeassistant/components/zwave_js/switch.py index ef769209b31..2ff80d8505e 100644 --- a/homeassistant/components/zwave_js/switch.py +++ b/homeassistant/components/zwave_js/switch.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo @@ -28,7 +28,7 @@ PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave sensor from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_js/update.py b/homeassistant/components/zwave_js/update.py index d060abe007d..985c4a86813 100644 --- a/homeassistant/components/zwave_js/update.py +++ b/homeassistant/components/zwave_js/update.py @@ -32,7 +32,7 @@ from homeassistant.const import EntityCategory from homeassistant.core import CoreState, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import ExtraStoredData @@ -77,7 +77,7 @@ class ZWaveNodeFirmwareUpdateExtraStoredData(ExtraStoredData): async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Z-Wave update entity from config entry.""" client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT] diff --git a/homeassistant/components/zwave_me/binary_sensor.py b/homeassistant/components/zwave_me/binary_sensor.py index d121c17770b..8563ef76ce1 100644 --- a/homeassistant/components/zwave_me/binary_sensor.py +++ b/homeassistant/components/zwave_me/binary_sensor.py @@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ZWaveMeController from .const import DOMAIN, ZWaveMePlatform @@ -33,7 +33,7 @@ DEVICE_NAME = ZWaveMePlatform.BINARY_SENSOR async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the binary sensor platform.""" diff --git a/homeassistant/components/zwave_me/button.py b/homeassistant/components/zwave_me/button.py index 50ddf01aeab..27d95a14199 100644 --- a/homeassistant/components/zwave_me/button.py +++ b/homeassistant/components/zwave_me/button.py @@ -4,7 +4,7 @@ from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -15,7 +15,7 @@ DEVICE_NAME = ZWaveMePlatform.BUTTON async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the number platform.""" diff --git a/homeassistant/components/zwave_me/climate.py b/homeassistant/components/zwave_me/climate.py index b8eed88b505..d54cc6a9310 100644 --- a/homeassistant/components/zwave_me/climate.py +++ b/homeassistant/components/zwave_me/climate.py @@ -15,7 +15,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -28,7 +28,7 @@ DEVICE_NAME = ZWaveMePlatform.CLIMATE async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the climate platform.""" diff --git a/homeassistant/components/zwave_me/cover.py b/homeassistant/components/zwave_me/cover.py index c9359402c01..3ae8ec894e1 100644 --- a/homeassistant/components/zwave_me/cover.py +++ b/homeassistant/components/zwave_me/cover.py @@ -12,7 +12,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -23,7 +23,7 @@ DEVICE_NAME = ZWaveMePlatform.COVER async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the cover platform.""" diff --git a/homeassistant/components/zwave_me/fan.py b/homeassistant/components/zwave_me/fan.py index bd0feba0dfb..6ab1df618cb 100644 --- a/homeassistant/components/zwave_me/fan.py +++ b/homeassistant/components/zwave_me/fan.py @@ -8,7 +8,7 @@ from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -19,7 +19,7 @@ DEVICE_NAME = ZWaveMePlatform.FAN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fan platform.""" diff --git a/homeassistant/components/zwave_me/light.py b/homeassistant/components/zwave_me/light.py index ef3eca5d389..f8ed397ea25 100644 --- a/homeassistant/components/zwave_me/light.py +++ b/homeassistant/components/zwave_me/light.py @@ -15,7 +15,7 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ZWaveMeController from .const import DOMAIN, ZWaveMePlatform @@ -25,7 +25,7 @@ from .entity import ZWaveMeEntity async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the rgb platform.""" diff --git a/homeassistant/components/zwave_me/lock.py b/homeassistant/components/zwave_me/lock.py index 0bcc8f092ae..cdc8b6471c1 100644 --- a/homeassistant/components/zwave_me/lock.py +++ b/homeassistant/components/zwave_me/lock.py @@ -10,7 +10,7 @@ from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -21,7 +21,7 @@ DEVICE_NAME = ZWaveMePlatform.LOCK async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the lock platform.""" diff --git a/homeassistant/components/zwave_me/number.py b/homeassistant/components/zwave_me/number.py index 9a98a4f8d00..2d6b88840f4 100644 --- a/homeassistant/components/zwave_me/number.py +++ b/homeassistant/components/zwave_me/number.py @@ -4,7 +4,7 @@ from homeassistant.components.number import NumberEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -15,7 +15,7 @@ DEVICE_NAME = ZWaveMePlatform.NUMBER async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the number platform.""" diff --git a/homeassistant/components/zwave_me/sensor.py b/homeassistant/components/zwave_me/sensor.py index be0b0bae284..fa9ccdfee99 100644 --- a/homeassistant/components/zwave_me/sensor.py +++ b/homeassistant/components/zwave_me/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import ZWaveMeController from .const import DOMAIN, ZWaveMePlatform @@ -118,7 +118,7 @@ DEVICE_NAME = ZWaveMePlatform.SENSOR async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensor platform.""" diff --git a/homeassistant/components/zwave_me/siren.py b/homeassistant/components/zwave_me/siren.py index 443b2cc7b37..7bfbf2b2cd4 100644 --- a/homeassistant/components/zwave_me/siren.py +++ b/homeassistant/components/zwave_me/siren.py @@ -6,7 +6,7 @@ from homeassistant.components.siren import SirenEntity, SirenEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -17,7 +17,7 @@ DEVICE_NAME = ZWaveMePlatform.SIREN async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the siren platform.""" diff --git a/homeassistant/components/zwave_me/switch.py b/homeassistant/components/zwave_me/switch.py index 05cf06484e9..26d832ca022 100644 --- a/homeassistant/components/zwave_me/switch.py +++ b/homeassistant/components/zwave_me/switch.py @@ -11,7 +11,7 @@ from homeassistant.components.switch import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, ZWaveMePlatform from .entity import ZWaveMeEntity @@ -30,7 +30,7 @@ SWITCH_MAP: dict[str, SwitchEntityDescription] = { async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switch platform.""" diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index 620e4bc8197..b4de9749250 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -15,6 +15,7 @@ from collections.abc import ( ) from contextvars import ContextVar from copy import deepcopy +from dataclasses import dataclass, field from datetime import datetime from enum import Enum, StrEnum import functools @@ -22,7 +23,7 @@ from functools import cache import logging from random import randint from types import MappingProxyType -from typing import TYPE_CHECKING, Any, Self, cast +from typing import TYPE_CHECKING, Any, Self, TypedDict, cast from async_interrupt import interrupt from propcache.api import cached_property @@ -127,7 +128,7 @@ HANDLERS: Registry[str, type[ConfigFlow]] = Registry() STORAGE_KEY = "core.config_entries" STORAGE_VERSION = 1 -STORAGE_VERSION_MINOR = 4 +STORAGE_VERSION_MINOR = 5 SAVE_DELAY = 1 @@ -253,6 +254,10 @@ class UnknownEntry(ConfigError): """Unknown entry specified.""" +class UnknownSubEntry(ConfigError): + """Unknown subentry specified.""" + + class OperationNotAllowed(ConfigError): """Raised when a config entry operation is not allowed.""" @@ -297,6 +302,7 @@ class ConfigFlowResult(FlowResult[ConfigFlowContext, str], total=False): minor_version: int options: Mapping[str, Any] + subentries: Iterable[ConfigSubentryData] version: int @@ -310,6 +316,61 @@ def _validate_item(*, disabled_by: ConfigEntryDisabler | Any | None = None) -> N ) +class ConfigSubentryData(TypedDict): + """Container for configuration subentry data. + + Returned by integrations, a subentry_id will be assigned automatically. + """ + + data: Mapping[str, Any] + subentry_type: str + title: str + unique_id: str | None + + +class ConfigSubentryDataWithId(ConfigSubentryData): + """Container for configuration subentry data. + + This type is used when loading existing subentries from storage. + """ + + subentry_id: str + + +class SubentryFlowContext(FlowContext, total=False): + """Typed context dict for subentry flow.""" + + entry_id: str + subentry_id: str + + +class SubentryFlowResult(FlowResult[SubentryFlowContext, tuple[str, str]], total=False): + """Typed result dict for subentry flow.""" + + unique_id: str | None + + +@dataclass(frozen=True, kw_only=True) +class ConfigSubentry: + """Container for a configuration subentry.""" + + data: MappingProxyType[str, Any] + subentry_id: str = field(default_factory=ulid_util.ulid_now) + subentry_type: str + title: str + unique_id: str | None + + def as_dict(self) -> ConfigSubentryDataWithId: + """Return dictionary version of this subentry.""" + return { + "data": dict(self.data), + "subentry_id": self.subentry_id, + "subentry_type": self.subentry_type, + "title": self.title, + "unique_id": self.unique_id, + } + + class ConfigEntry[_DataT = Any]: """Hold a configuration entry.""" @@ -319,6 +380,7 @@ class ConfigEntry[_DataT = Any]: data: MappingProxyType[str, Any] runtime_data: _DataT options: MappingProxyType[str, Any] + subentries: MappingProxyType[str, ConfigSubentry] unique_id: str | None state: ConfigEntryState reason: str | None @@ -334,6 +396,7 @@ class ConfigEntry[_DataT = Any]: supports_remove_device: bool | None _supports_options: bool | None _supports_reconfigure: bool | None + _supported_subentry_types: dict[str, dict[str, bool]] | None update_listeners: list[UpdateListenerType] _async_cancel_retry_setup: Callable[[], Any] | None _on_unload: list[Callable[[], Coroutine[Any, Any, None] | None]] | None @@ -363,6 +426,7 @@ class ConfigEntry[_DataT = Any]: pref_disable_polling: bool | None = None, source: str, state: ConfigEntryState = ConfigEntryState.NOT_LOADED, + subentries_data: Iterable[ConfigSubentryData | ConfigSubentryDataWithId] | None, title: str, unique_id: str | None, version: int, @@ -388,6 +452,25 @@ class ConfigEntry[_DataT = Any]: # Entry options _setter(self, "options", MappingProxyType(options or {})) + # Subentries + subentries_data = subentries_data or () + subentries = {} + for subentry_data in subentries_data: + subentry_kwargs = {} + if "subentry_id" in subentry_data: + # If subentry_data has key "subentry_id", we're loading from storage + subentry_kwargs["subentry_id"] = subentry_data["subentry_id"] # type: ignore[typeddict-item] + subentry = ConfigSubentry( + data=MappingProxyType(subentry_data["data"]), + subentry_type=subentry_data["subentry_type"], + title=subentry_data["title"], + unique_id=subentry_data.get("unique_id"), + **subentry_kwargs, + ) + subentries[subentry.subentry_id] = subentry + + _setter(self, "subentries", MappingProxyType(subentries)) + # Entry system options if pref_disable_new_entities is None: pref_disable_new_entities = False @@ -424,6 +507,9 @@ class ConfigEntry[_DataT = Any]: # Supports reconfigure _setter(self, "_supports_reconfigure", None) + # Supports subentries + _setter(self, "_supported_subentry_types", None) + # Listeners to call on update _setter(self, "update_listeners", []) @@ -496,6 +582,28 @@ class ConfigEntry[_DataT = Any]: ) return self._supports_reconfigure or False + @property + def supported_subentry_types(self) -> dict[str, dict[str, bool]]: + """Return supported subentry types.""" + if self._supported_subentry_types is None and ( + handler := HANDLERS.get(self.domain) + ): + # work out sub entries supported by the handler + supported_flows = handler.async_get_supported_subentry_types(self) + object.__setattr__( + self, + "_supported_subentry_types", + { + subentry_flow_type: { + "supports_reconfigure": hasattr( + subentry_flow_handler, "async_step_reconfigure" + ) + } + for subentry_flow_type, subentry_flow_handler in supported_flows.items() + }, + ) + return self._supported_subentry_types or {} + def clear_state_cache(self) -> None: """Clear cached properties that are included in as_json_fragment.""" self.__dict__.pop("as_json_fragment", None) @@ -515,12 +623,14 @@ class ConfigEntry[_DataT = Any]: "supports_remove_device": self.supports_remove_device or False, "supports_unload": self.supports_unload or False, "supports_reconfigure": self.supports_reconfigure, + "supported_subentry_types": self.supported_subentry_types, "pref_disable_new_entities": self.pref_disable_new_entities, "pref_disable_polling": self.pref_disable_polling, "disabled_by": self.disabled_by, "reason": self.reason, "error_reason_translation_key": self.error_reason_translation_key, "error_reason_translation_placeholders": self.error_reason_translation_placeholders, + "num_subentries": len(self.subentries), } return json_fragment(json_bytes(json_repr)) @@ -1012,6 +1122,7 @@ class ConfigEntry[_DataT = Any]: "pref_disable_new_entities": self.pref_disable_new_entities, "pref_disable_polling": self.pref_disable_polling, "source": self.source, + "subentries": [subentry.as_dict() for subentry in self.subentries.values()], "title": self.title, "unique_id": self.unique_id, "version": self.version, @@ -1497,6 +1608,7 @@ class ConfigEntriesFlowManager( minor_version=result["minor_version"], options=result["options"], source=flow.context["source"], + subentries_data=result["subentries"], title=result["title"], unique_id=flow.unique_id, version=result["version"], @@ -1787,6 +1899,11 @@ class ConfigEntryStore(storage.Store[dict[str, list[dict[str, Any]]]]): for entry in data["entries"]: entry["discovery_keys"] = {} + if old_minor_version < 5: + # Version 1.4 adds config subentries + for entry in data["entries"]: + entry.setdefault("subentries", entry.get("subentries", {})) + if old_major_version > 1: raise NotImplementedError return data @@ -1803,6 +1920,7 @@ class ConfigEntries: self.hass = hass self.flow = ConfigEntriesFlowManager(hass, self, hass_config) self.options = OptionsFlowManager(hass) + self.subentries = ConfigSubentryFlowManager(hass) self._hass_config = hass_config self._entries = ConfigEntryItems(hass) self._store = ConfigEntryStore(hass) @@ -2005,6 +2123,7 @@ class ConfigEntries: pref_disable_new_entities=entry["pref_disable_new_entities"], pref_disable_polling=entry["pref_disable_polling"], source=entry["source"], + subentries_data=entry["subentries"], title=entry["title"], unique_id=entry["unique_id"], version=entry["version"], @@ -2164,6 +2283,44 @@ class ConfigEntries: If the entry was changed, the update_listeners are fired and this function returns True + If the entry was not changed, the update_listeners are + not fired and this function returns False + """ + return self._async_update_entry( + entry, + data=data, + discovery_keys=discovery_keys, + minor_version=minor_version, + options=options, + pref_disable_new_entities=pref_disable_new_entities, + pref_disable_polling=pref_disable_polling, + title=title, + unique_id=unique_id, + version=version, + ) + + @callback + def _async_update_entry( + self, + entry: ConfigEntry, + *, + data: Mapping[str, Any] | UndefinedType = UNDEFINED, + discovery_keys: MappingProxyType[str, tuple[DiscoveryKey, ...]] + | UndefinedType = UNDEFINED, + minor_version: int | UndefinedType = UNDEFINED, + options: Mapping[str, Any] | UndefinedType = UNDEFINED, + pref_disable_new_entities: bool | UndefinedType = UNDEFINED, + pref_disable_polling: bool | UndefinedType = UNDEFINED, + subentries: dict[str, ConfigSubentry] | UndefinedType = UNDEFINED, + title: str | UndefinedType = UNDEFINED, + unique_id: str | None | UndefinedType = UNDEFINED, + version: int | UndefinedType = UNDEFINED, + ) -> bool: + """Update a config entry. + + If the entry was changed, the update_listeners are + fired and this function returns True + If the entry was not changed, the update_listeners are not fired and this function returns False """ @@ -2226,11 +2383,21 @@ class ConfigEntries: changed = True _setter(entry, "options", MappingProxyType(options)) + if subentries is not UNDEFINED: + if entry.subentries != subentries: + changed = True + _setter(entry, "subentries", MappingProxyType(subentries)) + if not changed: return False _setter(entry, "modified_at", utcnow()) + self._async_save_and_notify(entry) + return True + + @callback + def _async_save_and_notify(self, entry: ConfigEntry) -> None: for listener in entry.update_listeners: self.hass.async_create_task( listener(self.hass, entry), @@ -2241,8 +2408,92 @@ class ConfigEntries: entry.clear_state_cache() entry.clear_storage_cache() self._async_dispatch(ConfigEntryChange.UPDATED, entry) + + @callback + def async_add_subentry(self, entry: ConfigEntry, subentry: ConfigSubentry) -> bool: + """Add a subentry to a config entry.""" + self._raise_if_subentry_unique_id_exists(entry, subentry.unique_id) + + return self._async_update_entry( + entry, + subentries=entry.subentries | {subentry.subentry_id: subentry}, + ) + + @callback + def async_remove_subentry(self, entry: ConfigEntry, subentry_id: str) -> bool: + """Remove a subentry from a config entry.""" + subentries = dict(entry.subentries) + try: + subentries.pop(subentry_id) + except KeyError as err: + raise UnknownSubEntry from err + + result = self._async_update_entry(entry, subentries=subentries) + dev_reg = dr.async_get(self.hass) + ent_reg = er.async_get(self.hass) + + dev_reg.async_clear_config_subentry(entry.entry_id, subentry_id) + ent_reg.async_clear_config_subentry(entry.entry_id, subentry_id) + return result + + @callback + def async_update_subentry( + self, + entry: ConfigEntry, + subentry: ConfigSubentry, + *, + data: Mapping[str, Any] | UndefinedType = UNDEFINED, + title: str | UndefinedType = UNDEFINED, + unique_id: str | None | UndefinedType = UNDEFINED, + ) -> bool: + """Update a config subentry. + + If the subentry was changed, the update_listeners are + fired and this function returns True + + If the subentry was not changed, the update_listeners are + not fired and this function returns False + """ + if entry.entry_id not in self._entries: + raise UnknownEntry(entry.entry_id) + if subentry.subentry_id not in entry.subentries: + raise UnknownSubEntry(subentry.subentry_id) + + self.hass.verify_event_loop_thread("hass.config_entries.async_update_subentry") + changed = False + _setter = object.__setattr__ + + if unique_id is not UNDEFINED and subentry.unique_id != unique_id: + self._raise_if_subentry_unique_id_exists(entry, unique_id) + changed = True + _setter(subentry, "unique_id", unique_id) + + if title is not UNDEFINED and subentry.title != title: + changed = True + _setter(subentry, "title", title) + + if data is not UNDEFINED and subentry.data != data: + changed = True + _setter(subentry, "data", MappingProxyType(data)) + + if not changed: + return False + + _setter(entry, "modified_at", utcnow()) + + self._async_save_and_notify(entry) return True + def _raise_if_subentry_unique_id_exists( + self, entry: ConfigEntry, unique_id: str | None + ) -> None: + """Raise if a subentry with the same unique_id exists.""" + if unique_id is None: + return + for existing_subentry in entry.subentries.values(): + if existing_subentry.unique_id == unique_id: + raise data_entry_flow.AbortFlow("already_configured") + @callback def _async_dispatch( self, change_type: ConfigEntryChange, entry: ConfigEntry @@ -2579,6 +2830,14 @@ class ConfigFlow(ConfigEntryBaseFlow): """Return options flow support for this handler.""" return cls.async_get_options_flow is not ConfigFlow.async_get_options_flow + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[ConfigSubentryFlow]]: + """Return subentries supported by this handler.""" + return {} + @callback def _async_abort_entries_match( self, match_dict: dict[str, Any] | None = None @@ -2887,6 +3146,7 @@ class ConfigFlow(ConfigEntryBaseFlow): description: str | None = None, description_placeholders: Mapping[str, str] | None = None, options: Mapping[str, Any] | None = None, + subentries: Iterable[ConfigSubentryData] | None = None, ) -> ConfigFlowResult: """Finish config flow and create a config entry.""" if self.source in {SOURCE_REAUTH, SOURCE_RECONFIGURE}: @@ -2906,6 +3166,7 @@ class ConfigFlow(ConfigEntryBaseFlow): result["minor_version"] = self.MINOR_VERSION result["options"] = options or {} + result["subentries"] = subentries or () result["version"] = self.VERSION return result @@ -3020,17 +3281,199 @@ class ConfigFlow(ConfigEntryBaseFlow): ) -class OptionsFlowManager( - data_entry_flow.FlowManager[ConfigFlowContext, ConfigFlowResult] -): - """Flow to set options for a configuration entry.""" +class _ConfigSubFlowManager: + """Mixin class for flow managers which manage flows tied to a config entry.""" - _flow_result = ConfigFlowResult + hass: HomeAssistant def _async_get_config_entry(self, config_entry_id: str) -> ConfigEntry: """Return config entry or raise if not found.""" return self.hass.config_entries.async_get_known_entry(config_entry_id) + +class ConfigSubentryFlowManager( + data_entry_flow.FlowManager[ + SubentryFlowContext, SubentryFlowResult, tuple[str, str] + ], + _ConfigSubFlowManager, +): + """Manage all the config subentry flows that are in progress.""" + + _flow_result = SubentryFlowResult + + async def async_create_flow( + self, + handler_key: tuple[str, str], + *, + context: FlowContext | None = None, + data: dict[str, Any] | None = None, + ) -> ConfigSubentryFlow: + """Create a subentry flow for a config entry. + + The entry_id and flow.handler[0] is the same thing to map entry with flow. + """ + if not context or "source" not in context: + raise KeyError("Context not set or doesn't have a source set") + + entry_id, subentry_type = handler_key + entry = self._async_get_config_entry(entry_id) + handler = await _async_get_flow_handler(self.hass, entry.domain, {}) + subentry_types = handler.async_get_supported_subentry_types(entry) + if subentry_type not in subentry_types: + raise data_entry_flow.UnknownHandler( + f"Config entry '{entry.domain}' does not support subentry '{subentry_type}'" + ) + subentry_flow = subentry_types[subentry_type]() + subentry_flow.init_step = context["source"] + return subentry_flow + + async def async_finish_flow( + self, + flow: data_entry_flow.FlowHandler[ + SubentryFlowContext, SubentryFlowResult, tuple[str, str] + ], + result: SubentryFlowResult, + ) -> SubentryFlowResult: + """Finish a subentry flow and add a new subentry to the configuration entry. + + The flow.handler[0] and entry_id is the same thing to map flow with entry. + """ + flow = cast(ConfigSubentryFlow, flow) + + if result["type"] != data_entry_flow.FlowResultType.CREATE_ENTRY: + return result + + entry_id, subentry_type = flow.handler + entry = self.hass.config_entries.async_get_entry(entry_id) + if entry is None: + raise UnknownEntry(entry_id) + + unique_id = result.get("unique_id") + if unique_id is not None and not isinstance(unique_id, str): + raise HomeAssistantError("unique_id must be a string") + + self.hass.config_entries.async_add_subentry( + entry, + ConfigSubentry( + data=MappingProxyType(result["data"]), + subentry_type=subentry_type, + title=result["title"], + unique_id=unique_id, + ), + ) + + result["result"] = True + return result + + +class ConfigSubentryFlow( + data_entry_flow.FlowHandler[ + SubentryFlowContext, SubentryFlowResult, tuple[str, str] + ] +): + """Base class for config subentry flows.""" + + _flow_result = SubentryFlowResult + handler: tuple[str, str] + + @callback + def async_create_entry( + self, + *, + title: str | None = None, + data: Mapping[str, Any], + description: str | None = None, + description_placeholders: Mapping[str, str] | None = None, + unique_id: str | None = None, + ) -> SubentryFlowResult: + """Finish config flow and create a config entry.""" + if self.source != SOURCE_USER: + raise ValueError(f"Source is {self.source}, expected {SOURCE_USER}") + + result = super().async_create_entry( + title=title, + data=data, + description=description, + description_placeholders=description_placeholders, + ) + + result["unique_id"] = unique_id + + return result + + @callback + def async_update_and_abort( + self, + entry: ConfigEntry, + subentry: ConfigSubentry, + *, + unique_id: str | None | UndefinedType = UNDEFINED, + title: str | UndefinedType = UNDEFINED, + data: Mapping[str, Any] | UndefinedType = UNDEFINED, + data_updates: Mapping[str, Any] | UndefinedType = UNDEFINED, + ) -> SubentryFlowResult: + """Update config subentry and finish subentry flow. + + :param data: replace the subentry data with new data + :param data_updates: add items from data_updates to subentry data - existing + keys are overridden + :param title: replace the title of the subentry + :param unique_id: replace the unique_id of the subentry + """ + if data_updates is not UNDEFINED: + if data is not UNDEFINED: + raise ValueError("Cannot set both data and data_updates") + data = entry.data | data_updates + self.hass.config_entries.async_update_subentry( + entry=entry, + subentry=subentry, + unique_id=unique_id, + title=title, + data=data, + ) + return self.async_abort(reason="reconfigure_successful") + + @property + def _reconfigure_entry_id(self) -> str: + """Return reconfigure entry id.""" + if self.source != SOURCE_RECONFIGURE: + raise ValueError(f"Source is {self.source}, expected {SOURCE_RECONFIGURE}") + return self.handler[0] + + @callback + def _get_reconfigure_entry(self) -> ConfigEntry: + """Return the reconfigure config entry linked to the current context.""" + return self.hass.config_entries.async_get_known_entry( + self._reconfigure_entry_id + ) + + @property + def _reconfigure_subentry_id(self) -> str: + """Return reconfigure subentry id.""" + if self.source != SOURCE_RECONFIGURE: + raise ValueError(f"Source is {self.source}, expected {SOURCE_RECONFIGURE}") + return self.context["subentry_id"] + + @callback + def _get_reconfigure_subentry(self) -> ConfigSubentry: + """Return the reconfigure config subentry linked to the current context.""" + entry = self.hass.config_entries.async_get_known_entry( + self._reconfigure_entry_id + ) + subentry_id = self._reconfigure_subentry_id + if subentry_id not in entry.subentries: + raise UnknownEntry + return entry.subentries[subentry_id] + + +class OptionsFlowManager( + data_entry_flow.FlowManager[ConfigFlowContext, ConfigFlowResult], + _ConfigSubFlowManager, +): + """Manage all the config entry option flows that are in progress.""" + + _flow_result = ConfigFlowResult + async def async_create_flow( self, handler_key: str, @@ -3040,7 +3483,7 @@ class OptionsFlowManager( ) -> OptionsFlow: """Create an options flow for a config entry. - Entry_id and flow.handler is the same thing to map entry with flow. + The entry_id and the flow.handler is the same thing to map entry with flow. """ entry = self._async_get_config_entry(handler_key) handler = await _async_get_flow_handler(self.hass, entry.domain, {}) @@ -3056,7 +3499,7 @@ class OptionsFlowManager( This method is called when a flow step returns FlowResultType.ABORT or FlowResultType.CREATE_ENTRY. - Flow.handler and entry_id is the same thing to map flow with entry. + The flow.handler and the entry_id is the same thing to map flow with entry. """ flow = cast(OptionsFlow, flow) diff --git a/homeassistant/data_entry_flow.py b/homeassistant/data_entry_flow.py index e5ee5a79922..251e22e7990 100644 --- a/homeassistant/data_entry_flow.py +++ b/homeassistant/data_entry_flow.py @@ -561,7 +561,7 @@ class FlowManager(abc.ABC, Generic[_FlowContextT, _FlowResultT, _HandlerT]): if not hasattr(flow, method): self._async_remove_flow_progress(flow.flow_id) raise UnknownStep( - f"Handler {self.__class__.__name__} doesn't support step {step_id}" + f"Handler {flow.__class__.__name__} doesn't support step {step_id}" ) async def _async_setup_preview( diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index c2c1c1dcb94..5b651389772 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -467,6 +467,7 @@ FLOWS = { "peco", "pegel_online", "permobil", + "pglab", "philips_js", "pi_hole", "picnic", diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index 08f24577ba1..8d5283c8803 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -4739,6 +4739,13 @@ "integration_type": "virtual", "supported_by": "opower" }, + "pglab": { + "name": "PG LAB Electronics", + "integration_type": "hub", + "config_flow": true, + "iot_class": "local_push", + "single_config_entry": true + }, "philips": { "name": "Philips", "integrations": { diff --git a/homeassistant/generated/mqtt.py b/homeassistant/generated/mqtt.py index 72f160ee2ec..c4eb8708b0e 100644 --- a/homeassistant/generated/mqtt.py +++ b/homeassistant/generated/mqtt.py @@ -16,6 +16,9 @@ MQTT = { "fully_kiosk": [ "fully/deviceInfo/+", ], + "pglab": [ + "pglab/discovery/#", + ], "qbus": [ "cloudapp/QBUSMQTTGW/state", "cloudapp/QBUSMQTTGW/config", diff --git a/homeassistant/helpers/chat_session.py b/homeassistant/helpers/chat_session.py index 686272dd834..e7a4ecd2ca9 100644 --- a/homeassistant/helpers/chat_session.py +++ b/homeassistant/helpers/chat_session.py @@ -7,6 +7,7 @@ from contextlib import contextmanager from contextvars import ContextVar from dataclasses import dataclass, field from datetime import datetime, timedelta +import logging from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import ( @@ -27,6 +28,7 @@ DATA_CHAT_SESSION: HassKey[dict[str, ChatSession]] = HassKey("chat_session") DATA_CHAT_SESSION_CLEANUP: HassKey[SessionCleanup] = HassKey("chat_session_cleanup") CONVERSATION_TIMEOUT = timedelta(minutes=5) +LOGGER = logging.getLogger(__name__) current_session: ContextVar[ChatSession | None] = ContextVar( "current_session", default=None @@ -100,6 +102,7 @@ class SessionCleanup: # yielding session based on it. for conversation_id, session in list(all_sessions.items()): if session.last_updated + CONVERSATION_TIMEOUT < now: + LOGGER.debug("Cleaning up session %s", conversation_id) del all_sessions[conversation_id] session.async_cleanup() @@ -150,6 +153,7 @@ def async_get_chat_session( pass if session is None: + LOGGER.debug("Creating new session %s", conversation_id) session = ChatSession(conversation_id) current_session.set(session) diff --git a/homeassistant/helpers/data_entry_flow.py b/homeassistant/helpers/data_entry_flow.py index b15d8b9e607..65eb2786aaf 100644 --- a/homeassistant/helpers/data_entry_flow.py +++ b/homeassistant/helpers/data_entry_flow.py @@ -17,7 +17,7 @@ from . import config_validation as cv _FlowManagerT = TypeVar( "_FlowManagerT", - bound=data_entry_flow.FlowManager[Any, Any], + bound=data_entry_flow.FlowManager[Any, Any, Any], default=data_entry_flow.FlowManager, ) @@ -70,7 +70,7 @@ class FlowManagerIndexView(_BaseFlowManagerView[_FlowManagerT]): async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Initialize a POST request. - Override `_post_impl` in subclasses which need + Override `post` and call `_post_impl` in subclasses which need to implement their own `RequestDataValidator` """ return await self._post_impl(request, data) diff --git a/homeassistant/helpers/deprecation.py b/homeassistant/helpers/deprecation.py index f02c6507d02..375ec58c26f 100644 --- a/homeassistant/helpers/deprecation.py +++ b/homeassistant/helpers/deprecation.py @@ -244,35 +244,35 @@ def _print_deprecation_warning_internal_impl( ) -class DeprecatedConstant(NamedTuple): +class DeprecatedConstant[T](NamedTuple): """Deprecated constant.""" - value: Any + value: T replacement: str breaks_in_ha_version: str | None -class DeprecatedConstantEnum(NamedTuple): +class DeprecatedConstantEnum[T: (StrEnum | IntEnum | IntFlag)](NamedTuple): """Deprecated constant.""" - enum: StrEnum | IntEnum | IntFlag + enum: T breaks_in_ha_version: str | None -class DeprecatedAlias(NamedTuple): +class DeprecatedAlias[T](NamedTuple): """Deprecated alias.""" - value: Any + value: T replacement: str breaks_in_ha_version: str | None -class DeferredDeprecatedAlias: +class DeferredDeprecatedAlias[T]: """Deprecated alias with deferred evaluation of the value.""" def __init__( self, - value_fn: Callable[[], Any], + value_fn: Callable[[], T], replacement: str, breaks_in_ha_version: str | None, ) -> None: @@ -282,7 +282,7 @@ class DeferredDeprecatedAlias: self._value_fn = value_fn @functools.cached_property - def value(self) -> Any: + def value(self) -> T: """Return the value.""" return self._value_fn() diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 92101dd0e21..991a6cf5a57 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -56,7 +56,7 @@ EVENT_DEVICE_REGISTRY_UPDATED: EventType[EventDeviceRegistryUpdatedData] = Event ) STORAGE_KEY = "core.device_registry" STORAGE_VERSION_MAJOR = 1 -STORAGE_VERSION_MINOR = 8 +STORAGE_VERSION_MINOR = 9 CLEANUP_DELAY = 10 @@ -272,6 +272,7 @@ class DeviceEntry: area_id: str | None = attr.ib(default=None) config_entries: set[str] = attr.ib(converter=set, factory=set) + config_entries_subentries: dict[str, set[str | None]] = attr.ib(factory=dict) configuration_url: str | None = attr.ib(default=None) connections: set[tuple[str, str]] = attr.ib(converter=set, factory=set) created_at: datetime = attr.ib(factory=utcnow) @@ -311,6 +312,10 @@ class DeviceEntry: "area_id": self.area_id, "configuration_url": self.configuration_url, "config_entries": list(self.config_entries), + "config_entries_subentries": { + config_entry_id: list(subentries) + for config_entry_id, subentries in self.config_entries_subentries.items() + }, "connections": list(self.connections), "created_at": self.created_at.timestamp(), "disabled_by": self.disabled_by, @@ -354,7 +359,13 @@ class DeviceEntry: json_bytes( { "area_id": self.area_id, + # The config_entries list can be removed from the storage + # representation in HA Core 2026.2 "config_entries": list(self.config_entries), + "config_entries_subentries": { + config_entry_id: list(subentries) + for config_entry_id, subentries in self.config_entries_subentries.items() + }, "configuration_url": self.configuration_url, "connections": list(self.connections), "created_at": self.created_at, @@ -384,6 +395,7 @@ class DeletedDeviceEntry: """Deleted Device Registry Entry.""" config_entries: set[str] = attr.ib() + config_entries_subentries: dict[str, set[str | None]] = attr.ib() connections: set[tuple[str, str]] = attr.ib() identifiers: set[tuple[str, str]] = attr.ib() id: str = attr.ib() @@ -395,6 +407,7 @@ class DeletedDeviceEntry: def to_device_entry( self, config_entry_id: str, + config_subentry_id: str | None, connections: set[tuple[str, str]], identifiers: set[tuple[str, str]], ) -> DeviceEntry: @@ -402,6 +415,7 @@ class DeletedDeviceEntry: return DeviceEntry( # type ignores: likely https://github.com/python/mypy/issues/8625 config_entries={config_entry_id}, # type: ignore[arg-type] + config_entries_subentries={config_entry_id: {config_subentry_id}}, connections=self.connections & connections, # type: ignore[arg-type] created_at=self.created_at, identifiers=self.identifiers & identifiers, # type: ignore[arg-type] @@ -415,7 +429,13 @@ class DeletedDeviceEntry: return json_fragment( json_bytes( { + # The config_entries list can be removed from the storage + # representation in HA Core 2026.2 "config_entries": list(self.config_entries), + "config_entries_subentries": { + config_entry_id: list(subentries) + for config_entry_id, subentries in self.config_entries_subentries.items() + }, "connections": list(self.connections), "created_at": self.created_at, "identifiers": list(self.identifiers), @@ -458,7 +478,10 @@ class DeviceRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]): old_data: dict[str, list[dict[str, Any]]], ) -> dict[str, Any]: """Migrate to the new version.""" - if old_major_version < 2: + # Support for a future major version bump to 2 added in HA Core 2025.2. + # Major versions 1 and 2 will be the same, except that version 2 will no + # longer store a list of config_entries. + if old_major_version < 3: if old_minor_version < 2: # Version 1.2 implements migration and freezes the available keys, # populate keys which were introduced before version 1.2 @@ -505,8 +528,20 @@ class DeviceRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]): device["created_at"] = device["modified_at"] = created_at for device in old_data["deleted_devices"]: device["created_at"] = device["modified_at"] = created_at + if old_minor_version < 9: + # Introduced in 2025.2 + for device in old_data["devices"]: + device["config_entries_subentries"] = { + config_entry_id: {None} + for config_entry_id in device["config_entries"] + } + for device in old_data["deleted_devices"]: + device["config_entries_subentries"] = { + config_entry_id: {None} + for config_entry_id in device["config_entries"] + } - if old_major_version > 1: + if old_major_version > 2: raise NotImplementedError return old_data @@ -722,6 +757,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): self, *, config_entry_id: str, + config_subentry_id: str | None | UndefinedType = UNDEFINED, configuration_url: str | URL | None | UndefinedType = UNDEFINED, connections: set[tuple[str, str]] | None | UndefinedType = UNDEFINED, created_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored @@ -812,7 +848,11 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): else: self.deleted_devices.pop(deleted_device.id) device = deleted_device.to_device_entry( - config_entry_id, connections, identifiers + config_entry_id, + # Interpret not specifying a subentry as None + config_subentry_id if config_subentry_id is not UNDEFINED else None, + connections, + identifiers, ) self.devices[device.id] = device # If creating a new device, default to the config entry name @@ -846,6 +886,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): device.id, allow_collisions=True, add_config_entry_id=config_entry_id, + add_config_subentry_id=config_subentry_id, configuration_url=configuration_url, device_info_type=device_info_type, disabled_by=disabled_by, @@ -874,6 +915,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): device_id: str, *, add_config_entry_id: str | UndefinedType = UNDEFINED, + add_config_subentry_id: str | None | UndefinedType = UNDEFINED, # Temporary flag so we don't blow up when collisions are implicitly introduced # by calls to async_get_or_create. Must not be set by integrations. allow_collisions: bool = False, @@ -894,25 +936,58 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): new_connections: set[tuple[str, str]] | UndefinedType = UNDEFINED, new_identifiers: set[tuple[str, str]] | UndefinedType = UNDEFINED, remove_config_entry_id: str | UndefinedType = UNDEFINED, + remove_config_subentry_id: str | None | UndefinedType = UNDEFINED, serial_number: str | None | UndefinedType = UNDEFINED, suggested_area: str | None | UndefinedType = UNDEFINED, sw_version: str | None | UndefinedType = UNDEFINED, via_device_id: str | None | UndefinedType = UNDEFINED, ) -> DeviceEntry | None: - """Update device attributes.""" + """Update device attributes. + + :param add_config_subentry_id: Add the device to a specific subentry of add_config_entry_id + :param remove_config_subentry_id: Remove the device from a specific subentry of remove_config_subentry_id + """ old = self.devices[device_id] new_values: dict[str, Any] = {} # Dict with new key/value pairs old_values: dict[str, Any] = {} # Dict with old key/value pairs config_entries = old.config_entries + config_entries_subentries = old.config_entries_subentries if add_config_entry_id is not UNDEFINED: - if self.hass.config_entries.async_get_entry(add_config_entry_id) is None: + if ( + add_config_entry := self.hass.config_entries.async_get_entry( + add_config_entry_id + ) + ) is None: raise HomeAssistantError( f"Can't link device to unknown config entry {add_config_entry_id}" ) + if add_config_subentry_id is not UNDEFINED: + if add_config_entry_id is UNDEFINED: + raise HomeAssistantError( + "Can't add config subentry without specifying config entry" + ) + if ( + add_config_subentry_id + # mypy says add_config_entry can be None. That's impossible, because we + # raise above if that happens + and add_config_subentry_id not in add_config_entry.subentries # type: ignore[union-attr] + ): + raise HomeAssistantError( + f"Config entry {add_config_entry_id} has no subentry {add_config_subentry_id}" + ) + + if ( + remove_config_subentry_id is not UNDEFINED + and remove_config_entry_id is UNDEFINED + ): + raise HomeAssistantError( + "Can't remove config subentry without specifying config entry" + ) + if not new_connections and not new_identifiers: raise HomeAssistantError( "A device must have at least one of identifiers or connections" @@ -943,6 +1018,10 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): area_id = area.id if add_config_entry_id is not UNDEFINED: + if add_config_subentry_id is UNDEFINED: + # Interpret not specifying a subentry as None (the main entry) + add_config_subentry_id = None + primary_entry_id = old.primary_config_entry if ( device_info_type == "primary" @@ -962,25 +1041,59 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): if add_config_entry_id not in old.config_entries: config_entries = old.config_entries | {add_config_entry_id} + config_entries_subentries = old.config_entries_subentries | { + add_config_entry_id: {add_config_subentry_id} + } + elif ( + add_config_subentry_id + not in old.config_entries_subentries[add_config_entry_id] + ): + config_entries_subentries = old.config_entries_subentries | { + add_config_entry_id: old.config_entries_subentries[ + add_config_entry_id + ] + | {add_config_subentry_id} + } if ( remove_config_entry_id is not UNDEFINED and remove_config_entry_id in config_entries ): - if config_entries == {remove_config_entry_id}: - self.async_remove_device(device_id) - return None + if remove_config_subentry_id is UNDEFINED: + config_entries_subentries = dict(old.config_entries_subentries) + del config_entries_subentries[remove_config_entry_id] + elif ( + remove_config_subentry_id + in old.config_entries_subentries[remove_config_entry_id] + ): + config_entries_subentries = old.config_entries_subentries | { + remove_config_entry_id: old.config_entries_subentries[ + remove_config_entry_id + ] + - {remove_config_subentry_id} + } + if not config_entries_subentries[remove_config_entry_id]: + del config_entries_subentries[remove_config_entry_id] - if remove_config_entry_id == old.primary_config_entry: - new_values["primary_config_entry"] = None - old_values["primary_config_entry"] = old.primary_config_entry + if remove_config_entry_id not in config_entries_subentries: + if config_entries == {remove_config_entry_id}: + self.async_remove_device(device_id) + return None - config_entries = config_entries - {remove_config_entry_id} + if remove_config_entry_id == old.primary_config_entry: + new_values["primary_config_entry"] = None + old_values["primary_config_entry"] = old.primary_config_entry + + config_entries = config_entries - {remove_config_entry_id} if config_entries != old.config_entries: new_values["config_entries"] = config_entries old_values["config_entries"] = old.config_entries + if config_entries_subentries != old.config_entries_subentries: + new_values["config_entries_subentries"] = config_entries_subentries + old_values["config_entries_subentries"] = old.config_entries_subentries + added_connections: set[tuple[str, str]] | None = None added_identifiers: set[tuple[str, str]] | None = None @@ -1138,6 +1251,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): device = self.devices.pop(device_id) self.deleted_devices[device_id] = DeletedDeviceEntry( config_entries=device.config_entries, + config_entries_subentries=device.config_entries_subentries, connections=device.connections, created_at=device.created_at, identifiers=device.identifiers, @@ -1168,7 +1282,13 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): for device in data["devices"]: devices[device["id"]] = DeviceEntry( area_id=device["area_id"], - config_entries=set(device["config_entries"]), + config_entries=set(device["config_entries_subentries"]), + config_entries_subentries={ + config_entry_id: set(subentries) + for config_entry_id, subentries in device[ + "config_entries_subentries" + ].items() + }, configuration_url=device["configuration_url"], # type ignores (if tuple arg was cast): likely https://github.com/python/mypy/issues/8625 connections={ @@ -1208,6 +1328,12 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): for device in data["deleted_devices"]: deleted_devices[device["id"]] = DeletedDeviceEntry( config_entries=set(device["config_entries"]), + config_entries_subentries={ + config_entry_id: set(subentries) + for config_entry_id, subentries in device[ + "config_entries_subentries" + ].items() + }, connections={tuple(conn) for conn in device["connections"]}, created_at=datetime.fromisoformat(device["created_at"]), identifiers={tuple(iden) for iden in device["identifiers"]}, @@ -1243,14 +1369,70 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): if config_entries == {config_entry_id}: # Add a time stamp when the deleted device became orphaned self.deleted_devices[deleted_device.id] = attr.evolve( - deleted_device, orphaned_timestamp=now_time, config_entries=set() + deleted_device, + orphaned_timestamp=now_time, + config_entries=set(), + config_entries_subentries={}, ) else: config_entries = config_entries - {config_entry_id} + config_entries_subentries = dict( + deleted_device.config_entries_subentries + ) + del config_entries_subentries[config_entry_id] # No need to reindex here since we currently # do not have a lookup by config entry self.deleted_devices[deleted_device.id] = attr.evolve( - deleted_device, config_entries=config_entries + deleted_device, + config_entries=config_entries, + config_entries_subentries=config_entries_subentries, + ) + self.async_schedule_save() + + @callback + def async_clear_config_subentry( + self, config_entry_id: str, config_subentry_id: str + ) -> None: + """Clear config entry from registry entries.""" + now_time = time.time() + now_time = time.time() + for device in self.devices.get_devices_for_config_entry_id(config_entry_id): + self.async_update_device( + device.id, + remove_config_entry_id=config_entry_id, + remove_config_subentry_id=config_subentry_id, + ) + for deleted_device in list(self.deleted_devices.values()): + config_entries = deleted_device.config_entries + config_entries_subentries = deleted_device.config_entries_subentries + if ( + config_entry_id not in config_entries_subentries + or config_subentry_id not in config_entries_subentries[config_entry_id] + ): + continue + if config_entries_subentries == {config_entry_id: {config_subentry_id}}: + # We're removing the last config subentry from the last config + # entry, add a time stamp when the deleted device became orphaned + self.deleted_devices[deleted_device.id] = attr.evolve( + deleted_device, + orphaned_timestamp=now_time, + config_entries=set(), + config_entries_subentries={}, + ) + else: + config_entries_subentries = config_entries_subentries | { + config_entry_id: config_entries_subentries[config_entry_id] + - {config_subentry_id} + } + if not config_entries_subentries[config_entry_id]: + del config_entries_subentries[config_entry_id] + config_entries = config_entries - {config_entry_id} + # No need to reindex here since we currently + # do not have a lookup by config entry + self.deleted_devices[deleted_device.id] = attr.evolve( + deleted_device, + config_entries=config_entries, + config_entries_subentries=config_entries_subentries, ) self.async_schedule_save() diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index c8cc6979226..adf34f3b285 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -80,6 +80,22 @@ class AddEntitiesCallback(Protocol): """Define add_entities type.""" +class AddConfigEntryEntitiesCallback(Protocol): + """Protocol type for EntityPlatform.add_entities callback.""" + + def __call__( + self, + new_entities: Iterable[Entity], + update_before_add: bool = False, + *, + config_subentry_id: str | None = None, + ) -> None: + """Define add_entities type. + + :param config_subentry_id: subentry which the entities should be added to + """ + + class EntityPlatformModule(Protocol): """Protocol type for entity platform modules.""" @@ -105,7 +121,7 @@ class EntityPlatformModule(Protocol): self, hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up an integration platform from a config entry.""" @@ -517,13 +533,21 @@ class EntityPlatform: @callback def _async_schedule_add_entities_for_entry( - self, new_entities: Iterable[Entity], update_before_add: bool = False + self, + new_entities: Iterable[Entity], + update_before_add: bool = False, + *, + config_subentry_id: str | None = None, ) -> None: """Schedule adding entities for a single platform async and track the task.""" assert self.config_entry task = self.config_entry.async_create_task( self.hass, - self.async_add_entities(new_entities, update_before_add=update_before_add), + self.async_add_entities( + new_entities, + update_before_add=update_before_add, + config_subentry_id=config_subentry_id, + ), f"EntityPlatform async_add_entities_for_entry {self.domain}.{self.platform_name}", eager_start=True, ) @@ -625,12 +649,27 @@ class EntityPlatform: ) async def async_add_entities( - self, new_entities: Iterable[Entity], update_before_add: bool = False + self, + new_entities: Iterable[Entity], + update_before_add: bool = False, + *, + config_subentry_id: str | None = None, ) -> None: """Add entities for a single platform async. This method must be run in the event loop. + + :param subentry_id: subentry which the entities should be added to """ + if config_subentry_id and ( + not self.config_entry + or config_subentry_id not in self.config_entry.subentries + ): + raise HomeAssistantError( + f"Can't add entities to unknown subentry {config_subentry_id} of config " + f"entry {self.config_entry.entry_id if self.config_entry else None}" + ) + # handle empty list from component/platform if not new_entities: # type: ignore[truthy-iterable] return @@ -641,7 +680,9 @@ class EntityPlatform: entities: list[Entity] = [] for entity in new_entities: coros.append( - self._async_add_entity(entity, update_before_add, entity_registry) + self._async_add_entity( + entity, update_before_add, entity_registry, config_subentry_id + ) ) entities.append(entity) @@ -720,6 +761,7 @@ class EntityPlatform: entity: Entity, update_before_add: bool, entity_registry: EntityRegistry, + config_subentry_id: str | None, ) -> None: """Add an entity to the platform.""" if entity is None: @@ -779,6 +821,7 @@ class EntityPlatform: try: device = dev_reg.async_get(self.hass).async_get_or_create( config_entry_id=self.config_entry.entry_id, + config_subentry_id=config_subentry_id, **device_info, ) except dev_reg.DeviceInfoError as exc: @@ -825,6 +868,7 @@ class EntityPlatform: entity.unique_id, capabilities=entity.capability_attributes, config_entry=self.config_entry, + config_subentry_id=config_subentry_id, device_id=device.id if device else None, disabled_by=disabled_by, entity_category=entity.entity_category, diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 95a32696228..684d00fe344 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -79,7 +79,7 @@ EVENT_ENTITY_REGISTRY_UPDATED: EventType[EventEntityRegistryUpdatedData] = Event _LOGGER = logging.getLogger(__name__) STORAGE_VERSION_MAJOR = 1 -STORAGE_VERSION_MINOR = 15 +STORAGE_VERSION_MINOR = 16 STORAGE_KEY = "core.entity_registry" CLEANUP_INTERVAL = 3600 * 24 @@ -177,6 +177,7 @@ class RegistryEntry: categories: dict[str, str] = attr.ib(factory=dict) capabilities: Mapping[str, Any] | None = attr.ib(default=None) config_entry_id: str | None = attr.ib(default=None) + config_subentry_id: str | None = attr.ib(default=None) created_at: datetime = attr.ib(factory=utcnow) device_class: str | None = attr.ib(default=None) device_id: str | None = attr.ib(default=None) @@ -280,6 +281,7 @@ class RegistryEntry: "area_id": self.area_id, "categories": self.categories, "config_entry_id": self.config_entry_id, + "config_subentry_id": self.config_subentry_id, "created_at": self.created_at.timestamp(), "device_id": self.device_id, "disabled_by": self.disabled_by, @@ -341,6 +343,7 @@ class RegistryEntry: "categories": self.categories, "capabilities": self.capabilities, "config_entry_id": self.config_entry_id, + "config_subentry_id": self.config_subentry_id, "created_at": self.created_at, "device_class": self.device_class, "device_id": self.device_id, @@ -405,6 +408,7 @@ class DeletedRegistryEntry: unique_id: str = attr.ib() platform: str = attr.ib() config_entry_id: str | None = attr.ib() + config_subentry_id: str | None = attr.ib() domain: str = attr.ib(init=False, repr=False) id: str = attr.ib() orphaned_timestamp: float | None = attr.ib() @@ -424,6 +428,7 @@ class DeletedRegistryEntry: json_bytes( { "config_entry_id": self.config_entry_id, + "config_subentry_id": self.config_subentry_id, "created_at": self.created_at, "entity_id": self.entity_id, "id": self.id, @@ -539,6 +544,13 @@ class EntityRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]): for entity in data["deleted_entities"]: entity["created_at"] = entity["modified_at"] = created_at + if old_minor_version < 16: + # Version 1.16 adds config_subentry_id + for entity in data["entities"]: + entity["config_subentry_id"] = None + for entity in data["deleted_entities"]: + entity["config_subentry_id"] = None + if old_major_version > 1: raise NotImplementedError return data @@ -647,10 +659,12 @@ def _validate_item( platform: str, *, config_entry_id: str | None | UndefinedType = None, + config_subentry_id: str | None | UndefinedType = None, device_id: str | None | UndefinedType = None, disabled_by: RegistryEntryDisabler | None | UndefinedType = None, entity_category: EntityCategory | None | UndefinedType = None, hidden_by: RegistryEntryHider | None | UndefinedType = None, + old_config_subentry_id: str | None = None, report_non_string_unique_id: bool = True, unique_id: str | Hashable | UndefinedType | Any, ) -> None: @@ -676,6 +690,26 @@ def _validate_item( raise ValueError( f"Can't link entity to unknown config entry {config_entry_id}" ) + if ( + config_entry_id + and config_entry_id is not UNDEFINED + and old_config_subentry_id + and config_subentry_id is UNDEFINED + ): + raise ValueError("Can't change config entry without changing subentry") + if ( + config_entry_id + and config_entry_id is not UNDEFINED + and config_subentry_id + and config_subentry_id is not UNDEFINED + ): + if ( + not (config_entry := hass.config_entries.async_get_entry(config_entry_id)) + or config_subentry_id not in config_entry.subentries + ): + raise ValueError( + f"Config entry {config_entry_id} has no subentry {config_subentry_id}" + ) if device_id and device_id is not UNDEFINED: device_registry = dr.async_get(hass) if not device_registry.async_get(device_id): @@ -826,6 +860,7 @@ class EntityRegistry(BaseRegistry): # Data that we want entry to have capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, config_entry: ConfigEntry | None | UndefinedType = UNDEFINED, + config_subentry_id: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED, entity_category: EntityCategory | UndefinedType | None = UNDEFINED, has_entity_name: bool | UndefinedType = UNDEFINED, @@ -852,6 +887,7 @@ class EntityRegistry(BaseRegistry): entity_id, capabilities=capabilities, config_entry_id=config_entry_id, + config_subentry_id=config_subentry_id, device_id=device_id, entity_category=entity_category, has_entity_name=has_entity_name, @@ -869,6 +905,7 @@ class EntityRegistry(BaseRegistry): domain, platform, config_entry_id=config_entry_id, + config_subentry_id=config_subentry_id, device_id=device_id, disabled_by=disabled_by, entity_category=entity_category, @@ -907,6 +944,7 @@ class EntityRegistry(BaseRegistry): entry = RegistryEntry( capabilities=none_if_undefined(capabilities), config_entry_id=none_if_undefined(config_entry_id), + config_subentry_id=none_if_undefined(config_subentry_id), created_at=created_at, device_id=none_if_undefined(device_id), disabled_by=disabled_by, @@ -949,6 +987,7 @@ class EntityRegistry(BaseRegistry): orphaned_timestamp = None if config_entry_id else time.time() self.deleted_entities[key] = DeletedRegistryEntry( config_entry_id=config_entry_id, + config_subentry_id=entity.config_subentry_id, created_at=entity.created_at, entity_id=entity_id, id=entity.id, @@ -1008,6 +1047,20 @@ class EntityRegistry(BaseRegistry): ): self.async_remove(entity.entity_id) + # Remove entities which belong to config subentries no longer associated with the + # device + entities = async_entries_for_device( + self, event.data["device_id"], include_disabled_entities=True + ) + for entity in entities: + if ( + (config_entry_id := entity.config_entry_id) is not None + and config_entry_id in device.config_entries + and entity.config_subentry_id + not in device.config_entries_subentries[config_entry_id] + ): + self.async_remove(entity.entity_id) + # Re-enable disabled entities if the device is no longer disabled if not device.disabled: entities = async_entries_for_device( @@ -1041,6 +1094,7 @@ class EntityRegistry(BaseRegistry): categories: dict[str, str] | UndefinedType = UNDEFINED, capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, config_entry_id: str | None | UndefinedType = UNDEFINED, + config_subentry_id: str | None | UndefinedType = UNDEFINED, device_class: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED, disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED, @@ -1073,6 +1127,7 @@ class EntityRegistry(BaseRegistry): ("categories", categories), ("capabilities", capabilities), ("config_entry_id", config_entry_id), + ("config_subentry_id", config_subentry_id), ("device_class", device_class), ("device_id", device_id), ("disabled_by", disabled_by), @@ -1102,10 +1157,12 @@ class EntityRegistry(BaseRegistry): old.domain, old.platform, config_entry_id=config_entry_id, + config_subentry_id=config_subentry_id, device_id=device_id, disabled_by=disabled_by, entity_category=entity_category, hidden_by=hidden_by, + old_config_subentry_id=old.config_subentry_id, unique_id=new_unique_id, ) @@ -1170,6 +1227,7 @@ class EntityRegistry(BaseRegistry): categories: dict[str, str] | UndefinedType = UNDEFINED, capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, config_entry_id: str | None | UndefinedType = UNDEFINED, + config_subentry_id: str | None | UndefinedType = UNDEFINED, device_class: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED, disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED, @@ -1196,6 +1254,7 @@ class EntityRegistry(BaseRegistry): categories=categories, capabilities=capabilities, config_entry_id=config_entry_id, + config_subentry_id=config_subentry_id, device_class=device_class, device_id=device_id, disabled_by=disabled_by, @@ -1222,6 +1281,7 @@ class EntityRegistry(BaseRegistry): new_platform: str, *, new_config_entry_id: str | UndefinedType = UNDEFINED, + new_config_subentry_id: str | UndefinedType = UNDEFINED, new_unique_id: str | UndefinedType = UNDEFINED, new_device_id: str | None | UndefinedType = UNDEFINED, ) -> RegistryEntry: @@ -1246,6 +1306,7 @@ class EntityRegistry(BaseRegistry): entity_id, new_unique_id=new_unique_id, config_entry_id=new_config_entry_id, + config_subentry_id=new_config_subentry_id, device_id=new_device_id, platform=new_platform, ) @@ -1308,6 +1369,7 @@ class EntityRegistry(BaseRegistry): categories=entity["categories"], capabilities=entity["capabilities"], config_entry_id=entity["config_entry_id"], + config_subentry_id=entity["config_subentry_id"], created_at=datetime.fromisoformat(entity["created_at"]), device_class=entity["device_class"], device_id=entity["device_id"], @@ -1357,6 +1419,7 @@ class EntityRegistry(BaseRegistry): ) deleted_entities[key] = DeletedRegistryEntry( config_entry_id=entity["config_entry_id"], + config_subentry_id=entity["config_subentry_id"], created_at=datetime.fromisoformat(entity["created_at"]), entity_id=entity["entity_id"], id=entity["id"], @@ -1415,6 +1478,30 @@ class EntityRegistry(BaseRegistry): ) self.async_schedule_save() + @callback + def async_clear_config_subentry( + self, config_entry_id: str, config_subentry_id: str + ) -> None: + """Clear config subentry from registry entries.""" + now_time = time.time() + for entity_id in [ + entry.entity_id + for entry in self.entities.get_entries_for_config_entry_id(config_entry_id) + if entry.config_subentry_id == config_subentry_id + ]: + self.async_remove(entity_id) + for key, deleted_entity in list(self.deleted_entities.items()): + if config_subentry_id != deleted_entity.config_subentry_id: + continue + # Add a time stamp when the deleted entity became orphaned + self.deleted_entities[key] = attr.evolve( + deleted_entity, + orphaned_timestamp=now_time, + config_entry_id=None, + config_subentry_id=None, + ) + self.async_schedule_save() + @callback def async_purge_expired_orphaned_entities(self) -> None: """Purge expired orphaned entities from the registry. diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 0f53b732c13..4f52f49ce09 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -1,7 +1,7 @@ # Automatically generated by gen_requirements_all.py, do not edit aiodhcpwatcher==1.1.0 -aiodiscover==2.2.2 +aiodiscover==2.6.0 aiodns==3.2.0 aiohasupervisor==0.3.0 aiohttp-asyncmdnsresolver==0.1.0 @@ -37,7 +37,7 @@ habluetooth==3.21.1 hass-nabucasa==0.89.0 hassil==2.2.3 home-assistant-bluetooth==1.13.1 -home-assistant-frontend==20250205.0 +home-assistant-frontend==20250210.0 home-assistant-intents==2025.2.5 httpx==0.28.1 ifaddr==0.2.0 diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index f76e0b43c10..e2b6de6e6a3 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -252,7 +252,7 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = { arg_types={ 0: "HomeAssistant", 1: "ConfigEntry", - 2: "AddEntitiesCallback", + 2: "AddConfigEntryEntitiesCallback", }, return_type=None, ), diff --git a/requirements_all.txt b/requirements_all.txt index bb6d5219b94..f0e427714ae 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -219,7 +219,7 @@ aiocomelit==0.10.1 aiodhcpwatcher==1.1.0 # homeassistant.components.dhcp -aiodiscover==2.2.2 +aiodiscover==2.6.0 # homeassistant.components.dnsip aiodns==3.2.0 @@ -374,7 +374,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==12.4.1 +aioshelly==12.4.2 # homeassistant.components.skybell aioskybell==22.7.0 @@ -1027,7 +1027,7 @@ goodwe==0.3.6 google-api-python-client==2.71.0 # homeassistant.components.google_pubsub -google-cloud-pubsub==2.23.0 +google-cloud-pubsub==2.28.0 # homeassistant.components.google_cloud google-cloud-speech==2.27.0 @@ -1103,7 +1103,7 @@ ha-iotawattpy==0.1.2 ha-philipsjs==3.2.2 # homeassistant.components.habitica -habiticalib==0.3.5 +habiticalib==0.3.7 # homeassistant.components.bluetooth habluetooth==3.21.1 @@ -1149,7 +1149,7 @@ hole==0.8.0 holidays==0.66 # homeassistant.components.frontend -home-assistant-frontend==20250205.0 +home-assistant-frontend==20250210.0 # homeassistant.components.conversation home-assistant-intents==2025.2.5 @@ -1562,7 +1562,7 @@ omnilogic==0.4.5 ondilo==0.5.0 # homeassistant.components.onedrive -onedrive-personal-sdk==0.0.9 +onedrive-personal-sdk==0.0.10 # homeassistant.components.onvif onvif-zeep-async==3.2.5 @@ -1752,7 +1752,7 @@ py-schluter==0.1.7 py-sucks==0.9.10 # homeassistant.components.synology_dsm -py-synologydsm-api==2.6.0 +py-synologydsm-api==2.6.2 # homeassistant.components.atome pyAtome==0.1.1 @@ -1776,7 +1776,7 @@ pyEmby==1.10 pyHik==0.3.2 # homeassistant.components.homee -pyHomee==1.2.5 +pyHomee==1.2.7 # homeassistant.components.rfxtrx pyRFXtrx==0.31.1 @@ -1828,7 +1828,7 @@ pyatv==0.16.0 pyaussiebb==0.1.5 # homeassistant.components.balboa -pybalboa==1.0.2 +pybalboa==1.1.2 # homeassistant.components.bbox pybbox==0.0.5-alpha @@ -1915,7 +1915,7 @@ pyebox==1.1.4 pyecoforest==0.4.0 # homeassistant.components.econet -pyeconet==0.1.26 +pyeconet==0.1.27 # homeassistant.components.ista_ecotrend pyecotrend-ista==3.3.1 @@ -1993,7 +1993,7 @@ pygti==0.9.4 pyhaversion==22.8.0 # homeassistant.components.heos -pyheos==1.0.1 +pyheos==1.0.2 # homeassistant.components.hive pyhive-integration==1.0.1 @@ -2017,7 +2017,7 @@ pyinsteon==1.6.3 pyintesishome==1.8.0 # homeassistant.components.ipma -pyipma==3.0.8 +pyipma==3.0.9 # homeassistant.components.ipp pyipp==0.17.0 @@ -2210,6 +2210,9 @@ pypca==0.0.7 # homeassistant.components.lcn pypck==0.8.5 +# homeassistant.components.pglab +pypglab==0.0.3 + # homeassistant.components.pjlink pypjlink2==1.2.1 @@ -2394,7 +2397,7 @@ python-gc100==1.0.3a0 python-gitlab==1.6.0 # homeassistant.components.google_drive -python-google-drive-api==0.0.2 +python-google-drive-api==0.1.0 # homeassistant.components.analytics_insights python-homeassistant-analytics==0.9.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7b6fd7f011f..c0bfebe5673 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -207,7 +207,7 @@ aiocomelit==0.10.1 aiodhcpwatcher==1.1.0 # homeassistant.components.dhcp -aiodiscover==2.2.2 +aiodiscover==2.6.0 # homeassistant.components.dnsip aiodns==3.2.0 @@ -353,7 +353,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==12.4.1 +aioshelly==12.4.2 # homeassistant.components.skybell aioskybell==22.7.0 @@ -874,7 +874,7 @@ goodwe==0.3.6 google-api-python-client==2.71.0 # homeassistant.components.google_pubsub -google-cloud-pubsub==2.23.0 +google-cloud-pubsub==2.28.0 # homeassistant.components.google_cloud google-cloud-speech==2.27.0 @@ -941,7 +941,7 @@ ha-iotawattpy==0.1.2 ha-philipsjs==3.2.2 # homeassistant.components.habitica -habiticalib==0.3.5 +habiticalib==0.3.7 # homeassistant.components.bluetooth habluetooth==3.21.1 @@ -975,7 +975,7 @@ hole==0.8.0 holidays==0.66 # homeassistant.components.frontend -home-assistant-frontend==20250205.0 +home-assistant-frontend==20250210.0 # homeassistant.components.conversation home-assistant-intents==2025.2.5 @@ -1307,7 +1307,7 @@ omnilogic==0.4.5 ondilo==0.5.0 # homeassistant.components.onedrive -onedrive-personal-sdk==0.0.9 +onedrive-personal-sdk==0.0.10 # homeassistant.components.onvif onvif-zeep-async==3.2.5 @@ -1447,7 +1447,7 @@ py-nightscout==1.2.2 py-sucks==0.9.10 # homeassistant.components.synology_dsm -py-synologydsm-api==2.6.0 +py-synologydsm-api==2.6.2 # homeassistant.components.hdmi_cec pyCEC==0.5.2 @@ -1462,7 +1462,7 @@ pyDuotecno==2024.10.1 pyElectra==1.2.4 # homeassistant.components.homee -pyHomee==1.2.5 +pyHomee==1.2.7 # homeassistant.components.rfxtrx pyRFXtrx==0.31.1 @@ -1505,7 +1505,7 @@ pyatv==0.16.0 pyaussiebb==0.1.5 # homeassistant.components.balboa -pybalboa==1.0.2 +pybalboa==1.1.2 # homeassistant.components.blackbird pyblackbird==0.6 @@ -1559,7 +1559,7 @@ pydroid-ipcam==2.0.0 pyecoforest==0.4.0 # homeassistant.components.econet -pyeconet==0.1.26 +pyeconet==0.1.27 # homeassistant.components.ista_ecotrend pyecotrend-ista==3.3.1 @@ -1619,7 +1619,7 @@ pygti==0.9.4 pyhaversion==22.8.0 # homeassistant.components.heos -pyheos==1.0.1 +pyheos==1.0.2 # homeassistant.components.hive pyhive-integration==1.0.1 @@ -1640,7 +1640,7 @@ pyicloud==1.0.0 pyinsteon==1.6.3 # homeassistant.components.ipma -pyipma==3.0.8 +pyipma==3.0.9 # homeassistant.components.ipp pyipp==0.17.0 @@ -1800,6 +1800,9 @@ pypalazzetti==0.1.19 # homeassistant.components.lcn pypck==0.8.5 +# homeassistant.components.pglab +pypglab==0.0.3 + # homeassistant.components.pjlink pypjlink2==1.2.1 @@ -1936,7 +1939,7 @@ python-fullykiosk==0.0.14 # python-gammu==3.2.4 # homeassistant.components.google_drive -python-google-drive-api==0.0.2 +python-google-drive-api==0.1.0 # homeassistant.components.analytics_insights python-homeassistant-analytics==0.9.0 diff --git a/script/hassfest/__main__.py b/script/hassfest/__main__.py index c93d8fd4499..277696c669b 100644 --- a/script/hassfest/__main__.py +++ b/script/hassfest/__main__.py @@ -107,7 +107,13 @@ def get_config() -> Config: "--plugins", type=validate_plugins, default=ALL_PLUGIN_NAMES, - help="Comma-separate list of plugins to run. Valid plugin names: %(default)s", + help="Comma-separated list of plugins to run. Valid plugin names: %(default)s", + ) + parser.add_argument( + "--skip-plugins", + type=validate_plugins, + default=[], + help=f"Comma-separated list of plugins to skip. Valid plugin names: {ALL_PLUGIN_NAMES}", ) parser.add_argument( "--core-path", @@ -131,6 +137,9 @@ def get_config() -> Config: ): raise RuntimeError("Run from Home Assistant root") + if parsed.skip_plugins: + parsed.plugins = set(parsed.plugins) - set(parsed.skip_plugins) + return Config( root=parsed.core_path.absolute(), specific_integrations=parsed.integration_path, diff --git a/script/hassfest/model.py b/script/hassfest/model.py index 08ded687096..1ca4178d9c2 100644 --- a/script/hassfest/model.py +++ b/script/hassfest/model.py @@ -157,8 +157,10 @@ class Integration: @property def core(self) -> bool: """Core integration.""" - return self.path.as_posix().startswith( - self._config.core_integrations_path.as_posix() + return ( + self.path.absolute() + .as_posix() + .startswith(self._config.core_integrations_path.as_posix()) ) @property diff --git a/script/hassfest/translations.py b/script/hassfest/translations.py index b3d397dbd55..2e5ec3e8ba0 100644 --- a/script/hassfest/translations.py +++ b/script/hassfest/translations.py @@ -285,6 +285,15 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema: "user" if integration.integration_type == "helper" else None ), ), + vol.Optional("config_subentries"): cv.schema_with_slug_keys( + gen_data_entry_schema( + config=config, + integration=integration, + flow_title=REQUIRED, + require_step_title=False, + ), + slug_validator=vol.Any("_", cv.slug), + ), vol.Optional("options"): gen_data_entry_schema( config=config, integration=integration, diff --git a/script/scaffold/__main__.py b/script/scaffold/__main__.py index 93c787df50f..4c102083a74 100644 --- a/script/scaffold/__main__.py +++ b/script/scaffold/__main__.py @@ -60,20 +60,32 @@ def main() -> int: generate.generate(template, info) + hassfest_args = [ + "python", + "-m", + "script.hassfest", + ] + # If we wanted a new integration, we've already done our work. if args.template != "integration": generate.generate(args.template, info) + else: + hassfest_args.extend( + [ + "--integration-path", + info.integration_dir, + "--skip-plugins", + "quality_scale", # Skip quality scale as it will fail for newly generated integrations. + ] + ) - pipe_null = {} if args.develop else {"stdout": subprocess.DEVNULL} - + # Always output sub commands as the output will contain useful information if a command fails. print("Running hassfest to pick up new information.") - subprocess.run(["python", "-m", "script.hassfest"], **pipe_null, check=True) + subprocess.run(hassfest_args, check=True) print() print("Running gen_requirements_all to pick up new information.") - subprocess.run( - ["python", "-m", "script.gen_requirements_all"], **pipe_null, check=True - ) + subprocess.run(["python", "-m", "script.gen_requirements_all"], check=True) print() print("Running script/translations_develop to pick up new translation strings.") @@ -86,7 +98,6 @@ def main() -> int: "--integration", info.domain, ], - **pipe_null, check=True, ) print() diff --git a/script/scaffold/templates/config_flow_helper/integration/sensor.py b/script/scaffold/templates/config_flow_helper/integration/sensor.py index 741b2e85eb2..9c00dd568eb 100644 --- a/script/scaffold/templates/config_flow_helper/integration/sensor.py +++ b/script/scaffold/templates/config_flow_helper/integration/sensor.py @@ -7,13 +7,13 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Initialize NEW_NAME config entry.""" registry = er.async_get(hass) diff --git a/script/scaffold/templates/integration/integration/manifest.json b/script/scaffold/templates/integration/integration/manifest.json index 7235500391d..15bc84a9b5e 100644 --- a/script/scaffold/templates/integration/integration/manifest.json +++ b/script/scaffold/templates/integration/integration/manifest.json @@ -7,6 +7,7 @@ "documentation": "https://www.home-assistant.io/integrations/NEW_DOMAIN", "homekit": {}, "iot_class": "IOT_CLASS", + "quality_scale": "bronze", "requirements": [], "ssdp": [], "zeroconf": [] diff --git a/tests/common.py b/tests/common.py index 0315ee6d845..65e84bc6f00 100644 --- a/tests/common.py +++ b/tests/common.py @@ -86,7 +86,10 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_send, ) from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.json import JSONEncoder, _orjson_default_encoder, json_dumps from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util, ulid as ulid_util @@ -1004,6 +1007,7 @@ class MockConfigEntry(config_entries.ConfigEntry): reason=None, source=config_entries.SOURCE_USER, state=None, + subentries_data=None, title="Mock Title", unique_id=None, version=1, @@ -1020,6 +1024,7 @@ class MockConfigEntry(config_entries.ConfigEntry): "options": options or {}, "pref_disable_new_entities": pref_disable_new_entities, "pref_disable_polling": pref_disable_polling, + "subentries_data": subentries_data or (), "title": title, "unique_id": unique_id, "version": version, @@ -1092,6 +1097,28 @@ class MockConfigEntry(config_entries.ConfigEntry): }, ) + async def start_subentry_reconfigure_flow( + self, + hass: HomeAssistant, + subentry_flow_type: str, + subentry_id: str, + *, + show_advanced_options: bool = False, + ) -> ConfigFlowResult: + """Start a subentry reconfiguration flow.""" + if self.entry_id not in hass.config_entries._entries: + raise ValueError( + "Config entry must be added to hass to start reconfiguration flow" + ) + return await hass.config_entries.subentries.async_init( + (self.entry_id, subentry_flow_type), + context={ + "source": config_entries.SOURCE_RECONFIGURE, + "subentry_id": subentry_id, + "show_advanced_options": show_advanced_options, + }, + ) + async def start_reauth_flow( hass: HomeAssistant, @@ -1789,7 +1816,7 @@ def setup_test_component_platform( async def _async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up a test component platform.""" async_add_entities(entities) diff --git a/tests/components/acaia/snapshots/test_binary_sensor.ambr b/tests/components/acaia/snapshots/test_binary_sensor.ambr index 113b5f1501e..a9c52c052a3 100644 --- a/tests/components/acaia/snapshots/test_binary_sensor.ambr +++ b/tests/components/acaia/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/acaia/snapshots/test_button.ambr b/tests/components/acaia/snapshots/test_button.ambr index cd91ca1a17a..11827c0997f 100644 --- a/tests/components/acaia/snapshots/test_button.ambr +++ b/tests/components/acaia/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/acaia/snapshots/test_init.ambr b/tests/components/acaia/snapshots/test_init.ambr index 7011b20f68c..c7a11cb58df 100644 --- a/tests/components/acaia/snapshots/test_init.ambr +++ b/tests/components/acaia/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'kitchen', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/acaia/snapshots/test_sensor.ambr b/tests/components/acaia/snapshots/test_sensor.ambr index c3c8ce966ee..9214db4f102 100644 --- a/tests/components/acaia/snapshots/test_sensor.ambr +++ b/tests/components/acaia/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/accuweather/snapshots/test_sensor.ambr b/tests/components/accuweather/snapshots/test_sensor.ambr index 3468d638bc0..257d29ae844 100644 --- a/tests/components/accuweather/snapshots/test_sensor.ambr +++ b/tests/components/accuweather/snapshots/test_sensor.ambr @@ -15,6 +15,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -80,6 +81,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +147,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -210,6 +213,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +279,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +338,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -385,6 +391,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -440,6 +447,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -489,6 +497,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -537,6 +546,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -585,6 +595,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -633,6 +644,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -681,6 +693,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -729,6 +742,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -777,6 +791,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -825,6 +840,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -873,6 +889,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -921,6 +938,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -969,6 +987,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1016,6 +1035,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1063,6 +1083,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1110,6 +1131,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1157,6 +1179,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1204,6 +1227,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1251,6 +1275,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1298,6 +1323,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1345,6 +1371,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1392,6 +1419,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1441,6 +1469,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1491,6 +1520,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1540,6 +1570,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1589,6 +1620,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1638,6 +1670,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1687,6 +1720,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1736,6 +1770,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1784,6 +1819,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1832,6 +1868,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1880,6 +1917,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1928,6 +1966,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1978,6 +2017,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2028,6 +2068,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2077,6 +2118,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2126,6 +2168,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2175,6 +2218,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2224,6 +2268,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2275,6 +2320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2328,6 +2374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2387,6 +2434,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2440,6 +2488,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2489,6 +2538,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2538,6 +2588,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2587,6 +2638,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2636,6 +2688,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2687,6 +2740,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2737,6 +2791,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2786,6 +2841,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2835,6 +2891,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2884,6 +2941,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2933,6 +2991,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2982,6 +3041,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3031,6 +3091,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3080,6 +3141,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3129,6 +3191,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3178,6 +3241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3229,6 +3293,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3279,6 +3344,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3328,6 +3394,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3377,6 +3444,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3426,6 +3494,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3475,6 +3544,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3524,6 +3594,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3573,6 +3644,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3622,6 +3694,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3671,6 +3744,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3720,6 +3794,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3769,6 +3844,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3818,6 +3894,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3867,6 +3944,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3916,6 +3994,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3965,6 +4044,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4014,6 +4094,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4063,6 +4144,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4112,6 +4194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4161,6 +4244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4210,6 +4294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4261,6 +4346,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4311,6 +4397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4359,6 +4446,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4407,6 +4495,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4455,6 +4544,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4503,6 +4593,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4551,6 +4642,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4599,6 +4691,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4647,6 +4740,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4695,6 +4789,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4743,6 +4838,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4791,6 +4887,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4840,6 +4937,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4889,6 +4987,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4938,6 +5037,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4987,6 +5087,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5038,6 +5139,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5088,6 +5190,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5137,6 +5240,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5186,6 +5290,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5235,6 +5340,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5284,6 +5390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5335,6 +5442,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5387,6 +5495,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5439,6 +5548,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5489,6 +5599,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5539,6 +5650,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5589,6 +5701,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5639,6 +5752,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5689,6 +5803,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5739,6 +5854,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5789,6 +5905,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5839,6 +5956,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5889,6 +6007,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5939,6 +6058,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5991,6 +6111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6041,6 +6162,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6091,6 +6213,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6141,6 +6264,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6191,6 +6315,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6241,6 +6366,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6291,6 +6417,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6341,6 +6468,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6391,6 +6519,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6441,6 +6570,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6491,6 +6621,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/accuweather/snapshots/test_weather.ambr b/tests/components/accuweather/snapshots/test_weather.ambr index cbe1891d216..862d79c2fde 100644 --- a/tests/components/accuweather/snapshots/test_weather.ambr +++ b/tests/components/accuweather/snapshots/test_weather.ambr @@ -247,6 +247,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/aemet/snapshots/test_diagnostics.ambr b/tests/components/aemet/snapshots/test_diagnostics.ambr index 0e40cce1b86..165e682de68 100644 --- a/tests/components/aemet/snapshots/test_diagnostics.ambr +++ b/tests/components/aemet/snapshots/test_diagnostics.ambr @@ -22,6 +22,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/airgradient/snapshots/test_button.ambr b/tests/components/airgradient/snapshots/test_button.ambr index fa3f8994c3c..85ad29f98f2 100644 --- a/tests/components/airgradient/snapshots/test_button.ambr +++ b/tests/components/airgradient/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airgradient/snapshots/test_init.ambr b/tests/components/airgradient/snapshots/test_init.ambr index 72cb12535f1..4e0c8027b43 100644 --- a/tests/components/airgradient/snapshots/test_init.ambr +++ b/tests/components/airgradient/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/airgradient/snapshots/test_number.ambr b/tests/components/airgradient/snapshots/test_number.ambr index 87df8757eeb..f847a4a472d 100644 --- a/tests/components/airgradient/snapshots/test_number.ambr +++ b/tests/components/airgradient/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airgradient/snapshots/test_select.ambr b/tests/components/airgradient/snapshots/test_select.ambr index b8fca4a110b..cc080560ae5 100644 --- a/tests/components/airgradient/snapshots/test_select.ambr +++ b/tests/components/airgradient/snapshots/test_select.ambr @@ -15,6 +15,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -74,6 +75,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -129,6 +131,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -184,6 +187,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +244,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -299,6 +304,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -360,6 +366,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +429,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -481,6 +489,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -539,6 +548,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -600,6 +610,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airgradient/snapshots/test_sensor.ambr b/tests/components/airgradient/snapshots/test_sensor.ambr index 3db188bed95..38a6774b6db 100644 --- a/tests/components/airgradient/snapshots/test_sensor.ambr +++ b/tests/components/airgradient/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -157,6 +160,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -213,6 +217,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -266,6 +271,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -315,6 +321,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -368,6 +375,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +430,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -469,6 +478,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -519,6 +529,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -620,6 +632,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -671,6 +684,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -722,6 +736,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -772,6 +787,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -823,6 +839,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -873,6 +890,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -924,6 +942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -975,6 +994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1022,6 +1042,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1070,6 +1091,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1120,6 +1142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1167,6 +1190,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1217,6 +1241,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1267,6 +1292,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1317,6 +1343,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1368,6 +1395,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1415,6 +1443,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airgradient/snapshots/test_switch.ambr b/tests/components/airgradient/snapshots/test_switch.ambr index 752355dbe97..ae2116d5b29 100644 --- a/tests/components/airgradient/snapshots/test_switch.ambr +++ b/tests/components/airgradient/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airgradient/snapshots/test_update.ambr b/tests/components/airgradient/snapshots/test_update.ambr index 1f944bb528b..53c815629f2 100644 --- a/tests/components/airgradient/snapshots/test_update.ambr +++ b/tests/components/airgradient/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airly/snapshots/test_diagnostics.ambr b/tests/components/airly/snapshots/test_diagnostics.ambr index ec501b2fd7e..1c760eaec52 100644 --- a/tests/components/airly/snapshots/test_diagnostics.ambr +++ b/tests/components/airly/snapshots/test_diagnostics.ambr @@ -19,6 +19,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Home', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/airly/snapshots/test_sensor.ambr b/tests/components/airly/snapshots/test_sensor.ambr index 23a4d13cd00..134023f34e0 100644 --- a/tests/components/airly/snapshots/test_sensor.ambr +++ b/tests/components/airly/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -62,6 +63,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -118,6 +120,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -173,6 +176,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -230,6 +234,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -287,6 +292,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +348,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -399,6 +406,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -456,6 +464,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -511,6 +520,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -568,6 +578,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airnow/snapshots/test_diagnostics.ambr b/tests/components/airnow/snapshots/test_diagnostics.ambr index 3dd4788dc61..73ba6a7123f 100644 --- a/tests/components/airnow/snapshots/test_diagnostics.ambr +++ b/tests/components/airnow/snapshots/test_diagnostics.ambr @@ -35,6 +35,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 2, diff --git a/tests/components/airtouch5/snapshots/test_cover.ambr b/tests/components/airtouch5/snapshots/test_cover.ambr index a8e57f69527..d2ae3cddc7f 100644 --- a/tests/components/airtouch5/snapshots/test_cover.ambr +++ b/tests/components/airtouch5/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/airvisual/snapshots/test_diagnostics.ambr b/tests/components/airvisual/snapshots/test_diagnostics.ambr index 606d6082351..0dbdef1d508 100644 --- a/tests/components/airvisual/snapshots/test_diagnostics.ambr +++ b/tests/components/airvisual/snapshots/test_diagnostics.ambr @@ -47,6 +47,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 3, diff --git a/tests/components/airvisual_pro/snapshots/test_diagnostics.ambr b/tests/components/airvisual_pro/snapshots/test_diagnostics.ambr index cb1d3a7aee7..113db6e3b96 100644 --- a/tests/components/airvisual_pro/snapshots/test_diagnostics.ambr +++ b/tests/components/airvisual_pro/snapshots/test_diagnostics.ambr @@ -101,6 +101,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'XXXXXXX', 'version': 1, diff --git a/tests/components/airzone/snapshots/test_diagnostics.ambr b/tests/components/airzone/snapshots/test_diagnostics.ambr index 0c3c0ba7c7a..b4976c07e1b 100644 --- a/tests/components/airzone/snapshots/test_diagnostics.ambr +++ b/tests/components/airzone/snapshots/test_diagnostics.ambr @@ -289,6 +289,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr b/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr index c6ad36916bf..4bd7bfaccdd 100644 --- a/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr +++ b/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr @@ -101,6 +101,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'installation1', 'version': 1, diff --git a/tests/components/alarm_control_panel/conftest.py b/tests/components/alarm_control_panel/conftest.py index ddf67b27860..541644def38 100644 --- a/tests/components/alarm_control_panel/conftest.py +++ b/tests/components/alarm_control_panel/conftest.py @@ -14,7 +14,7 @@ from homeassistant.components.alarm_control_panel.const import CodeFormat from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er, frame -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import MockAlarm @@ -194,7 +194,7 @@ async def setup_alarm_control_panel_platform_test_entity( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test alarm control panel platform via config entry.""" async_add_entities([entity]) diff --git a/tests/components/ambient_network/snapshots/test_sensor.ambr b/tests/components/ambient_network/snapshots/test_sensor.ambr index fd48184ca0b..7266afcfd96 100644 --- a/tests/components/ambient_network/snapshots/test_sensor.ambr +++ b/tests/components/ambient_network/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -126,6 +128,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -182,6 +185,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -238,6 +242,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -297,6 +302,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -353,6 +359,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -407,6 +414,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -458,6 +466,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -517,6 +526,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -576,6 +586,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -635,6 +646,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -691,6 +703,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -746,6 +759,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -803,6 +817,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -857,6 +872,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -916,6 +932,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -975,6 +992,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1034,6 +1052,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1093,6 +1112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1149,6 +1169,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1205,6 +1226,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1264,6 +1286,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1320,6 +1343,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1374,6 +1398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1425,6 +1450,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1484,6 +1510,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1543,6 +1570,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1602,6 +1630,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1658,6 +1687,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1713,6 +1743,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1770,6 +1801,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1824,6 +1856,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1883,6 +1916,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1942,6 +1976,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2000,6 +2035,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2058,6 +2094,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2113,6 +2150,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2168,6 +2206,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2226,6 +2265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2281,6 +2321,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2336,6 +2377,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2394,6 +2436,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2452,6 +2495,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2510,6 +2554,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2565,6 +2610,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2619,6 +2665,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2675,6 +2722,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2728,6 +2776,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2786,6 +2835,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ambient_station/snapshots/test_diagnostics.ambr b/tests/components/ambient_station/snapshots/test_diagnostics.ambr index 2f90b09d39f..07db19101ab 100644 --- a/tests/components/ambient_station/snapshots/test_diagnostics.ambr +++ b/tests/components/ambient_station/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 2, diff --git a/tests/components/analytics_insights/snapshots/test_sensor.ambr b/tests/components/analytics_insights/snapshots/test_sensor.ambr index 6e11b344b0b..799738eb677 100644 --- a/tests/components/analytics_insights/snapshots/test_sensor.ambr +++ b/tests/components/analytics_insights/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -308,6 +314,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/anthropic/snapshots/test_conversation.ambr b/tests/components/anthropic/snapshots/test_conversation.ambr index e4dd7cd00bb..93f3b03d9af 100644 --- a/tests/components/anthropic/snapshots/test_conversation.ambr +++ b/tests/components/anthropic/snapshots/test_conversation.ambr @@ -1,7 +1,7 @@ # serializer version: 1 # name: test_unknown_hass_api dict({ - 'conversation_id': None, + 'conversation_id': '1234', 'response': IntentResponse( card=dict({ }), @@ -20,7 +20,7 @@ speech=dict({ 'plain': dict({ 'extra_data': None, - 'speech': 'Error preparing LLM API: API non-existing not found', + 'speech': 'Error preparing LLM API', }), }), speech_slots=dict({ diff --git a/tests/components/anthropic/test_conversation.py b/tests/components/anthropic/test_conversation.py index bb77e2ff926..2f1de3a2db9 100644 --- a/tests/components/anthropic/test_conversation.py +++ b/tests/components/anthropic/test_conversation.py @@ -10,7 +10,6 @@ from syrupy.assertion import SnapshotAssertion import voluptuous as vol from homeassistant.components import conversation -from homeassistant.components.conversation import trace from homeassistant.const import CONF_LLM_HASS_API from homeassistant.core import Context, HomeAssistant from homeassistant.exceptions import HomeAssistantError @@ -250,42 +249,6 @@ async def test_function_call( ), ) - # Test Conversation tracing - traces = trace.async_get_traces() - assert traces - last_trace = traces[-1].as_dict() - trace_events = last_trace.get("events", []) - assert [event["event_type"] for event in trace_events] == [ - trace.ConversationTraceEventType.ASYNC_PROCESS, - trace.ConversationTraceEventType.AGENT_DETAIL, - trace.ConversationTraceEventType.TOOL_CALL, - ] - # AGENT_DETAIL event contains the raw prompt passed to the model - detail_event = trace_events[1] - assert "Answer in plain text" in detail_event["data"]["system"] - assert "Today's date is 2024-06-03." in trace_events[1]["data"]["system"] - - # Call it again, make sure we have updated prompt - with ( - patch( - "anthropic.resources.messages.AsyncMessages.create", - new_callable=AsyncMock, - side_effect=completion_result, - ) as mock_create, - freeze_time("2024-06-04 23:00:00"), - ): - result = await conversation.async_converse( - hass, - "Please call the test function", - None, - context, - agent_id=agent_id, - ) - - assert "Today's date is 2024-06-04." in mock_create.mock_calls[1][2]["system"] - # Test old assert message not updated - assert "Today's date is 2024-06-03." in trace_events[1]["data"]["system"] - @patch("homeassistant.components.anthropic.conversation.llm.AssistAPI._async_get_tools") async def test_function_exception( @@ -448,7 +411,7 @@ async def test_unknown_hass_api( ) result = await conversation.async_converse( - hass, "hello", None, Context(), agent_id="conversation.claude" + hass, "hello", "1234", Context(), agent_id="conversation.claude" ) assert result == snapshot diff --git a/tests/components/aosmith/snapshots/test_device.ambr b/tests/components/aosmith/snapshots/test_device.ambr index dec33a92fe2..e647b7fa6a5 100644 --- a/tests/components/aosmith/snapshots/test_device.ambr +++ b/tests/components/aosmith/snapshots/test_device.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'basement', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/aosmith/snapshots/test_sensor.ambr b/tests/components/aosmith/snapshots/test_sensor.ambr index 563b52f6df7..c422e8fdab5 100644 --- a/tests/components/aosmith/snapshots/test_sensor.ambr +++ b/tests/components/aosmith/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -60,6 +61,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/aosmith/snapshots/test_water_heater.ambr b/tests/components/aosmith/snapshots/test_water_heater.ambr index deb079570f1..43db89807b6 100644 --- a/tests/components/aosmith/snapshots/test_water_heater.ambr +++ b/tests/components/aosmith/snapshots/test_water_heater.ambr @@ -9,6 +9,7 @@ 'min_temp': 95, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -71,6 +72,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/apsystems/snapshots/test_binary_sensor.ambr b/tests/components/apsystems/snapshots/test_binary_sensor.ambr index 0875c88976b..381fc1864fc 100644 --- a/tests/components/apsystems/snapshots/test_binary_sensor.ambr +++ b/tests/components/apsystems/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/apsystems/snapshots/test_number.ambr b/tests/components/apsystems/snapshots/test_number.ambr index a2b82e23596..21141de7d64 100644 --- a/tests/components/apsystems/snapshots/test_number.ambr +++ b/tests/components/apsystems/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/apsystems/snapshots/test_sensor.ambr b/tests/components/apsystems/snapshots/test_sensor.ambr index 669e89fda17..251a8d8428c 100644 --- a/tests/components/apsystems/snapshots/test_sensor.ambr +++ b/tests/components/apsystems/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +372,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -416,6 +424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/apsystems/snapshots/test_switch.ambr b/tests/components/apsystems/snapshots/test_switch.ambr index 6daa9fd6e14..a9f74ee5517 100644 --- a/tests/components/apsystems/snapshots/test_switch.ambr +++ b/tests/components/apsystems/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/aquacell/snapshots/test_sensor.ambr b/tests/components/aquacell/snapshots/test_sensor.ambr index a237f59881a..eeac14c000d 100644 --- a/tests/components/aquacell/snapshots/test_sensor.ambr +++ b/tests/components/aquacell/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -154,6 +157,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -202,6 +206,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +261,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/arve/snapshots/test_sensor.ambr b/tests/components/arve/snapshots/test_sensor.ambr index 5c7888c41de..ed2494c3197 100644 --- a/tests/components/arve/snapshots/test_sensor.ambr +++ b/tests/components/arve/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -43,6 +44,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -78,6 +80,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +116,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -148,6 +152,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -183,6 +188,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +224,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/assist_pipeline/conftest.py b/tests/components/assist_pipeline/conftest.py index 0f6872edbfe..02ec7c04607 100644 --- a/tests/components/assist_pipeline/conftest.py +++ b/tests/components/assist_pipeline/conftest.py @@ -25,7 +25,7 @@ from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_setup_component from tests.common import ( @@ -225,7 +225,7 @@ async def init_supporting_components( async def async_setup_entry_stt_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test stt platform via config entry.""" async_add_entities([mock_stt_provider_entity]) @@ -233,7 +233,7 @@ async def init_supporting_components( async def async_setup_entry_wake_word_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test wake word platform via config entry.""" async_add_entities( @@ -325,7 +325,7 @@ async def assist_device( async def async_setup_entry_select_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test select platform via config entry.""" entities = [ diff --git a/tests/components/assist_pipeline/test_select.py b/tests/components/assist_pipeline/test_select.py index 5ce3b1020d0..fec34cb2496 100644 --- a/tests/components/assist_pipeline/test_select.py +++ b/tests/components/assist_pipeline/test_select.py @@ -19,7 +19,7 @@ from homeassistant.config_entries import ConfigEntry, ConfigEntryState from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import MockConfigEntry, MockPlatform, mock_platform @@ -31,7 +31,7 @@ class SelectPlatform(MockPlatform): self, hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up fake select platform.""" pipeline_entity = AssistPipelineSelect(hass, "test-domain", "test-prefix") diff --git a/tests/components/assist_pipeline/test_websocket.py b/tests/components/assist_pipeline/test_websocket.py index 2cd56f094dd..f856bbe7f61 100644 --- a/tests/components/assist_pipeline/test_websocket.py +++ b/tests/components/assist_pipeline/test_websocket.py @@ -9,6 +9,7 @@ from unittest.mock import ANY, Mock, patch import pytest from syrupy.assertion import SnapshotAssertion +from homeassistant.components import conversation from homeassistant.components.assist_pipeline.const import ( DOMAIN, SAMPLE_CHANNELS, @@ -22,7 +23,7 @@ from homeassistant.components.assist_pipeline.pipeline import ( ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import chat_session, device_registry as dr from .conftest import ( BYTES_ONE_SECOND, @@ -2727,3 +2728,62 @@ async def test_stt_cooldown_different_ids( # Both should start stt assert {event_type_1, event_type_2} == {"stt-start"} + + +async def test_intent_progress_event( + hass: HomeAssistant, + hass_ws_client: WebSocketGenerator, + init_components, +) -> None: + """Test intent-progress events from a pipeline are forwarded.""" + client = await hass_ws_client(hass) + + orig_converse = conversation.async_converse + expected_delta_events = [ + {"chat_log_delta": {"role": "assistant"}}, + {"chat_log_delta": {"content": "Hello"}}, + ] + + async def mock_delta_stream(): + """Mock delta stream.""" + for d in expected_delta_events: + yield d["chat_log_delta"] + + async def mock_converse(**kwargs): + """Mock converse method.""" + with ( + chat_session.async_get_chat_session( + kwargs["hass"], kwargs["conversation_id"] + ) as session, + conversation.async_get_chat_log(hass, session) as chat_log, + ): + async for _content in chat_log.async_add_delta_content_stream( + "", mock_delta_stream() + ): + pass + + return await orig_converse(**kwargs) + + with patch("homeassistant.components.conversation.async_converse", mock_converse): + await client.send_json_auto_id( + { + "type": "assist_pipeline/run", + "start_stage": "intent", + "end_stage": "intent", + "input": {"text": "Are the lights on?"}, + "conversation_id": "mock-conversation-id", + "device_id": "mock-device-id", + } + ) + + # result + msg = await client.receive_json() + assert msg["success"] + + events = [] + for _ in range(6): + msg = await client.receive_json() + if msg["event"]["type"] == "intent-progress": + events.append(msg["event"]["data"]) + + assert events == expected_delta_events diff --git a/tests/components/assist_satellite/test_entity.py b/tests/components/assist_satellite/test_entity.py index b3437bf5c5d..42b4adf742c 100644 --- a/tests/components/assist_satellite/test_entity.py +++ b/tests/components/assist_satellite/test_entity.py @@ -590,3 +590,54 @@ async def test_start_conversation_reject_builtin_agent( target={"entity_id": "assist_satellite.test_entity"}, blocking=True, ) + + +async def test_wake_word_start_keeps_responding( + hass: HomeAssistant, init_components: ConfigEntry, entity: MockAssistSatellite +) -> None: + """Test entity state stays responding on wake word start event.""" + + state = hass.states.get(ENTITY_ID) + assert state is not None + assert state.state == AssistSatelliteState.IDLE + + # Get into responding state + audio_stream = object() + + with patch( + "homeassistant.components.assist_satellite.entity.async_pipeline_from_audio_stream" + ) as mock_start_pipeline: + await entity.async_accept_pipeline_from_satellite( + audio_stream, start_stage=PipelineStage.TTS + ) + + assert mock_start_pipeline.called + kwargs = mock_start_pipeline.call_args[1] + event_callback = kwargs["event_callback"] + event_callback(PipelineEvent(PipelineEventType.TTS_START, {})) + + state = hass.states.get(ENTITY_ID) + assert state.state == AssistSatelliteState.RESPONDING + + # Verify that starting a new wake word stream keeps the state + audio_stream = object() + + with patch( + "homeassistant.components.assist_satellite.entity.async_pipeline_from_audio_stream" + ) as mock_start_pipeline: + await entity.async_accept_pipeline_from_satellite( + audio_stream, start_stage=PipelineStage.WAKE_WORD + ) + + assert mock_start_pipeline.called + kwargs = mock_start_pipeline.call_args[1] + event_callback = kwargs["event_callback"] + event_callback(PipelineEvent(PipelineEventType.WAKE_WORD_START, {})) + + state = hass.states.get(ENTITY_ID) + assert state.state == AssistSatelliteState.RESPONDING + + # Only return to idle once TTS is finished + entity.tts_response_finished() + state = hass.states.get(ENTITY_ID) + assert state.state == AssistSatelliteState.IDLE diff --git a/tests/components/august/snapshots/test_binary_sensor.ambr b/tests/components/august/snapshots/test_binary_sensor.ambr index 6e95b0ce552..be5947372f5 100644 --- a/tests/components/august/snapshots/test_binary_sensor.ambr +++ b/tests/components/august/snapshots/test_binary_sensor.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'tmt100_name', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://account.august.com', 'connections': set({ }), diff --git a/tests/components/august/snapshots/test_lock.ambr b/tests/components/august/snapshots/test_lock.ambr index 6aad3a140ca..0a594fed1ee 100644 --- a/tests/components/august/snapshots/test_lock.ambr +++ b/tests/components/august/snapshots/test_lock.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'online_with_doorsense_name', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://account.august.com', 'connections': set({ tuple( diff --git a/tests/components/autarco/snapshots/test_sensor.ambr b/tests/components/autarco/snapshots/test_sensor.ambr index dbbd8e9b47d..d57f4be5da0 100644 --- a/tests/components/autarco/snapshots/test_sensor.ambr +++ b/tests/components/autarco/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +372,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -416,6 +424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -467,6 +476,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -518,6 +528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -620,6 +632,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -671,6 +684,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -722,6 +736,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -773,6 +788,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/axis/snapshots/test_binary_sensor.ambr b/tests/components/axis/snapshots/test_binary_sensor.ambr index ab860489d55..6c0f3ead473 100644 --- a/tests/components/axis/snapshots/test_binary_sensor.ambr +++ b/tests/components/axis/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -382,6 +390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +486,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/axis/snapshots/test_camera.ambr b/tests/components/axis/snapshots/test_camera.ambr index 564ff96b3d8..1e70e2a799f 100644 --- a/tests/components/axis/snapshots/test_camera.ambr +++ b/tests/components/axis/snapshots/test_camera.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/axis/snapshots/test_diagnostics.ambr b/tests/components/axis/snapshots/test_diagnostics.ambr index ebd0061f416..b475c796d2b 100644 --- a/tests/components/axis/snapshots/test_diagnostics.ambr +++ b/tests/components/axis/snapshots/test_diagnostics.ambr @@ -47,6 +47,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 3, diff --git a/tests/components/axis/snapshots/test_hub.ambr b/tests/components/axis/snapshots/test_hub.ambr index 16579287f09..9e407bfef0b 100644 --- a/tests/components/axis/snapshots/test_hub.ambr +++ b/tests/components/axis/snapshots/test_hub.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://1.2.3.4:80', 'connections': set({ tuple( @@ -39,6 +40,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://1.2.3.4:80', 'connections': set({ tuple( diff --git a/tests/components/axis/snapshots/test_light.ambr b/tests/components/axis/snapshots/test_light.ambr index b37da39fe27..d8d01543ee5 100644 --- a/tests/components/axis/snapshots/test_light.ambr +++ b/tests/components/axis/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/axis/snapshots/test_switch.ambr b/tests/components/axis/snapshots/test_switch.ambr index dc4c75371cf..fa6091550e5 100644 --- a/tests/components/axis/snapshots/test_switch.ambr +++ b/tests/components/axis/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/azure_devops/snapshots/test_sensor.ambr b/tests/components/azure_devops/snapshots/test_sensor.ambr index aa8d1d9e7e0..0b8f35497c6 100644 --- a/tests/components/azure_devops/snapshots/test_sensor.ambr +++ b/tests/components/azure_devops/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -157,6 +160,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -204,6 +208,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -250,6 +255,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +302,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -388,6 +396,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -435,6 +444,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/backup/common.py b/tests/components/backup/common.py index 1e7278134d4..afdb5e47a2e 100644 --- a/tests/components/backup/common.py +++ b/tests/components/backup/common.py @@ -13,6 +13,7 @@ from homeassistant.components.backup import ( AgentBackup, BackupAgent, BackupAgentPlatformProtocol, + BackupNotFound, Folder, ) from homeassistant.components.backup.const import DATA_MANAGER @@ -134,6 +135,37 @@ class BackupAgentTest(BackupAgent): """Delete a backup file.""" +def mock_backup_agent(name: str, backups: list[AgentBackup] | None = None) -> Mock: + """Create a mock backup agent.""" + + async def get_backup(backup_id: str, **kwargs: Any) -> AgentBackup | None: + """Get a backup.""" + return next((b for b in backups if b.backup_id == backup_id), None) + + backups = backups or [] + mock_agent = Mock(spec=BackupAgent) + mock_agent.domain = "test" + mock_agent.name = name + mock_agent.unique_id = name + type(mock_agent).agent_id = BackupAgent.agent_id + mock_agent.async_delete_backup = AsyncMock( + spec_set=[BackupAgent.async_delete_backup] + ) + mock_agent.async_download_backup = AsyncMock( + side_effect=BackupNotFound, spec_set=[BackupAgent.async_download_backup] + ) + mock_agent.async_get_backup = AsyncMock( + side_effect=get_backup, spec_set=[BackupAgent.async_get_backup] + ) + mock_agent.async_list_backups = AsyncMock( + return_value=backups, spec_set=[BackupAgent.async_list_backups] + ) + mock_agent.async_upload_backup = AsyncMock( + spec_set=[BackupAgent.async_upload_backup] + ) + return mock_agent + + async def setup_backup_integration( hass: HomeAssistant, with_hassio: bool = False, diff --git a/tests/components/backup/snapshots/test_websocket.ambr b/tests/components/backup/snapshots/test_websocket.ambr index 421432fb66e..2f063262f34 100644 --- a/tests/components/backup/snapshots/test_websocket.ambr +++ b/tests/components/backup/snapshots/test_websocket.ambr @@ -3697,12 +3697,13 @@ # --- # name: test_delete_with_errors[side_effect1-storage_data0] dict({ - 'error': dict({ - 'code': 'home_assistant_error', - 'message': 'Boom!', - }), 'id': 1, - 'success': False, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Boom!', + }), + }), + 'success': True, 'type': 'result', }) # --- @@ -3757,12 +3758,13 @@ # --- # name: test_delete_with_errors[side_effect1-storage_data1] dict({ - 'error': dict({ - 'code': 'home_assistant_error', - 'message': 'Boom!', - }), 'id': 1, - 'success': False, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Boom!', + }), + }), + 'success': True, 'type': 'result', }) # --- @@ -4019,12 +4021,89 @@ # --- # name: test_details_with_errors[side_effect0] dict({ - 'error': dict({ - 'code': 'home_assistant_error', - 'message': 'Boom!', - }), 'id': 1, - 'success': False, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Oops', + }), + 'backup': dict({ + 'addons': list([ + dict({ + 'name': 'Test', + 'slug': 'test', + 'version': '1.0.0', + }), + ]), + 'agents': dict({ + 'backup.local': dict({ + 'protected': False, + 'size': 0, + }), + }), + 'backup_id': 'abc123', + 'database_included': True, + 'date': '1970-01-01T00:00:00.000Z', + 'extra_metadata': dict({ + 'instance_id': 'our_uuid', + 'with_automatic_settings': True, + }), + 'failed_agent_ids': list([ + ]), + 'folders': list([ + 'media', + 'share', + ]), + 'homeassistant_included': True, + 'homeassistant_version': '2024.12.0', + 'name': 'Test', + 'with_automatic_settings': True, + }), + }), + 'success': True, + 'type': 'result', + }) +# --- +# name: test_details_with_errors[side_effect1] + dict({ + 'id': 1, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Boom!', + }), + 'backup': dict({ + 'addons': list([ + dict({ + 'name': 'Test', + 'slug': 'test', + 'version': '1.0.0', + }), + ]), + 'agents': dict({ + 'backup.local': dict({ + 'protected': False, + 'size': 0, + }), + }), + 'backup_id': 'abc123', + 'database_included': True, + 'date': '1970-01-01T00:00:00.000Z', + 'extra_metadata': dict({ + 'instance_id': 'our_uuid', + 'with_automatic_settings': True, + }), + 'failed_agent_ids': list([ + ]), + 'folders': list([ + 'media', + 'share', + ]), + 'homeassistant_included': True, + 'homeassistant_version': '2024.12.0', + 'name': 'Test', + 'with_automatic_settings': True, + }), + }), + 'success': True, 'type': 'result', }) # --- @@ -4542,12 +4621,105 @@ # --- # name: test_info_with_errors[side_effect0] dict({ - 'error': dict({ - 'code': 'home_assistant_error', - 'message': 'Boom!', - }), 'id': 1, - 'success': False, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Oops', + }), + 'backups': list([ + dict({ + 'addons': list([ + dict({ + 'name': 'Test', + 'slug': 'test', + 'version': '1.0.0', + }), + ]), + 'agents': dict({ + 'backup.local': dict({ + 'protected': False, + 'size': 0, + }), + }), + 'backup_id': 'abc123', + 'database_included': True, + 'date': '1970-01-01T00:00:00.000Z', + 'extra_metadata': dict({ + 'instance_id': 'our_uuid', + 'with_automatic_settings': True, + }), + 'failed_agent_ids': list([ + ]), + 'folders': list([ + 'media', + 'share', + ]), + 'homeassistant_included': True, + 'homeassistant_version': '2024.12.0', + 'name': 'Test', + 'with_automatic_settings': True, + }), + ]), + 'last_attempted_automatic_backup': None, + 'last_completed_automatic_backup': None, + 'last_non_idle_event': None, + 'next_automatic_backup': None, + 'next_automatic_backup_additional': False, + 'state': 'idle', + }), + 'success': True, + 'type': 'result', + }) +# --- +# name: test_info_with_errors[side_effect1] + dict({ + 'id': 1, + 'result': dict({ + 'agent_errors': dict({ + 'domain.test': 'Boom!', + }), + 'backups': list([ + dict({ + 'addons': list([ + dict({ + 'name': 'Test', + 'slug': 'test', + 'version': '1.0.0', + }), + ]), + 'agents': dict({ + 'backup.local': dict({ + 'protected': False, + 'size': 0, + }), + }), + 'backup_id': 'abc123', + 'database_included': True, + 'date': '1970-01-01T00:00:00.000Z', + 'extra_metadata': dict({ + 'instance_id': 'our_uuid', + 'with_automatic_settings': True, + }), + 'failed_agent_ids': list([ + ]), + 'folders': list([ + 'media', + 'share', + ]), + 'homeassistant_included': True, + 'homeassistant_version': '2024.12.0', + 'name': 'Test', + 'with_automatic_settings': True, + }), + ]), + 'last_attempted_automatic_backup': None, + 'last_completed_automatic_backup': None, + 'last_non_idle_event': None, + 'next_automatic_backup': None, + 'next_automatic_backup_additional': False, + 'state': 'idle', + }), + 'success': True, 'type': 'result', }) # --- diff --git a/tests/components/backup/test_http.py b/tests/components/backup/test_http.py index 24fd15fc4fe..9ebf3e8bd40 100644 --- a/tests/components/backup/test_http.py +++ b/tests/components/backup/test_http.py @@ -25,6 +25,7 @@ from .common import ( TEST_BACKUP_ABC123, BackupAgentTest, aiter_from_iter, + mock_backup_agent, setup_backup_integration, ) @@ -112,16 +113,14 @@ async def test_downloading_local_encrypted_backup( await _test_downloading_encrypted_backup(hass_client, "backup.local") -@patch.object(BackupAgentTest, "async_download_backup") async def test_downloading_remote_encrypted_backup( - download_mock, hass: HomeAssistant, hass_client: ClientSessionGenerator, ) -> None: """Test downloading a local backup file.""" backup_path = get_fixture_path("test_backups/c0cb53bd.tar", DOMAIN) await setup_backup_integration(hass) - hass.data[DATA_MANAGER].backup_agents["domain.test"] = BackupAgentTest( + mock_agent = mock_backup_agent( "test", [ AgentBackup( @@ -139,11 +138,12 @@ async def test_downloading_remote_encrypted_backup( ) ], ) + hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent async def download_backup(backup_id: str, **kwargs: Any) -> AsyncIterator[bytes]: return aiter_from_iter((backup_path.read_bytes(),)) - download_mock.side_effect = download_backup + mock_agent.async_download_backup.side_effect = download_backup await _test_downloading_encrypted_backup(hass_client, "domain.test") @@ -154,9 +154,7 @@ async def test_downloading_remote_encrypted_backup( (BackupNotFound, 404), ], ) -@patch.object(BackupAgentTest, "async_download_backup") async def test_downloading_remote_encrypted_backup_with_error( - download_mock, hass: HomeAssistant, hass_client: ClientSessionGenerator, error: Exception, @@ -164,7 +162,7 @@ async def test_downloading_remote_encrypted_backup_with_error( ) -> None: """Test downloading a local backup file.""" await setup_backup_integration(hass) - hass.data[DATA_MANAGER].backup_agents["domain.test"] = BackupAgentTest( + mock_agent = mock_backup_agent( "test", [ AgentBackup( @@ -182,8 +180,9 @@ async def test_downloading_remote_encrypted_backup_with_error( ) ], ) + hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent - download_mock.side_effect = error + mock_agent.async_download_backup.side_effect = error client = await hass_client() resp = await client.get( "/api/backup/download/abc123?agent_id=domain.test&password=blah" diff --git a/tests/components/backup/test_websocket.py b/tests/components/backup/test_websocket.py index 5af6d595938..773256bdd0b 100644 --- a/tests/components/backup/test_websocket.py +++ b/tests/components/backup/test_websocket.py @@ -20,6 +20,7 @@ from homeassistant.components.backup import ( from homeassistant.components.backup.agent import BackupAgentUnreachableError from homeassistant.components.backup.const import DATA_MANAGER, DOMAIN from homeassistant.components.backup.manager import ( + AgentBackupStatus, CreateBackupEvent, CreateBackupState, ManagerBackup, @@ -98,15 +99,6 @@ def mock_delay_save() -> Generator[None]: yield -@pytest.fixture(name="delete_backup") -def mock_delete_backup() -> Generator[AsyncMock]: - """Mock manager delete backup.""" - with patch( - "homeassistant.components.backup.BackupManager.async_delete_backup" - ) as mock_delete_backup: - yield mock_delete_backup - - @pytest.fixture(name="get_backups") def mock_get_backups() -> Generator[AsyncMock]: """Mock manager get backups.""" @@ -148,7 +140,8 @@ async def test_info( @pytest.mark.parametrize( - "side_effect", [HomeAssistantError("Boom!"), BackupAgentUnreachableError] + "side_effect", + [Exception("Oops"), HomeAssistantError("Boom!"), BackupAgentUnreachableError], ) async def test_info_with_errors( hass: HomeAssistant, @@ -209,7 +202,8 @@ async def test_details( @pytest.mark.parametrize( - "side_effect", [HomeAssistantError("Boom!"), BackupAgentUnreachableError] + "side_effect", + [Exception("Oops"), HomeAssistantError("Boom!"), BackupAgentUnreachableError], ) async def test_details_with_errors( hass: HomeAssistant, @@ -907,7 +901,7 @@ async def test_agents_info( assert await client.receive_json() == snapshot -@pytest.mark.usefixtures("create_backup", "delete_backup", "get_backups") +@pytest.mark.usefixtures("get_backups") @pytest.mark.parametrize( "storage_data", [ @@ -1157,7 +1151,7 @@ async def test_config_info( assert await client.receive_json() == snapshot -@pytest.mark.usefixtures("create_backup", "delete_backup", "get_backups") +@pytest.mark.usefixtures("get_backups") @pytest.mark.parametrize( "commands", [ @@ -1322,7 +1316,7 @@ async def test_config_update( assert hass_storage[DOMAIN] == snapshot -@pytest.mark.usefixtures("create_backup", "delete_backup", "get_backups") +@pytest.mark.usefixtures("get_backups") @pytest.mark.parametrize( "command", [ @@ -1779,14 +1773,13 @@ async def test_config_schedule_logic( "command", "backups", "get_backups_agent_errors", - "delete_backup_agent_errors", + "agent_delete_backup_side_effects", "last_backup_time", "next_time", "backup_time", "backup_calls", "get_backups_calls", "delete_calls", - "delete_args_list", ), [ ( @@ -1798,21 +1791,25 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -1825,8 +1822,7 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, # we get backups even if backup retention copies is None - 0, - [], + {}, ), ( { @@ -1837,21 +1833,25 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -1864,8 +1864,7 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 0, - [], + {}, ), ( { @@ -1876,11 +1875,13 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, @@ -1893,8 +1894,7 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 0, - [], + {}, ), ( { @@ -1905,26 +1905,46 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -1937,38 +1957,59 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 1, - [call("backup-1")], + { + "test.test-agent": [call("backup-1")], + "test.test-agent2": [call("backup-1")], + }, ), ( { "type": "backup/config/update", "create_backup": {"agent_ids": ["test.test-agent"]}, - "retention": {"copies": 2, "days": None}, + "retention": {"copies": 3, "days": None}, "schedule": {"recurrence": "daily"}, }, { "backup-1": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -1981,8 +2022,10 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 2, - [call("backup-1"), call("backup-2")], + { + "test.test-agent": [call("backup-1")], + "test.test-agent2": [call("backup-1")], + }, ), ( { @@ -1993,35 +2036,44 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( - date="2024-11-10T04:45:00+01:00", + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( - date="2024-11-11T04:45:00+01:00", + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( - date="2024-11-12T04:45:00+01:00", + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-5": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, - {"test-agent": BackupAgentError("Boom!")}, + {}, {}, "2024-11-11T04:45:00+01:00", "2024-11-12T04:45:00+01:00", "2024-11-12T04:45:00+01:00", 1, 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1"), call("backup-2")]}, ), ( { @@ -2032,35 +2084,80 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=False, + spec=ManagerBackup, + ), + }, + {"test.test-agent": BackupAgentError("Boom!")}, + {}, + "2024-11-11T04:45:00+01:00", + "2024-11-12T04:45:00+01:00", + "2024-11-12T04:45:00+01:00", + 1, + 1, + {"test.test-agent": [call("backup-1")]}, + ), + ( + { + "type": "backup/config/update", + "create_backup": {"agent_ids": ["test.test-agent"]}, + "retention": {"copies": 2, "days": None}, + "schedule": {"recurrence": "daily"}, + }, + { + "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-10T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-11T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, {}, - {"test-agent": BackupAgentError("Boom!")}, + {"test.test-agent": BackupAgentError("Boom!")}, "2024-11-11T04:45:00+01:00", "2024-11-12T04:45:00+01:00", "2024-11-12T04:45:00+01:00", 1, 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( { @@ -2071,26 +2168,46 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2103,8 +2220,18 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 3, - [call("backup-1"), call("backup-2"), call("backup-3")], + { + "test.test-agent": [ + call("backup-1"), + call("backup-2"), + call("backup-3"), + ], + "test.test-agent2": [ + call("backup-1"), + call("backup-2"), + call("backup-3"), + ], + }, ), ( { @@ -2115,11 +2242,45 @@ async def test_config_schedule_logic( }, { "backup-1": MagicMock( - date="2024-11-12T04:45:00+01:00", + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, + date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, + date="2024-11-10T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-3": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, + date="2024-11-11T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-4": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + }, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-5": MagicMock( + agents={ + "test.test-agent": MagicMock(spec=AgentBackupStatus), + "test.test-agent2": MagicMock(spec=AgentBackupStatus), + }, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2132,8 +2293,44 @@ async def test_config_schedule_logic( "2024-11-12T04:45:00+01:00", 1, 1, - 0, - [], + { + "test.test-agent": [ + call("backup-1"), + call("backup-2"), + call("backup-3"), + ], + "test.test-agent2": [call("backup-1"), call("backup-2")], + }, + ), + ( + { + "type": "backup/config/update", + "create_backup": {"agent_ids": ["test.test-agent"]}, + "retention": {"copies": 0, "days": None}, + "schedule": {"recurrence": "daily"}, + }, + { + "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=True, + spec=ManagerBackup, + ), + "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, + date="2024-11-12T04:45:00+01:00", + with_automatic_settings=False, + spec=ManagerBackup, + ), + }, + {}, + {}, + "2024-11-11T04:45:00+01:00", + "2024-11-12T04:45:00+01:00", + "2024-11-12T04:45:00+01:00", + 1, + 1, + {}, ), ], ) @@ -2144,19 +2341,17 @@ async def test_config_retention_copies_logic( freezer: FrozenDateTimeFactory, hass_storage: dict[str, Any], create_backup: AsyncMock, - delete_backup: AsyncMock, get_backups: AsyncMock, command: dict[str, Any], backups: dict[str, Any], get_backups_agent_errors: dict[str, Exception], - delete_backup_agent_errors: dict[str, Exception], + agent_delete_backup_side_effects: dict[str, Exception], last_backup_time: str, next_time: str, backup_time: str, backup_calls: int, get_backups_calls: int, - delete_calls: int, - delete_args_list: Any, + delete_calls: dict[str, Any], ) -> None: """Test config backup retention copies logic.""" created_backup: MagicMock = create_backup.return_value[1].result().backup @@ -2194,13 +2389,18 @@ async def test_config_retention_copies_logic( "minor_version": store.STORAGE_VERSION_MINOR, } get_backups.return_value = (backups, get_backups_agent_errors) - delete_backup.return_value = delete_backup_agent_errors await hass.config.async_set_time_zone("Europe/Amsterdam") freezer.move_to("2024-11-11 12:00:00+01:00") - await setup_backup_integration(hass, remote_agents=["test-agent"]) + await setup_backup_integration(hass, remote_agents=["test-agent", "test-agent2"]) await hass.async_block_till_done() + manager = hass.data[DATA_MANAGER] + for agent_id, agent in manager.backup_agents.items(): + agent.async_delete_backup = AsyncMock( + side_effect=agent_delete_backup_side_effects.get(agent_id), autospec=True + ) + await client.send_json_auto_id(command) result = await client.receive_json() @@ -2211,8 +2411,10 @@ async def test_config_retention_copies_logic( await hass.async_block_till_done() assert create_backup.call_count == backup_calls assert get_backups.call_count == get_backups_calls - assert delete_backup.call_count == delete_calls - assert delete_backup.call_args_list == delete_args_list + for agent_id, agent in manager.backup_agents.items(): + agent_delete_calls = delete_calls.get(agent_id, []) + assert agent.async_delete_backup.call_count == len(agent_delete_calls) + assert agent.async_delete_backup.call_args_list == agent_delete_calls async_fire_time_changed(hass, fire_all=True) # flush out storage save await hass.async_block_till_done() assert ( @@ -2243,11 +2445,9 @@ async def test_config_retention_copies_logic( "config_command", "backups", "get_backups_agent_errors", - "delete_backup_agent_errors", "backup_calls", "get_backups_calls", "delete_calls", - "delete_args_list", ), [ ( @@ -2259,32 +2459,34 @@ async def test_config_retention_copies_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, {}, - {}, 1, 1, # we get backups even if backup retention copies is None - 0, - [], + {}, ), ( { @@ -2295,32 +2497,34 @@ async def test_config_retention_copies_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, {}, + 1, + 1, {}, - 1, - 1, - 0, - [], ), ( { @@ -2331,37 +2535,40 @@ async def test_config_retention_copies_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, {}, - {}, 1, 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( { @@ -2372,37 +2579,40 @@ async def test_config_retention_copies_logic( }, { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), }, {}, - {}, 1, 1, - 2, - [call("backup-1"), call("backup-2")], + {"test.test-agent": [call("backup-1"), call("backup-2")]}, ), ], ) @@ -2412,18 +2622,15 @@ async def test_config_retention_copies_logic_manual_backup( freezer: FrozenDateTimeFactory, hass_storage: dict[str, Any], create_backup: AsyncMock, - delete_backup: AsyncMock, get_backups: AsyncMock, config_command: dict[str, Any], backup_command: dict[str, Any], backups: dict[str, Any], get_backups_agent_errors: dict[str, Exception], - delete_backup_agent_errors: dict[str, Exception], backup_time: str, backup_calls: int, get_backups_calls: int, - delete_calls: int, - delete_args_list: Any, + delete_calls: dict[str, Any], ) -> None: """Test config backup retention copies logic for manual backup.""" created_backup: MagicMock = create_backup.return_value[1].result().backup @@ -2461,13 +2668,16 @@ async def test_config_retention_copies_logic_manual_backup( "minor_version": store.STORAGE_VERSION_MINOR, } get_backups.return_value = (backups, get_backups_agent_errors) - delete_backup.return_value = delete_backup_agent_errors await hass.config.async_set_time_zone("Europe/Amsterdam") freezer.move_to("2024-11-11 12:00:00+01:00") await setup_backup_integration(hass, remote_agents=["test-agent"]) await hass.async_block_till_done() + manager = hass.data[DATA_MANAGER] + for agent in manager.backup_agents.values(): + agent.async_delete_backup = AsyncMock(autospec=True) + await client.send_json_auto_id(config_command) result = await client.receive_json() assert result["success"] @@ -2482,8 +2692,10 @@ async def test_config_retention_copies_logic_manual_backup( assert create_backup.call_count == backup_calls assert get_backups.call_count == get_backups_calls - assert delete_backup.call_count == delete_calls - assert delete_backup.call_args_list == delete_args_list + for agent_id, agent in manager.backup_agents.items(): + agent_delete_calls = delete_calls.get(agent_id, []) + assert agent.async_delete_backup.call_count == len(agent_delete_calls) + assert agent.async_delete_backup.call_args_list == agent_delete_calls async_fire_time_changed(hass, fire_all=True) # flush out storage save await hass.async_block_till_done() assert ( @@ -2502,13 +2714,12 @@ async def test_config_retention_copies_logic_manual_backup( "commands", "backups", "get_backups_agent_errors", - "delete_backup_agent_errors", + "agent_delete_backup_side_effects", "last_backup_time", "start_time", "next_time", "get_backups_calls", "delete_calls", - "delete_args_list", ), [ # No config update - cleanup backups older than 2 days @@ -2517,16 +2728,19 @@ async def test_config_retention_copies_logic_manual_backup( [], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2538,8 +2752,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), # No config update - No cleanup ( @@ -2547,16 +2760,19 @@ async def test_config_retention_copies_logic_manual_backup( [], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2568,8 +2784,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 0, - 0, - [], + {}, ), # Unchanged config ( @@ -2584,16 +2799,19 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2605,8 +2823,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( None, @@ -2620,16 +2837,19 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2641,8 +2861,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( None, @@ -2656,16 +2875,19 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2677,8 +2899,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 0, - [], + {}, ), ( None, @@ -2692,21 +2913,25 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2718,8 +2943,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 2, - [call("backup-1"), call("backup-2")], + {"test.test-agent": [call("backup-1"), call("backup-2")]}, ), ( None, @@ -2733,16 +2957,19 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2754,8 +2981,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( None, @@ -2769,16 +2995,19 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2790,8 +3019,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 1, - [call("backup-1")], + {"test.test-agent": [call("backup-1")]}, ), ( None, @@ -2805,21 +3033,25 @@ async def test_config_retention_copies_logic_manual_backup( ], { "backup-1": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-09T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"test.test-agent": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, @@ -2831,8 +3063,7 @@ async def test_config_retention_copies_logic_manual_backup( "2024-11-11T12:00:00+01:00", "2024-11-12T12:00:00+01:00", 1, - 2, - [call("backup-1"), call("backup-2")], + {"test.test-agent": [call("backup-1"), call("backup-2")]}, ), ], ) @@ -2841,19 +3072,17 @@ async def test_config_retention_days_logic( hass_ws_client: WebSocketGenerator, freezer: FrozenDateTimeFactory, hass_storage: dict[str, Any], - delete_backup: AsyncMock, get_backups: AsyncMock, stored_retained_days: int | None, commands: list[dict[str, Any]], backups: dict[str, Any], get_backups_agent_errors: dict[str, Exception], - delete_backup_agent_errors: dict[str, Exception], + agent_delete_backup_side_effects: dict[str, Exception], last_backup_time: str, start_time: str, next_time: str, get_backups_calls: int, - delete_calls: int, - delete_args_list: list[Any], + delete_calls: dict[str, Any], ) -> None: """Test config backup retention logic.""" client = await hass_ws_client(hass) @@ -2888,13 +3117,18 @@ async def test_config_retention_days_logic( "minor_version": store.STORAGE_VERSION_MINOR, } get_backups.return_value = (backups, get_backups_agent_errors) - delete_backup.return_value = delete_backup_agent_errors await hass.config.async_set_time_zone("Europe/Amsterdam") freezer.move_to(start_time) - await setup_backup_integration(hass) + await setup_backup_integration(hass, remote_agents=["test-agent"]) await hass.async_block_till_done() + manager = hass.data[DATA_MANAGER] + for agent_id, agent in manager.backup_agents.items(): + agent.async_delete_backup = AsyncMock( + side_effect=agent_delete_backup_side_effects.get(agent_id), autospec=True + ) + for command in commands: await client.send_json_auto_id(command) result = await client.receive_json() @@ -2904,8 +3138,10 @@ async def test_config_retention_days_logic( async_fire_time_changed(hass) await hass.async_block_till_done() assert get_backups.call_count == get_backups_calls - assert delete_backup.call_count == delete_calls - assert delete_backup.call_args_list == delete_args_list + for agent_id, agent in manager.backup_agents.items(): + agent_delete_calls = delete_calls.get(agent_id, []) + assert agent.async_delete_backup.call_count == len(agent_delete_calls) + assert agent.async_delete_backup.call_args_list == agent_delete_calls async_fire_time_changed(hass, fire_all=True) # flush out storage save await hass.async_block_till_done() diff --git a/tests/components/balboa/snapshots/test_binary_sensor.ambr b/tests/components/balboa/snapshots/test_binary_sensor.ambr index c37c8a20d4b..4aa0f1d71fe 100644 --- a/tests/components/balboa/snapshots/test_binary_sensor.ambr +++ b/tests/components/balboa/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/balboa/snapshots/test_climate.ambr b/tests/components/balboa/snapshots/test_climate.ambr index d3060077341..70e33c4065f 100644 --- a/tests/components/balboa/snapshots/test_climate.ambr +++ b/tests/components/balboa/snapshots/test_climate.ambr @@ -17,6 +17,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/balboa/snapshots/test_fan.ambr b/tests/components/balboa/snapshots/test_fan.ambr index 8d35ab6de7c..4df73c3178c 100644 --- a/tests/components/balboa/snapshots/test_fan.ambr +++ b/tests/components/balboa/snapshots/test_fan.ambr @@ -8,6 +8,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/balboa/snapshots/test_light.ambr b/tests/components/balboa/snapshots/test_light.ambr index 31777744740..fdfd7af1d0c 100644 --- a/tests/components/balboa/snapshots/test_light.ambr +++ b/tests/components/balboa/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/balboa/snapshots/test_select.ambr b/tests/components/balboa/snapshots/test_select.ambr index a0cfd68d009..68368bf3602 100644 --- a/tests/components/balboa/snapshots/test_select.ambr +++ b/tests/components/balboa/snapshots/test_select.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bang_olufsen/snapshots/test_diagnostics.ambr b/tests/components/bang_olufsen/snapshots/test_diagnostics.ambr index e9540b5cec6..d7f9a045921 100644 --- a/tests/components/bang_olufsen/snapshots/test_diagnostics.ambr +++ b/tests/components/bang_olufsen/snapshots/test_diagnostics.ambr @@ -18,6 +18,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Beosound Balance-11111111', 'unique_id': '11111111', 'version': 1, diff --git a/tests/components/binary_sensor/test_init.py b/tests/components/binary_sensor/test_init.py index 26b8d919d72..de2b2565fe1 100644 --- a/tests/components/binary_sensor/test_init.py +++ b/tests/components/binary_sensor/test_init.py @@ -9,7 +9,7 @@ from homeassistant.components import binary_sensor from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.const import STATE_OFF, STATE_ON, EntityCategory from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .common import MockBinarySensor @@ -102,7 +102,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test binary_sensor platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) @@ -172,7 +172,7 @@ async def test_entity_category_config_raises_error( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test binary_sensor platform via config entry.""" async_add_entities([entity1, entity2]) diff --git a/tests/components/blink/snapshots/test_diagnostics.ambr b/tests/components/blink/snapshots/test_diagnostics.ambr index edc2879a66b..54df2b48cdb 100644 --- a/tests/components/blink/snapshots/test_diagnostics.ambr +++ b/tests/components/blink/snapshots/test_diagnostics.ambr @@ -48,6 +48,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 3, diff --git a/tests/components/bluemaestro/snapshots/test_sensor.ambr b/tests/components/bluemaestro/snapshots/test_sensor.ambr index 2b777ec6f09..48f20aa97b5 100644 --- a/tests/components/bluemaestro/snapshots/test_sensor.ambr +++ b/tests/components/bluemaestro/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_binary_sensor.ambr b/tests/components/bmw_connected_drive/snapshots/test_binary_sensor.ambr index c0462279e59..569d39c1a5a 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_binary_sensor.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -200,6 +204,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -248,6 +253,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -302,6 +308,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -348,6 +355,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -397,6 +405,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -444,6 +453,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -492,6 +502,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -550,6 +561,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -597,6 +609,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -645,6 +658,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -698,6 +712,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -744,6 +759,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -796,6 +812,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -843,6 +860,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -891,6 +909,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -949,6 +968,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -996,6 +1016,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1044,6 +1065,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1098,6 +1120,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1144,6 +1167,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1196,6 +1220,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1245,6 +1270,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1306,6 +1332,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1354,6 +1381,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1407,6 +1435,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_button.ambr b/tests/components/bmw_connected_drive/snapshots/test_button.ambr index f38441125ce..5072b918d2e 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_button.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -374,6 +382,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -420,6 +429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -466,6 +476,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -512,6 +523,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +570,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -604,6 +617,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -650,6 +664,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -696,6 +711,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -742,6 +758,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -788,6 +805,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -834,6 +852,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_lock.ambr b/tests/components/bmw_connected_drive/snapshots/test_lock.ambr index 395c6e56dda..3dc4e59b7b1 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_lock.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_number.ambr b/tests/components/bmw_connected_drive/snapshots/test_number.ambr index 71dbc46b454..866e52e7982 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_number.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_select.ambr b/tests/components/bmw_connected_drive/snapshots/test_select.ambr index b827dfe478a..de76b07057e 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_select.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -79,6 +80,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +149,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -214,6 +217,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +286,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr b/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr index 624b2c6007f..230025fc865 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -166,6 +169,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -227,6 +231,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -279,6 +284,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +339,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -387,6 +394,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -441,6 +449,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -494,6 +503,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -548,6 +558,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -602,6 +613,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -654,6 +666,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -705,6 +718,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -752,6 +766,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -814,6 +829,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -875,6 +891,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -933,6 +950,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -989,6 +1007,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1046,6 +1065,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1103,6 +1123,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1160,6 +1181,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1217,6 +1239,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1271,6 +1294,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1328,6 +1352,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1385,6 +1410,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1442,6 +1468,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1499,6 +1526,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1553,6 +1581,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1607,6 +1636,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1659,6 +1689,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1710,6 +1741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1757,6 +1789,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1819,6 +1852,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1880,6 +1914,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1938,6 +1973,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1994,6 +2030,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2051,6 +2088,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2108,6 +2146,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2165,6 +2204,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2222,6 +2262,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2276,6 +2317,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2333,6 +2375,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2390,6 +2433,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2447,6 +2491,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2504,6 +2549,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2558,6 +2604,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2612,6 +2659,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2672,6 +2720,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2728,6 +2777,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2785,6 +2835,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2842,6 +2893,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2899,6 +2951,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2956,6 +3009,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3010,6 +3064,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3067,6 +3122,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3124,6 +3180,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3181,6 +3238,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3238,6 +3296,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3292,6 +3351,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3345,6 +3405,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3399,6 +3460,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bmw_connected_drive/snapshots/test_switch.ambr b/tests/components/bmw_connected_drive/snapshots/test_switch.ambr index 5b60a32c3be..ce6ebc21f51 100644 --- a/tests/components/bmw_connected_drive/snapshots/test_switch.ambr +++ b/tests/components/bmw_connected_drive/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/braviatv/snapshots/test_diagnostics.ambr b/tests/components/braviatv/snapshots/test_diagnostics.ambr index cd29c647df7..de76c00cd23 100644 --- a/tests/components/braviatv/snapshots/test_diagnostics.ambr +++ b/tests/components/braviatv/snapshots/test_diagnostics.ambr @@ -19,6 +19,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'very_unique_string', 'version': 1, diff --git a/tests/components/bring/snapshots/test_event.ambr b/tests/components/bring/snapshots/test_event.ambr index 907467bd6bb..0bcdcb5b565 100644 --- a/tests/components/bring/snapshots/test_event.ambr +++ b/tests/components/bring/snapshots/test_event.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -95,6 +96,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bring/snapshots/test_sensor.ambr b/tests/components/bring/snapshots/test_sensor.ambr index 97e1d1b4bd9..eb307d31396 100644 --- a/tests/components/bring/snapshots/test_sensor.ambr +++ b/tests/components/bring/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -181,6 +184,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -250,6 +254,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -297,6 +302,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -350,6 +356,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -402,6 +409,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -472,6 +480,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -541,6 +550,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bring/snapshots/test_todo.ambr b/tests/components/bring/snapshots/test_todo.ambr index 6a7104727a1..46146415bf6 100644 --- a/tests/components/bring/snapshots/test_todo.ambr +++ b/tests/components/bring/snapshots/test_todo.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/brother/snapshots/test_sensor.ambr b/tests/components/brother/snapshots/test_sensor.ambr index 4de85859461..847ea0a2c6b 100644 --- a/tests/components/brother/snapshots/test_sensor.ambr +++ b/tests/components/brother/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -308,6 +314,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -358,6 +365,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -408,6 +416,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -458,6 +467,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -508,6 +518,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +569,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -608,6 +620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -658,6 +671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -708,6 +722,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -758,6 +773,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -806,6 +822,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -855,6 +872,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -905,6 +923,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -955,6 +974,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1005,6 +1025,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1055,6 +1076,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1105,6 +1127,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1153,6 +1176,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1201,6 +1225,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1251,6 +1276,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1301,6 +1327,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1351,6 +1378,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bryant_evolution/snapshots/test_climate.ambr b/tests/components/bryant_evolution/snapshots/test_climate.ambr index 4f6c1f2bbc4..3aeaf66329f 100644 --- a/tests/components/bryant_evolution/snapshots/test_climate.ambr +++ b/tests/components/bryant_evolution/snapshots/test_climate.ambr @@ -21,6 +21,7 @@ 'min_temp': 45, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bsblan/snapshots/test_climate.ambr b/tests/components/bsblan/snapshots/test_climate.ambr index 16828fea752..70d13f1cb95 100644 --- a/tests/components/bsblan/snapshots/test_climate.ambr +++ b/tests/components/bsblan/snapshots/test_climate.ambr @@ -18,6 +18,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -91,6 +92,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bsblan/snapshots/test_sensor.ambr b/tests/components/bsblan/snapshots/test_sensor.ambr index 0146dd23b3d..df7ceecc957 100644 --- a/tests/components/bsblan/snapshots/test_sensor.ambr +++ b/tests/components/bsblan/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/bsblan/snapshots/test_water_heater.ambr b/tests/components/bsblan/snapshots/test_water_heater.ambr index c1a13b764c0..37fdb14aca9 100644 --- a/tests/components/bsblan/snapshots/test_water_heater.ambr +++ b/tests/components/bsblan/snapshots/test_water_heater.ambr @@ -14,6 +14,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/button/conftest.py b/tests/components/button/conftest.py index 75d5509efc9..0784aa09963 100644 --- a/tests/components/button/conftest.py +++ b/tests/components/button/conftest.py @@ -6,7 +6,7 @@ import pytest from homeassistant.components.button import DOMAIN, ButtonEntity from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import TEST_DOMAIN @@ -31,7 +31,7 @@ async def setup_platform(hass: HomeAssistant) -> None: async def async_setup_platform( hass: HomeAssistant, config: ConfigType, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up test button platform.""" diff --git a/tests/components/button/test_init.py b/tests/components/button/test_init.py index 7df5308e096..783fd786a50 100644 --- a/tests/components/button/test_init.py +++ b/tests/components/button/test_init.py @@ -22,7 +22,7 @@ from homeassistant.const import ( STATE_UNKNOWN, ) from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -175,7 +175,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test button platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) diff --git a/tests/components/calendar/conftest.py b/tests/components/calendar/conftest.py index 3e18f595764..5bf061591ee 100644 --- a/tests/components/calendar/conftest.py +++ b/tests/components/calendar/conftest.py @@ -12,7 +12,7 @@ from homeassistant.components.calendar import DOMAIN, CalendarEntity, CalendarEv from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from tests.common import ( @@ -145,7 +145,7 @@ def mock_setup_integration( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test event platform via config entry.""" new_entities = create_test_entities() diff --git a/tests/components/cambridge_audio/snapshots/test_init.ambr b/tests/components/cambridge_audio/snapshots/test_init.ambr index 64182ee2188..7f4bbed36f7 100644 --- a/tests/components/cambridge_audio/snapshots/test_init.ambr +++ b/tests/components/cambridge_audio/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.20.218', 'connections': set({ }), @@ -30,4 +31,4 @@ 'sw_version': None, 'via_device_id': None, }) -# --- \ No newline at end of file +# --- diff --git a/tests/components/cambridge_audio/snapshots/test_select.ambr b/tests/components/cambridge_audio/snapshots/test_select.ambr index b40c8a8d5c4..8c9801b101b 100644 --- a/tests/components/cambridge_audio/snapshots/test_select.ambr +++ b/tests/components/cambridge_audio/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/cambridge_audio/snapshots/test_switch.ambr b/tests/components/cambridge_audio/snapshots/test_switch.ambr index 9bfcd7c6da7..cd4326fdcc3 100644 --- a/tests/components/cambridge_audio/snapshots/test_switch.ambr +++ b/tests/components/cambridge_audio/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ccm15/snapshots/test_climate.ambr b/tests/components/ccm15/snapshots/test_climate.ambr index 27dcbcb3405..a3cda75463f 100644 --- a/tests/components/ccm15/snapshots/test_climate.ambr +++ b/tests/components/ccm15/snapshots/test_climate.ambr @@ -28,6 +28,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -83,6 +84,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +220,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -273,6 +276,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/chacon_dio/snapshots/test_cover.ambr b/tests/components/chacon_dio/snapshots/test_cover.ambr index b2febe20070..afac3359410 100644 --- a/tests/components/chacon_dio/snapshots/test_cover.ambr +++ b/tests/components/chacon_dio/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/chacon_dio/snapshots/test_switch.ambr b/tests/components/chacon_dio/snapshots/test_switch.ambr index 7a65dad5445..a2620005531 100644 --- a/tests/components/chacon_dio/snapshots/test_switch.ambr +++ b/tests/components/chacon_dio/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/climate/test_init.py b/tests/components/climate/test_init.py index 45570c63008..8900a9faefa 100644 --- a/tests/components/climate/test_init.py +++ b/tests/components/climate/test_init.py @@ -42,7 +42,7 @@ from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTempera from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import issue_registry as ir -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -582,7 +582,7 @@ async def test_issue_aux_property_deprecated( async def async_setup_entry_climate_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test weather platform via config entry.""" async_add_entities([climate_entity]) diff --git a/tests/components/climate/test_intent.py b/tests/components/climate/test_intent.py index 00ab2f8d278..65d607e618b 100644 --- a/tests/components/climate/test_intent.py +++ b/tests/components/climate/test_intent.py @@ -24,7 +24,7 @@ from homeassistant.helpers import ( floor_registry as fr, intent, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_setup_component from tests.common import ( @@ -90,7 +90,7 @@ async def create_mock_platform( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test event platform via config entry.""" async_add_entities(entities) diff --git a/tests/components/co2signal/snapshots/test_diagnostics.ambr b/tests/components/co2signal/snapshots/test_diagnostics.ambr index 9218e7343ec..4159c8ec1a1 100644 --- a/tests/components/co2signal/snapshots/test_diagnostics.ambr +++ b/tests/components/co2signal/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/co2signal/snapshots/test_sensor.ambr b/tests/components/co2signal/snapshots/test_sensor.ambr index 3702521e4c3..1e241735102 100644 --- a/tests/components/co2signal/snapshots/test_sensor.ambr +++ b/tests/components/co2signal/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -60,6 +61,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/coinbase/snapshots/test_diagnostics.ambr b/tests/components/coinbase/snapshots/test_diagnostics.ambr index 51bd946f140..3eab18fb9f3 100644 --- a/tests/components/coinbase/snapshots/test_diagnostics.ambr +++ b/tests/components/coinbase/snapshots/test_diagnostics.ambr @@ -44,6 +44,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': None, 'version': 1, diff --git a/tests/components/comelit/snapshots/test_diagnostics.ambr b/tests/components/comelit/snapshots/test_diagnostics.ambr index 58ce74035f9..877f48a4611 100644 --- a/tests/components/comelit/snapshots/test_diagnostics.ambr +++ b/tests/components/comelit/snapshots/test_diagnostics.ambr @@ -71,6 +71,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, @@ -135,6 +137,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/config/test_config_entries.py b/tests/components/config/test_config_entries.py index f5241f65200..28161c0182c 100644 --- a/tests/components/config/test_config_entries.py +++ b/tests/components/config/test_config_entries.py @@ -1,6 +1,5 @@ """Test config entries API.""" -from collections import OrderedDict from collections.abc import Generator from http import HTTPStatus from typing import Any @@ -139,11 +138,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supported_subentry_types": {}, "supports_options": True, "supports_reconfigure": False, "supports_remove_device": False, @@ -157,11 +158,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": "Unsupported API", "source": "bla2", "state": core_ce.ConfigEntryState.SETUP_ERROR.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -175,11 +178,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -193,11 +198,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla4", "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -211,11 +218,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla5", "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -401,9 +410,10 @@ async def test_initialize_flow(hass: HomeAssistant, client: TestClient) -> None: class TestFlow(core_ce.ConfigFlow): async def async_step_user(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("username")] = str - schema[vol.Required("password")] = str + schema = { + vol.Required("username"): str, + vol.Required("password"): str, + } return self.async_show_form( step_id="user", @@ -483,13 +493,14 @@ async def test_initialize_flow_unauth( class TestFlow(core_ce.ConfigFlow): async def async_step_user(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("username")] = str - schema[vol.Required("password")] = str + schema = { + vol.Required("username"): str, + vol.Required("password"): str, + } return self.async_show_form( step_id="user", - data_schema=schema, + data_schema=vol.Schema(schema), description_placeholders={"url": "https://example.com"}, errors={"username": "Should be unique."}, ) @@ -530,7 +541,7 @@ async def test_abort(hass: HomeAssistant, client: TestClient) -> None: } -@pytest.mark.usefixtures("enable_custom_integrations", "freezer") +@pytest.mark.usefixtures("freezer") async def test_create_account(hass: HomeAssistant, client: TestClient) -> None: """Test a flow that creates an account.""" mock_platform(hass, "test.config_flow", None) @@ -573,11 +584,13 @@ async def test_create_account(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": core_ce.SOURCE_USER, "state": core_ce.ConfigEntryState.LOADED.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -588,10 +601,11 @@ async def test_create_account(hass: HomeAssistant, client: TestClient) -> None: "description_placeholders": None, "options": {}, "minor_version": 1, + "subentries": [], } -@pytest.mark.usefixtures("enable_custom_integrations", "freezer") +@pytest.mark.usefixtures("freezer") async def test_two_step_flow(hass: HomeAssistant, client: TestClient) -> None: """Test we can finish a two step flow.""" mock_integration( @@ -656,11 +670,13 @@ async def test_two_step_flow(hass: HomeAssistant, client: TestClient) -> None: "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": core_ce.SOURCE_USER, "state": core_ce.ConfigEntryState.LOADED.value, + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -671,6 +687,7 @@ async def test_two_step_flow(hass: HomeAssistant, client: TestClient) -> None: "description_placeholders": None, "options": {}, "minor_version": 1, + "subentries": [], } @@ -819,9 +836,10 @@ async def test_get_progress_flow(hass: HomeAssistant, client: TestClient) -> Non class TestFlow(core_ce.ConfigFlow): async def async_step_user(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("username")] = str - schema[vol.Required("password")] = str + schema = { + vol.Required("username"): str, + vol.Required("password"): str, + } return self.async_show_form( step_id="user", @@ -857,9 +875,10 @@ async def test_get_progress_flow_unauth( class TestFlow(core_ce.ConfigFlow): async def async_step_user(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("username")] = str - schema[vol.Required("password")] = str + schema = { + vol.Required("username"): str, + vol.Required("password"): str, + } return self.async_show_form( step_id="user", @@ -891,11 +910,9 @@ async def test_options_flow(hass: HomeAssistant, client: TestClient) -> None: def async_get_options_flow(config_entry): class OptionsFlowHandler(data_entry_flow.FlowHandler): async def async_step_init(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("enabled")] = bool return self.async_show_form( step_id="user", - data_schema=vol.Schema(schema), + data_schema=vol.Schema({vol.Required("enabled"): bool}), description_placeholders={"enabled": "Set to true to be true"}, ) @@ -956,11 +973,9 @@ async def test_options_flow_unauth( def async_get_options_flow(config_entry): class OptionsFlowHandler(data_entry_flow.FlowHandler): async def async_step_init(self, user_input=None): - schema = OrderedDict() - schema[vol.Required("enabled")] = bool return self.async_show_form( step_id="user", - data_schema=schema, + data_schema=vol.Schema({vol.Required("enabled"): bool}), description_placeholders={"enabled": "Set to true to be true"}, ) @@ -1125,6 +1140,320 @@ async def test_options_flow_with_invalid_data( assert data == {"errors": {"choices": "invalid is not a valid option"}} +async def test_subentry_flow(hass: HomeAssistant, client) -> None: + """Test we can start a subentry flow.""" + + class TestFlow(core_ce.ConfigFlow): + class SubentryFlowHandler(core_ce.ConfigSubentryFlow): + async def async_step_init(self, user_input=None): + raise NotImplementedError + + async def async_step_user(self, user_input=None): + return self.async_show_form( + step_id="user", + data_schema=vol.Schema({vol.Required("enabled"): bool}), + description_placeholders={"enabled": "Set to true to be true"}, + ) + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: core_ce.ConfigEntry + ) -> dict[str, type[core_ce.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + MockConfigEntry( + domain="test", + entry_id="test1", + source="bla", + ).add_to_hass(hass) + entry = hass.config_entries.async_entries()[0] + + with mock_config_flow("test", TestFlow): + url = "/api/config/config_entries/subentries/flow" + resp = await client.post(url, json={"handler": [entry.entry_id, "test"]}) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + data.pop("flow_id") + assert data == { + "type": "form", + "handler": ["test1", "test"], + "step_id": "user", + "data_schema": [{"name": "enabled", "required": True, "type": "boolean"}], + "description_placeholders": {"enabled": "Set to true to be true"}, + "errors": None, + "last_step": None, + "preview": None, + } + + +async def test_subentry_reconfigure_flow(hass: HomeAssistant, client) -> None: + """Test we can start a subentry reconfigure flow.""" + + class TestFlow(core_ce.ConfigFlow): + class SubentryFlowHandler(core_ce.ConfigSubentryFlow): + async def async_step_init(self, user_input=None): + raise NotImplementedError + + async def async_step_user(self, user_input=None): + raise NotImplementedError + + async def async_step_reconfigure(self, user_input=None): + return self.async_show_form( + step_id="reconfigure", + data_schema=vol.Schema({vol.Required("enabled"): bool}), + description_placeholders={"enabled": "Set to true to be true"}, + ) + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: core_ce.ConfigEntry + ) -> dict[str, type[core_ce.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + MockConfigEntry( + domain="test", + entry_id="test1", + source="bla", + subentries_data=[ + core_ce.ConfigSubentryData( + data={}, + subentry_id="mock_id", + subentry_type="test", + title="Title", + unique_id=None, + ) + ], + ).add_to_hass(hass) + entry = hass.config_entries.async_entries()[0] + + with mock_config_flow("test", TestFlow): + url = "/api/config/config_entries/subentries/flow" + resp = await client.post( + url, json={"handler": [entry.entry_id, "test"], "subentry_id": "mock_id"} + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + data.pop("flow_id") + assert data == { + "type": "form", + "handler": ["test1", "test"], + "step_id": "reconfigure", + "data_schema": [{"name": "enabled", "required": True, "type": "boolean"}], + "description_placeholders": {"enabled": "Set to true to be true"}, + "errors": None, + "last_step": None, + "preview": None, + } + + +@pytest.mark.parametrize( + ("endpoint", "method"), + [ + ("/api/config/config_entries/subentries/flow", "post"), + ("/api/config/config_entries/subentries/flow/1", "get"), + ("/api/config/config_entries/subentries/flow/1", "post"), + ], +) +async def test_subentry_flow_unauth( + hass: HomeAssistant, client, hass_admin_user: MockUser, endpoint: str, method: str +) -> None: + """Test unauthorized on subentry flow.""" + + class TestFlow(core_ce.ConfigFlow): + class SubentryFlowHandler(core_ce.ConfigSubentryFlow): + async def async_step_init(self, user_input=None): + return self.async_show_form( + step_id="user", + data_schema=vol.Schema({vol.Required("enabled"): bool}), + description_placeholders={"enabled": "Set to true to be true"}, + ) + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: core_ce.ConfigEntry + ) -> dict[str, type[core_ce.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + MockConfigEntry( + domain="test", + entry_id="test1", + source="bla", + ).add_to_hass(hass) + entry = hass.config_entries.async_entries()[0] + + hass_admin_user.groups = [] + + with mock_config_flow("test", TestFlow): + resp = await getattr(client, method)(endpoint, json={"handler": entry.entry_id}) + + assert resp.status == HTTPStatus.UNAUTHORIZED + + +async def test_two_step_subentry_flow(hass: HomeAssistant, client) -> None: + """Test we can finish a two step subentry flow.""" + mock_integration( + hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) + ) + mock_platform(hass, "test.config_flow", None) + + class TestFlow(core_ce.ConfigFlow): + class SubentryFlowHandler(core_ce.ConfigSubentryFlow): + async def async_step_user(self, user_input=None): + return await self.async_step_finish() + + async def async_step_finish(self, user_input=None): + if user_input: + return self.async_create_entry( + title="Mock title", data=user_input, unique_id="test" + ) + + return self.async_show_form( + step_id="finish", data_schema=vol.Schema({"enabled": bool}) + ) + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: core_ce.ConfigEntry + ) -> dict[str, type[core_ce.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + MockConfigEntry( + domain="test", + entry_id="test1", + source="bla", + ).add_to_hass(hass) + entry = hass.config_entries.async_entries()[0] + + with mock_config_flow("test", TestFlow): + url = "/api/config/config_entries/subentries/flow" + resp = await client.post(url, json={"handler": [entry.entry_id, "test"]}) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + flow_id = data["flow_id"] + expected_data = { + "data_schema": [{"name": "enabled", "type": "boolean"}], + "description_placeholders": None, + "errors": None, + "flow_id": flow_id, + "handler": ["test1", "test"], + "last_step": None, + "preview": None, + "step_id": "finish", + "type": "form", + } + assert data == expected_data + + resp = await client.get(f"/api/config/config_entries/subentries/flow/{flow_id}") + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert data == expected_data + + resp = await client.post( + f"/api/config/config_entries/subentries/flow/{flow_id}", + json={"enabled": True}, + ) + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert data == { + "description_placeholders": None, + "description": None, + "flow_id": flow_id, + "handler": ["test1", "test"], + "title": "Mock title", + "type": "create_entry", + "unique_id": "test", + } + + +async def test_subentry_flow_with_invalid_data(hass: HomeAssistant, client) -> None: + """Test a subentry flow with invalid_data.""" + mock_integration( + hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) + ) + mock_platform(hass, "test.config_flow", None) + + class TestFlow(core_ce.ConfigFlow): + class SubentryFlowHandler(core_ce.ConfigSubentryFlow): + async def async_step_user(self, user_input=None): + return self.async_show_form( + step_id="finish", + data_schema=vol.Schema( + { + vol.Required( + "choices", default=["invalid", "valid"] + ): cv.multi_select({"valid": "Valid"}) + } + ), + ) + + async def async_step_finish(self, user_input=None): + return self.async_create_entry(title="Enable disable", data=user_input) + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: core_ce.ConfigEntry + ) -> dict[str, type[core_ce.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + MockConfigEntry( + domain="test", + entry_id="test1", + source="bla", + ).add_to_hass(hass) + entry = hass.config_entries.async_entries()[0] + + with mock_config_flow("test", TestFlow): + url = "/api/config/config_entries/subentries/flow" + resp = await client.post(url, json={"handler": [entry.entry_id, "test"]}) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + flow_id = data.pop("flow_id") + assert data == { + "type": "form", + "handler": ["test1", "test"], + "step_id": "finish", + "data_schema": [ + { + "default": ["invalid", "valid"], + "name": "choices", + "options": {"valid": "Valid"}, + "required": True, + "type": "multi_select", + } + ], + "description_placeholders": None, + "errors": None, + "last_step": None, + "preview": None, + } + + with mock_config_flow("test", TestFlow): + resp = await client.post( + f"/api/config/config_entries/subentries/flow/{flow_id}", + json={"choices": ["valid", "invalid"]}, + ) + assert resp.status == HTTPStatus.BAD_REQUEST + data = await resp.json() + assert data == {"errors": {"choices": "invalid is not a valid option"}} + + @pytest.mark.usefixtures("freezer") async def test_get_single( hass: HomeAssistant, hass_ws_client: WebSocketGenerator @@ -1157,11 +1486,13 @@ async def test_get_single( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "user", "state": "loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1517,11 +1848,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1536,11 +1869,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": "Unsupported API", "source": "bla2", "state": "setup_error", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1555,11 +1890,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1574,11 +1911,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla4", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1593,11 +1932,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla5", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1623,11 +1964,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1652,11 +1995,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla4", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1671,11 +2016,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla5", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1700,11 +2047,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1719,11 +2068,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1754,11 +2105,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1773,11 +2126,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": "Unsupported API", "source": "bla2", "state": "setup_error", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1792,11 +2147,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1811,11 +2168,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla4", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1830,11 +2189,13 @@ async def test_get_matching_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": timestamp, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla5", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1937,11 +2298,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": created, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1959,11 +2322,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": created, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": "Unsupported API", "source": "bla2", "state": "setup_error", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -1981,11 +2346,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": created, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2009,11 +2376,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": modified, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2038,11 +2407,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": modified, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2066,11 +2437,13 @@ async def test_subscribe_entries_ws( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": entry.modified_at.timestamp(), + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2156,11 +2529,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": created, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2178,11 +2553,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": created, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2208,11 +2585,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": modified, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2234,11 +2613,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": modified, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla3", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2264,11 +2645,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": modified, + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2292,11 +2675,13 @@ async def test_subscribe_entries_ws_filtered( "error_reason_translation_key": None, "error_reason_translation_placeholders": None, "modified_at": entry.modified_at.timestamp(), + "num_subentries": 0, "pref_disable_new_entities": False, "pref_disable_polling": False, "reason": None, "source": "bla", "state": "not_loaded", + "supported_subentry_types": {}, "supports_options": False, "supports_reconfigure": False, "supports_remove_device": False, @@ -2400,7 +2785,7 @@ async def test_flow_with_multiple_schema_errors_base( "ignore_translations", ["component.test.config.abort.reconfigure_successful"], ) -@pytest.mark.usefixtures("enable_custom_integrations", "freezer") +@pytest.mark.usefixtures("freezer") async def test_supports_reconfigure( hass: HomeAssistant, client: TestClient, @@ -2476,7 +2861,6 @@ async def test_supports_reconfigure( } -@pytest.mark.usefixtures("enable_custom_integrations") async def test_does_not_support_reconfigure( hass: HomeAssistant, client: TestClient ) -> None: @@ -2502,8 +2886,144 @@ async def test_does_not_support_reconfigure( ) assert resp.status == HTTPStatus.BAD_REQUEST - response = await resp.text() - assert ( - response - == '{"message":"Handler ConfigEntriesFlowManager doesn\'t support step reconfigure"}' + response = await resp.json() + assert response == {"message": "Handler TestFlow doesn't support step reconfigure"} + + +async def test_list_subentries( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator +) -> None: + """Test that we can list subentries.""" + assert await async_setup_component(hass, "config", {}) + ws_client = await hass_ws_client(hass) + + entry = MockConfigEntry( + domain="test", + state=core_ce.ConfigEntryState.LOADED, + subentries_data=[ + core_ce.ConfigSubentryData( + data={"test": "test"}, + subentry_id="mock_id", + subentry_type="test", + title="Mock title", + unique_id="test", + ) + ], ) + entry.add_to_hass(hass) + + assert entry.pref_disable_new_entities is False + assert entry.pref_disable_polling is False + + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/list", + "entry_id": entry.entry_id, + } + ) + response = await ws_client.receive_json() + + assert response["success"] + assert response["result"] == [ + { + "subentry_id": "mock_id", + "subentry_type": "test", + "title": "Mock title", + "unique_id": "test", + }, + ] + + # Try listing subentries for an unknown entry + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/list", + "entry_id": "no_such_entry", + } + ) + response = await ws_client.receive_json() + + assert not response["success"] + assert response["error"] == { + "code": "not_found", + "message": "Config entry not found", + } + + +async def test_delete_subentry( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator +) -> None: + """Test that we can delete a subentry.""" + assert await async_setup_component(hass, "config", {}) + ws_client = await hass_ws_client(hass) + + entry = MockConfigEntry( + domain="test", + state=core_ce.ConfigEntryState.LOADED, + subentries_data=[ + core_ce.ConfigSubentryData( + data={"test": "test"}, + subentry_id="mock_id", + subentry_type="test", + title="Mock title", + ) + ], + ) + entry.add_to_hass(hass) + + assert entry.pref_disable_new_entities is False + assert entry.pref_disable_polling is False + + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/delete", + "entry_id": entry.entry_id, + "subentry_id": "mock_id", + } + ) + response = await ws_client.receive_json() + + assert response["success"] + assert response["result"] is None + + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/list", + "entry_id": entry.entry_id, + } + ) + response = await ws_client.receive_json() + + assert response["success"] + assert response["result"] == [] + + # Try deleting the subentry again + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/delete", + "entry_id": entry.entry_id, + "subentry_id": "mock_id", + } + ) + response = await ws_client.receive_json() + + assert not response["success"] + assert response["error"] == { + "code": "not_found", + "message": "Config subentry not found", + } + + # Try deleting subentry from an unknown entry + await ws_client.send_json_auto_id( + { + "type": "config_entries/subentries/delete", + "entry_id": "no_such_entry", + "subentry_id": "mock_id", + } + ) + response = await ws_client.receive_json() + + assert not response["success"] + assert response["error"] == { + "code": "not_found", + "message": "Config entry not found", + } diff --git a/tests/components/config/test_device_registry.py b/tests/components/config/test_device_registry.py index c840ce2bed2..8a4e1ef234f 100644 --- a/tests/components/config/test_device_registry.py +++ b/tests/components/config/test_device_registry.py @@ -65,6 +65,7 @@ async def test_list_devices( { "area_id": None, "config_entries": [entry.entry_id], + "config_entries_subentries": {entry.entry_id: [None]}, "configuration_url": None, "connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]], "created_at": utcnow().timestamp(), @@ -87,6 +88,7 @@ async def test_list_devices( { "area_id": None, "config_entries": [entry.entry_id], + "config_entries_subentries": {entry.entry_id: [None]}, "configuration_url": None, "connections": [], "created_at": utcnow().timestamp(), @@ -121,6 +123,7 @@ async def test_list_devices( { "area_id": None, "config_entries": [entry.entry_id], + "config_entries_subentries": {entry.entry_id: [None]}, "configuration_url": None, "connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]], "created_at": utcnow().timestamp(), diff --git a/tests/components/config/test_entity_registry.py b/tests/components/config/test_entity_registry.py index bfbd69ec9bd..2e3de33d808 100644 --- a/tests/components/config/test_entity_registry.py +++ b/tests/components/config/test_entity_registry.py @@ -67,6 +67,7 @@ async def test_list_entities( "area_id": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": utcnow().timestamp(), "device_id": None, "disabled_by": None, @@ -89,6 +90,7 @@ async def test_list_entities( "area_id": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": utcnow().timestamp(), "device_id": None, "disabled_by": None, @@ -138,6 +140,7 @@ async def test_list_entities( "area_id": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": utcnow().timestamp(), "device_id": None, "disabled_by": None, @@ -374,6 +377,7 @@ async def test_get_entity(hass: HomeAssistant, client: MockHAClientWebSocket) -> "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": name_created_at.timestamp(), "device_class": None, "device_id": None, @@ -410,6 +414,7 @@ async def test_get_entity(hass: HomeAssistant, client: MockHAClientWebSocket) -> "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": no_name_created_at.timestamp(), "device_class": None, "device_id": None, @@ -477,6 +482,7 @@ async def test_get_entities(hass: HomeAssistant, client: MockHAClientWebSocket) "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": name_created_at.timestamp(), "device_class": None, "device_id": None, @@ -504,6 +510,7 @@ async def test_get_entities(hass: HomeAssistant, client: MockHAClientWebSocket) "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": no_name_created_at.timestamp(), "device_class": None, "device_id": None, @@ -586,6 +593,7 @@ async def test_update_entity( "categories": {"scope1": "id", "scope2": "id"}, "created_at": created.timestamp(), "config_entry_id": None, + "config_subentry_id": None, "device_class": "custom_device_class", "device_id": None, "disabled_by": None, @@ -668,6 +676,7 @@ async def test_update_entity( "capabilities": None, "categories": {"scope1": "id", "scope2": "id"}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": "custom_device_class", "device_id": None, @@ -714,6 +723,7 @@ async def test_update_entity( "capabilities": None, "categories": {"scope1": "id", "scope2": "id"}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": "custom_device_class", "device_id": None, @@ -759,6 +769,7 @@ async def test_update_entity( "capabilities": None, "categories": {"scope1": "id", "scope2": "id", "scope3": "id"}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": "custom_device_class", "device_id": None, @@ -804,6 +815,7 @@ async def test_update_entity( "capabilities": None, "categories": {"scope1": "id", "scope2": "id", "scope3": "other_id"}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": "custom_device_class", "device_id": None, @@ -849,6 +861,7 @@ async def test_update_entity( "capabilities": None, "categories": {"scope1": "id", "scope3": "other_id"}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": "custom_device_class", "device_id": None, @@ -911,6 +924,7 @@ async def test_update_entity_require_restart( "capabilities": None, "categories": {}, "config_entry_id": config_entry.entry_id, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": None, "device_id": None, @@ -1032,6 +1046,7 @@ async def test_update_entity_no_changes( "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": None, "device_id": None, @@ -1129,6 +1144,7 @@ async def test_update_entity_id( "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": created.timestamp(), "device_class": None, "device_id": None, diff --git a/tests/components/conversation/__init__.py b/tests/components/conversation/__init__.py index 1ae3372968e..314188dbd82 100644 --- a/tests/components/conversation/__init__.py +++ b/tests/components/conversation/__init__.py @@ -2,7 +2,11 @@ from __future__ import annotations +from dataclasses import dataclass, field from typing import Literal +from unittest.mock import patch + +import pytest from homeassistant.components import conversation from homeassistant.components.conversation.models import ( @@ -14,7 +18,7 @@ from homeassistant.components.homeassistant.exposed_entities import ( async_expose_entity, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers import intent +from homeassistant.helpers import chat_session, intent class MockAgent(conversation.AbstractConversationAgent): @@ -44,6 +48,53 @@ class MockAgent(conversation.AbstractConversationAgent): ) +@pytest.fixture +async def mock_chat_log(hass: HomeAssistant) -> MockChatLog: + """Return mock chat logs.""" + # pylint: disable-next=contextmanager-generator-missing-cleanup + with ( + patch( + "homeassistant.components.conversation.chat_log.ChatLog", + MockChatLog, + ), + chat_session.async_get_chat_session(hass, "mock-conversation-id") as session, + conversation.async_get_chat_log(hass, session) as chat_log, + ): + yield chat_log + + +@dataclass +class MockChatLog(conversation.ChatLog): + """Mock chat log.""" + + _mock_tool_results: dict = field(default_factory=dict) + + def mock_tool_results(self, results: dict) -> None: + """Set tool results.""" + self._mock_tool_results = results + + @property + def llm_api(self): + """Return LLM API.""" + return self._llm_api + + @llm_api.setter + def llm_api(self, value): + """Set LLM API.""" + self._llm_api = value + + if not value: + return + + async def async_call_tool(tool_input): + """Call tool.""" + if tool_input.id not in self._mock_tool_results: + raise ValueError(f"Tool {tool_input.id} not found") + return self._mock_tool_results[tool_input.id] + + self._llm_api.async_call_tool = async_call_tool + + def expose_new(hass: HomeAssistant, expose_new: bool) -> None: """Enable exposing new entities to the default agent.""" exposed_entities = hass.data[DATA_EXPOSED_ENTITIES] diff --git a/tests/components/conversation/snapshots/test_chat_log.ambr b/tests/components/conversation/snapshots/test_chat_log.ambr index 4e94157c601..1ddbf68bb84 100644 --- a/tests/components/conversation/snapshots/test_chat_log.ambr +++ b/tests/components/conversation/snapshots/test_chat_log.ambr @@ -1,4 +1,154 @@ # serializer version: 1 +# name: test_add_delta_content_stream[deltas0] + list([ + ]) +# --- +# name: test_add_delta_content_stream[deltas1] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test', + 'role': 'assistant', + 'tool_calls': None, + }), + ]) +# --- +# name: test_add_delta_content_stream[deltas2] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test', + 'role': 'assistant', + 'tool_calls': None, + }), + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test 2', + 'role': 'assistant', + 'tool_calls': None, + }), + ]) +# --- +# name: test_add_delta_content_stream[deltas3] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': None, + 'role': 'assistant', + 'tool_calls': list([ + dict({ + 'id': 'mock-tool-call-id', + 'tool_args': dict({ + 'param1': 'Test Param 1', + }), + 'tool_name': 'test_tool', + }), + ]), + }), + dict({ + 'agent_id': 'mock-agent-id', + 'role': 'tool_result', + 'tool_call_id': 'mock-tool-call-id', + 'tool_name': 'test_tool', + 'tool_result': 'Test Param 1', + }), + ]) +# --- +# name: test_add_delta_content_stream[deltas4] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test', + 'role': 'assistant', + 'tool_calls': list([ + dict({ + 'id': 'mock-tool-call-id', + 'tool_args': dict({ + 'param1': 'Test Param 1', + }), + 'tool_name': 'test_tool', + }), + ]), + }), + dict({ + 'agent_id': 'mock-agent-id', + 'role': 'tool_result', + 'tool_call_id': 'mock-tool-call-id', + 'tool_name': 'test_tool', + 'tool_result': 'Test Param 1', + }), + ]) +# --- +# name: test_add_delta_content_stream[deltas5] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test', + 'role': 'assistant', + 'tool_calls': list([ + dict({ + 'id': 'mock-tool-call-id', + 'tool_args': dict({ + 'param1': 'Test Param 1', + }), + 'tool_name': 'test_tool', + }), + ]), + }), + dict({ + 'agent_id': 'mock-agent-id', + 'role': 'tool_result', + 'tool_call_id': 'mock-tool-call-id', + 'tool_name': 'test_tool', + 'tool_result': 'Test Param 1', + }), + dict({ + 'agent_id': 'mock-agent-id', + 'content': 'Test 2', + 'role': 'assistant', + 'tool_calls': None, + }), + ]) +# --- +# name: test_add_delta_content_stream[deltas6] + list([ + dict({ + 'agent_id': 'mock-agent-id', + 'content': None, + 'role': 'assistant', + 'tool_calls': list([ + dict({ + 'id': 'mock-tool-call-id', + 'tool_args': dict({ + 'param1': 'Test Param 1', + }), + 'tool_name': 'test_tool', + }), + dict({ + 'id': 'mock-tool-call-id-2', + 'tool_args': dict({ + 'param1': 'Test Param 2', + }), + 'tool_name': 'test_tool', + }), + ]), + }), + dict({ + 'agent_id': 'mock-agent-id', + 'role': 'tool_result', + 'tool_call_id': 'mock-tool-call-id', + 'tool_name': 'test_tool', + 'tool_result': 'Test Param 1', + }), + dict({ + 'agent_id': 'mock-agent-id', + 'role': 'tool_result', + 'tool_call_id': 'mock-tool-call-id-2', + 'tool_name': 'test_tool', + 'tool_result': 'Test Param 2', + }), + ]) +# --- # name: test_template_error dict({ 'conversation_id': , diff --git a/tests/components/conversation/test_chat_log.py b/tests/components/conversation/test_chat_log.py index 1f659b8005e..a4dc9b819c1 100644 --- a/tests/components/conversation/test_chat_log.py +++ b/tests/components/conversation/test_chat_log.py @@ -1,6 +1,7 @@ """Test the conversation session.""" from collections.abc import Generator +from dataclasses import asdict from datetime import timedelta from unittest.mock import AsyncMock, Mock, patch @@ -282,7 +283,7 @@ async def test_extra_systen_prompt( @pytest.mark.parametrize( "prerun_tool_tasks", [ - None, + (), ("mock-tool-call-id",), ("mock-tool-call-id", "mock-tool-call-id-2"), ], @@ -290,7 +291,7 @@ async def test_extra_systen_prompt( async def test_tool_call( hass: HomeAssistant, mock_conversation_input: ConversationInput, - prerun_tool_tasks: tuple[str] | None, + prerun_tool_tasks: tuple[str], ) -> None: """Test using the session tool calling API.""" @@ -334,15 +335,13 @@ async def test_tool_call( ], ) - tool_call_tasks = None - if prerun_tool_tasks: - tool_call_tasks = { - tool_call_id: hass.async_create_task( - chat_log.llm_api.async_call_tool(content.tool_calls[0]), - tool_call_id, - ) - for tool_call_id in prerun_tool_tasks - } + tool_call_tasks = { + tool_call_id: hass.async_create_task( + chat_log.llm_api.async_call_tool(content.tool_calls[0]), + tool_call_id, + ) + for tool_call_id in prerun_tool_tasks + } with pytest.raises(ValueError): chat_log.async_add_assistant_content_without_tools(content) @@ -350,7 +349,7 @@ async def test_tool_call( results = [ tool_result_content async for tool_result_content in chat_log.async_add_assistant_content( - content, tool_call_tasks=tool_call_tasks + content, tool_call_tasks=tool_call_tasks or None ) ] @@ -382,37 +381,36 @@ async def test_tool_call_exception( ) mock_tool.async_call.side_effect = HomeAssistantError("Test error") - with patch( - "homeassistant.helpers.llm.AssistAPI._async_get_tools", return_value=[] - ) as mock_get_tools: + with ( + patch( + "homeassistant.helpers.llm.AssistAPI._async_get_tools", return_value=[] + ) as mock_get_tools, + chat_session.async_get_chat_session(hass) as session, + async_get_chat_log(hass, session, mock_conversation_input) as chat_log, + ): mock_get_tools.return_value = [mock_tool] - - with ( - chat_session.async_get_chat_session(hass) as session, - async_get_chat_log(hass, session, mock_conversation_input) as chat_log, - ): - await chat_log.async_update_llm_data( - conversing_domain="test", - user_input=mock_conversation_input, - user_llm_hass_api="assist", - user_llm_prompt=None, + await chat_log.async_update_llm_data( + conversing_domain="test", + user_input=mock_conversation_input, + user_llm_hass_api="assist", + user_llm_prompt=None, + ) + result = None + async for tool_result_content in chat_log.async_add_assistant_content( + AssistantContent( + agent_id=mock_conversation_input.agent_id, + content="", + tool_calls=[ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={"param1": "Test Param"}, + ) + ], ) - result = None - async for tool_result_content in chat_log.async_add_assistant_content( - AssistantContent( - agent_id=mock_conversation_input.agent_id, - content="", - tool_calls=[ - llm.ToolInput( - id="mock-tool-call-id", - tool_name="test_tool", - tool_args={"param1": "Test Param"}, - ) - ], - ) - ): - assert result is None - result = tool_result_content + ): + assert result is None + result = tool_result_content assert result == ToolResultContent( agent_id=mock_conversation_input.agent_id, @@ -420,3 +418,226 @@ async def test_tool_call_exception( tool_result={"error": "HomeAssistantError", "error_text": "Test error"}, tool_name="test_tool", ) + + +@pytest.mark.parametrize( + "deltas", + [ + [], + # With content + [ + {"role": "assistant"}, + {"content": "Test"}, + ], + # With 2 content + [ + {"role": "assistant"}, + {"content": "Test"}, + {"role": "assistant"}, + {"content": "Test 2"}, + ], + # With 1 tool call + [ + {"role": "assistant"}, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={"param1": "Test Param 1"}, + ) + ] + }, + ], + # With content and 1 tool call + [ + {"role": "assistant"}, + {"content": "Test"}, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={"param1": "Test Param 1"}, + ) + ] + }, + ], + # With 2 contents and 1 tool call + [ + {"role": "assistant"}, + {"content": "Test"}, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={"param1": "Test Param 1"}, + ) + ] + }, + {"role": "assistant"}, + {"content": "Test 2"}, + ], + # With 2 tool calls + [ + {"role": "assistant"}, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={"param1": "Test Param 1"}, + ) + ] + }, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id-2", + tool_name="test_tool", + tool_args={"param1": "Test Param 2"}, + ) + ] + }, + ], + ], +) +async def test_add_delta_content_stream( + hass: HomeAssistant, + mock_conversation_input: ConversationInput, + snapshot: SnapshotAssertion, + deltas: list[dict], +) -> None: + """Test streaming deltas.""" + + mock_tool = AsyncMock() + mock_tool.name = "test_tool" + mock_tool.description = "Test function" + mock_tool.parameters = vol.Schema( + {vol.Optional("param1", description="Test parameters"): str} + ) + + async def tool_call( + hass: HomeAssistant, tool_input: llm.ToolInput, llm_context: llm.LLMContext + ) -> str: + """Call the tool.""" + return tool_input.tool_args["param1"] + + mock_tool.async_call.side_effect = tool_call + expected_delta = [] + + async def stream(): + """Yield deltas.""" + for d in deltas: + yield d + expected_delta.append(d) + + captured_deltas = [] + + with ( + patch( + "homeassistant.helpers.llm.AssistAPI._async_get_tools", return_value=[] + ) as mock_get_tools, + chat_session.async_get_chat_session(hass) as session, + async_get_chat_log( + hass, + session, + mock_conversation_input, + chat_log_delta_listener=lambda chat_log, delta: captured_deltas.append( + delta + ), + ) as chat_log, + ): + mock_get_tools.return_value = [mock_tool] + await chat_log.async_update_llm_data( + conversing_domain="test", + user_input=mock_conversation_input, + user_llm_hass_api="assist", + user_llm_prompt=None, + ) + + results = [] + async for content in chat_log.async_add_delta_content_stream( + "mock-agent-id", stream() + ): + results.append(content) + + # Interweave the tool results with the source deltas into expected_delta + if content.role == "tool_result": + expected_delta.append(asdict(content)) + + assert captured_deltas == expected_delta + assert results == snapshot + assert chat_log.content[2:] == results + + +async def test_add_delta_content_stream_errors( + hass: HomeAssistant, + mock_conversation_input: ConversationInput, +) -> None: + """Test streaming deltas error handling.""" + + async def stream(deltas): + """Yield deltas.""" + for d in deltas: + yield d + + with ( + chat_session.async_get_chat_session(hass) as session, + async_get_chat_log(hass, session, mock_conversation_input) as chat_log, + ): + # Stream content without LLM API set + with pytest.raises(ValueError): # noqa: PT012 + async for _tool_result_content in chat_log.async_add_delta_content_stream( + "mock-agent-id", + stream( + [ + {"role": "assistant"}, + { + "tool_calls": [ + llm.ToolInput( + id="mock-tool-call-id", + tool_name="test_tool", + tool_args={}, + ) + ] + }, + ] + ), + ): + pass + + # Non assistant role + for role in "system", "user": + with pytest.raises(ValueError): # noqa: PT012 + async for ( + _tool_result_content + ) in chat_log.async_add_delta_content_stream( + "mock-agent-id", + stream([{"role": role}]), + ): + pass + + +async def test_chat_log_reuse( + hass: HomeAssistant, + mock_conversation_input: ConversationInput, +) -> None: + """Test that we can reuse a chat log.""" + with ( + chat_session.async_get_chat_session(hass) as session, + async_get_chat_log(hass, session) as chat_log, + ): + assert chat_log.conversation_id == session.conversation_id + assert len(chat_log.content) == 1 + + with async_get_chat_log(hass, session) as chat_log2: + assert chat_log2 is chat_log + assert len(chat_log.content) == 1 + + with async_get_chat_log(hass, session, mock_conversation_input) as chat_log2: + assert chat_log2 is chat_log + assert len(chat_log.content) == 2 + assert chat_log.content[1].role == "user" + assert chat_log.content[1].content == mock_conversation_input.text diff --git a/tests/components/cookidoo/snapshots/test_button.ambr b/tests/components/cookidoo/snapshots/test_button.ambr index a6223059aa1..f316b0cfc82 100644 --- a/tests/components/cookidoo/snapshots/test_button.ambr +++ b/tests/components/cookidoo/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/cookidoo/snapshots/test_sensor.ambr b/tests/components/cookidoo/snapshots/test_sensor.ambr index 568b0baf688..ca861241971 100644 --- a/tests/components/cookidoo/snapshots/test_sensor.ambr +++ b/tests/components/cookidoo/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/cookidoo/snapshots/test_todo.ambr b/tests/components/cookidoo/snapshots/test_todo.ambr index be641432929..5b2c7552548 100644 --- a/tests/components/cookidoo/snapshots/test_todo.ambr +++ b/tests/components/cookidoo/snapshots/test_todo.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deako/snapshots/test_light.ambr b/tests/components/deako/snapshots/test_light.ambr index 7bc170654e1..f5ef5fd19e8 100644 --- a/tests/components/deako/snapshots/test_light.ambr +++ b/tests/components/deako/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -121,6 +123,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_alarm_control_panel.ambr b/tests/components/deconz/snapshots/test_alarm_control_panel.ambr index 86b97a62dfe..e1a6126498c 100644 --- a/tests/components/deconz/snapshots/test_alarm_control_panel.ambr +++ b/tests/components/deconz/snapshots/test_alarm_control_panel.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_binary_sensor.ambr b/tests/components/deconz/snapshots/test_binary_sensor.ambr index 584575c23af..6b348d3ed0a 100644 --- a/tests/components/deconz/snapshots/test_binary_sensor.ambr +++ b/tests/components/deconz/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -197,6 +201,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -247,6 +252,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -341,6 +348,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -389,6 +397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -436,6 +445,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -484,6 +494,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -531,6 +542,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -578,6 +590,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -627,6 +640,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -676,6 +690,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -725,6 +740,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -772,6 +788,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -819,6 +836,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -875,6 +893,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -925,6 +944,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -972,6 +992,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_button.ambr b/tests/components/deconz/snapshots/test_button.ambr index 1ef5248ebc3..b7ad00cdacd 100644 --- a/tests/components/deconz/snapshots/test_button.ambr +++ b/tests/components/deconz/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_climate.ambr b/tests/components/deconz/snapshots/test_climate.ambr index 4e33e11534e..f8d572ab2ca 100644 --- a/tests/components/deconz/snapshots/test_climate.ambr +++ b/tests/components/deconz/snapshots/test_climate.ambr @@ -24,6 +24,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +112,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -207,6 +209,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +297,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -360,6 +364,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -425,6 +430,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -491,6 +497,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_cover.ambr b/tests/components/deconz/snapshots/test_cover.ambr index 5c50923453c..41ff4e950a8 100644 --- a/tests/components/deconz/snapshots/test_cover.ambr +++ b/tests/components/deconz/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_diagnostics.ambr b/tests/components/deconz/snapshots/test_diagnostics.ambr index 1ca674a4fbe..20558b4bbbd 100644 --- a/tests/components/deconz/snapshots/test_diagnostics.ambr +++ b/tests/components/deconz/snapshots/test_diagnostics.ambr @@ -21,6 +21,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/deconz/snapshots/test_fan.ambr b/tests/components/deconz/snapshots/test_fan.ambr index 8b7dbba64e4..6a260c39673 100644 --- a/tests/components/deconz/snapshots/test_fan.ambr +++ b/tests/components/deconz/snapshots/test_fan.ambr @@ -8,6 +8,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_hub.ambr b/tests/components/deconz/snapshots/test_hub.ambr index f3aa9a5e65d..06067b69c17 100644 --- a/tests/components/deconz/snapshots/test_hub.ambr +++ b/tests/components/deconz/snapshots/test_hub.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://1.2.3.4:80', 'connections': set({ }), diff --git a/tests/components/deconz/snapshots/test_light.ambr b/tests/components/deconz/snapshots/test_light.ambr index b73bbcca216..212ccd84d0c 100644 --- a/tests/components/deconz/snapshots/test_light.ambr +++ b/tests/components/deconz/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -75,6 +76,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +162,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -238,6 +241,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +318,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -379,6 +384,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -464,6 +470,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -542,6 +549,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -618,6 +626,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -683,6 +692,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -768,6 +778,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -846,6 +857,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -931,6 +943,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1022,6 +1035,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1122,6 +1136,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1215,6 +1230,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1291,6 +1307,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1348,6 +1365,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1418,6 +1436,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_number.ambr b/tests/components/deconz/snapshots/test_number.ambr index 26e044e1d31..173d5e87043 100644 --- a/tests/components/deconz/snapshots/test_number.ambr +++ b/tests/components/deconz/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_scene.ambr b/tests/components/deconz/snapshots/test_scene.ambr index 85a5ab92c5c..21456afaea1 100644 --- a/tests/components/deconz/snapshots/test_scene.ambr +++ b/tests/components/deconz/snapshots/test_scene.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_select.ambr b/tests/components/deconz/snapshots/test_select.ambr index 997eab0901f..7fa2aaf11cb 100644 --- a/tests/components/deconz/snapshots/test_select.ambr +++ b/tests/components/deconz/snapshots/test_select.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +126,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -180,6 +183,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +240,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -293,6 +298,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +355,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -405,6 +412,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -462,6 +470,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -523,6 +532,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/deconz/snapshots/test_sensor.ambr b/tests/components/deconz/snapshots/test_sensor.ambr index 0b76366b5d1..be397f0e22a 100644 --- a/tests/components/deconz/snapshots/test_sensor.ambr +++ b/tests/components/deconz/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +163,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -257,6 +262,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -305,6 +311,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -353,6 +360,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -401,6 +409,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -450,6 +459,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -505,6 +515,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -557,6 +568,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -611,6 +623,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -663,6 +676,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -717,6 +731,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -771,6 +786,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -822,6 +838,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -876,6 +893,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -928,6 +946,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -980,6 +999,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1035,6 +1055,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1085,6 +1106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1134,6 +1156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1186,6 +1209,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1239,6 +1263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1290,6 +1315,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1341,6 +1367,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1392,6 +1419,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1443,6 +1471,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1493,6 +1522,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1544,6 +1574,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1600,6 +1631,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1651,6 +1683,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1702,6 +1735,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1753,6 +1787,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1803,6 +1838,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1854,6 +1890,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1905,6 +1942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1956,6 +1994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2006,6 +2045,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2058,6 +2098,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2109,6 +2150,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2160,6 +2202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2211,6 +2254,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/device_tracker/test_config_entry.py b/tests/components/device_tracker/test_config_entry.py index bc721803450..fa1e65ded51 100644 --- a/tests/components/device_tracker/test_config_entry.py +++ b/tests/components/device_tracker/test_config_entry.py @@ -35,7 +35,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -114,7 +114,7 @@ async def create_mock_platform( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test event platform via config entry.""" async_add_entities(entities) diff --git a/tests/components/devolo_home_control/snapshots/test_binary_sensor.ambr b/tests/components/devolo_home_control/snapshots/test_binary_sensor.ambr index c5daed73b33..659420c1590 100644 --- a/tests/components/devolo_home_control/snapshots/test_binary_sensor.ambr +++ b/tests/components/devolo_home_control/snapshots/test_binary_sensor.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_climate.ambr b/tests/components/devolo_home_control/snapshots/test_climate.ambr index be7d6f78142..96ffe45c4a4 100644 --- a/tests/components/devolo_home_control/snapshots/test_climate.ambr +++ b/tests/components/devolo_home_control/snapshots/test_climate.ambr @@ -35,6 +35,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_cover.ambr b/tests/components/devolo_home_control/snapshots/test_cover.ambr index 7d88d42d5c2..44bff626923 100644 --- a/tests/components/devolo_home_control/snapshots/test_cover.ambr +++ b/tests/components/devolo_home_control/snapshots/test_cover.ambr @@ -22,6 +22,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_diagnostics.ambr b/tests/components/devolo_home_control/snapshots/test_diagnostics.ambr index abedc128756..0e507ca0b28 100644 --- a/tests/components/devolo_home_control/snapshots/test_diagnostics.ambr +++ b/tests/components/devolo_home_control/snapshots/test_diagnostics.ambr @@ -47,6 +47,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '123456', 'version': 1, diff --git a/tests/components/devolo_home_control/snapshots/test_light.ambr b/tests/components/devolo_home_control/snapshots/test_light.ambr index 959656b52a4..11dc768a519 100644 --- a/tests/components/devolo_home_control/snapshots/test_light.ambr +++ b/tests/components/devolo_home_control/snapshots/test_light.ambr @@ -29,6 +29,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -85,6 +86,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_sensor.ambr b/tests/components/devolo_home_control/snapshots/test_sensor.ambr index 3c23385594a..7cca8b23e77 100644 --- a/tests/components/devolo_home_control/snapshots/test_sensor.ambr +++ b/tests/components/devolo_home_control/snapshots/test_sensor.ambr @@ -24,6 +24,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -74,6 +75,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -125,6 +127,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -176,6 +179,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -227,6 +231,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_siren.ambr b/tests/components/devolo_home_control/snapshots/test_siren.ambr index 5c94674998c..41b68574065 100644 --- a/tests/components/devolo_home_control/snapshots/test_siren.ambr +++ b/tests/components/devolo_home_control/snapshots/test_siren.ambr @@ -27,6 +27,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -81,6 +82,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -135,6 +137,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_control/snapshots/test_switch.ambr b/tests/components/devolo_home_control/snapshots/test_switch.ambr index 3e2f6f705d3..d3097716092 100644 --- a/tests/components/devolo_home_control/snapshots/test_switch.ambr +++ b/tests/components/devolo_home_control/snapshots/test_switch.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_binary_sensor.ambr b/tests/components/devolo_home_network/snapshots/test_binary_sensor.ambr index c0df0d5d5a5..a33fdf084dd 100644 --- a/tests/components/devolo_home_network/snapshots/test_binary_sensor.ambr +++ b/tests/components/devolo_home_network/snapshots/test_binary_sensor.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_button.ambr b/tests/components/devolo_home_network/snapshots/test_button.ambr index 126ac4e7cdb..31d8ebf31a0 100644 --- a/tests/components/devolo_home_network/snapshots/test_button.ambr +++ b/tests/components/devolo_home_network/snapshots/test_button.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_diagnostics.ambr b/tests/components/devolo_home_network/snapshots/test_diagnostics.ambr index 53940bf5119..1288b7f3ef6 100644 --- a/tests/components/devolo_home_network/snapshots/test_diagnostics.ambr +++ b/tests/components/devolo_home_network/snapshots/test_diagnostics.ambr @@ -32,6 +32,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '1234567890', 'version': 1, diff --git a/tests/components/devolo_home_network/snapshots/test_image.ambr b/tests/components/devolo_home_network/snapshots/test_image.ambr index b3924a508cf..3772672d8cb 100644 --- a/tests/components/devolo_home_network/snapshots/test_image.ambr +++ b/tests/components/devolo_home_network/snapshots/test_image.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_init.ambr b/tests/components/devolo_home_network/snapshots/test_init.ambr index 297c9a25183..bdc597819a7 100644 --- a/tests/components/devolo_home_network/snapshots/test_init.ambr +++ b/tests/components/devolo_home_network/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.0.2.1', 'connections': set({ tuple( @@ -39,6 +40,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.0.2.1', 'connections': set({ }), diff --git a/tests/components/devolo_home_network/snapshots/test_sensor.ambr b/tests/components/devolo_home_network/snapshots/test_sensor.ambr index 2e6730cdb21..9e2d8879ac9 100644 --- a/tests/components/devolo_home_network/snapshots/test_sensor.ambr +++ b/tests/components/devolo_home_network/snapshots/test_sensor.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -115,6 +117,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -260,6 +265,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_switch.ambr b/tests/components/devolo_home_network/snapshots/test_switch.ambr index a2df5d2579f..6499bb9a17b 100644 --- a/tests/components/devolo_home_network/snapshots/test_switch.ambr +++ b/tests/components/devolo_home_network/snapshots/test_switch.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/devolo_home_network/snapshots/test_update.ambr b/tests/components/devolo_home_network/snapshots/test_update.ambr index 8a1065f9a60..f4d1c0480cf 100644 --- a/tests/components/devolo_home_network/snapshots/test_update.ambr +++ b/tests/components/devolo_home_network/snapshots/test_update.ambr @@ -32,6 +32,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/discovergy/snapshots/test_sensor.ambr b/tests/components/discovergy/snapshots/test_sensor.ambr index b4831d81bda..866a57c8dda 100644 --- a/tests/components/discovergy/snapshots/test_sensor.ambr +++ b/tests/components/discovergy/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -44,6 +45,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -188,6 +192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/drop_connect/snapshots/test_binary_sensor.ambr b/tests/components/drop_connect/snapshots/test_binary_sensor.ambr index 9b0cc201573..8d83482e208 100644 --- a/tests/components/drop_connect/snapshots/test_binary_sensor.ambr +++ b/tests/components/drop_connect/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -287,6 +293,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -334,6 +341,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -427,6 +436,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/dsmr/conftest.py b/tests/components/dsmr/conftest.py index ccb7920e141..769e98f6db4 100644 --- a/tests/components/dsmr/conftest.py +++ b/tests/components/dsmr/conftest.py @@ -113,6 +113,12 @@ def dsmr_connection_send_validate_fixture() -> Generator[ EQUIPMENT_IDENTIFIER_GAS, [{"value": "123456789", "unit": ""}] ), } + if args[1] == "5EONHU": + protocol.telegram = { + LUXEMBOURG_EQUIPMENT_IDENTIFIER: CosemObject( + LUXEMBOURG_EQUIPMENT_IDENTIFIER, [{"value": "12345678", "unit": ""}] + ), + } if args[1] == "5S": protocol.telegram = { P1_MESSAGE_TIMESTAMP: CosemObject( diff --git a/tests/components/dsmr/test_config_flow.py b/tests/components/dsmr/test_config_flow.py index 91adf38eacf..961c9831f44 100644 --- a/tests/components/dsmr/test_config_flow.py +++ b/tests/components/dsmr/test_config_flow.py @@ -163,6 +163,16 @@ async def test_setup_network_rfxtrx( "serial_id_gas": "123456789", }, ), + ( + "5EONHU", + { + "port": "/dev/ttyUSB1234", + "dsmr_version": "5EONHU", + "protocol": "dsmr_protocol", + "serial_id": "12345678", + "serial_id_gas": None, + }, + ), ( "5S", { diff --git a/tests/components/dsmr/test_sensor.py b/tests/components/dsmr/test_sensor.py index fbe14b38aa3..5657c5999ce 100644 --- a/tests/components/dsmr/test_sensor.py +++ b/tests/components/dsmr/test_sensor.py @@ -512,6 +512,76 @@ async def test_luxembourg_meter( ) +async def test_eonhu_meter( + hass: HomeAssistant, dsmr_connection_fixture: tuple[MagicMock, MagicMock, MagicMock] +) -> None: + """Test if v5 meter is correctly parsed.""" + (connection_factory, transport, protocol) = dsmr_connection_fixture + + entry_data = { + "port": "/dev/ttyUSB0", + "dsmr_version": "5EONHU", + "serial_id": "1234", + } + entry_options = { + "time_between_update": 0, + } + + telegram = Telegram() + telegram.add( + ELECTRICITY_IMPORTED_TOTAL, + CosemObject( + (0, 0), + [{"value": Decimal("123.456"), "unit": UnitOfEnergy.KILO_WATT_HOUR}], + ), + "ELECTRICITY_IMPORTED_TOTAL", + ) + telegram.add( + ELECTRICITY_EXPORTED_TOTAL, + CosemObject( + (0, 0), + [{"value": Decimal("654.321"), "unit": UnitOfEnergy.KILO_WATT_HOUR}], + ), + "ELECTRICITY_EXPORTED_TOTAL", + ) + + mock_entry = MockConfigEntry( + domain="dsmr", unique_id="/dev/ttyUSB0", data=entry_data, options=entry_options + ) + + mock_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_entry.entry_id) + await hass.async_block_till_done() + + telegram_callback = connection_factory.call_args_list[0][0][2] + + # simulate a telegram pushed from the smartmeter and parsed by dsmr_parser + telegram_callback(telegram) + + # after receiving telegram entities need to have the chance to be created + await hass.async_block_till_done() + + active_tariff = hass.states.get("sensor.electricity_meter_energy_consumption_total") + assert active_tariff.state == "123.456" + assert active_tariff.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.ENERGY + assert ( + active_tariff.attributes.get(ATTR_STATE_CLASS) + == SensorStateClass.TOTAL_INCREASING + ) + assert ( + active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) + == UnitOfEnergy.KILO_WATT_HOUR + ) + + active_tariff = hass.states.get("sensor.electricity_meter_energy_production_total") + assert active_tariff.state == "654.321" + assert ( + active_tariff.attributes.get("unit_of_measurement") + == UnitOfEnergy.KILO_WATT_HOUR + ) + + async def test_belgian_meter( hass: HomeAssistant, dsmr_connection_fixture: tuple[MagicMock, MagicMock, MagicMock] ) -> None: diff --git a/tests/components/dsmr_reader/snapshots/test_diagnostics.ambr b/tests/components/dsmr_reader/snapshots/test_diagnostics.ambr index d407fe2dc5b..0a46dd7f476 100644 --- a/tests/components/dsmr_reader/snapshots/test_diagnostics.ambr +++ b/tests/components/dsmr_reader/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'dsmr_reader', 'unique_id': 'UNIQUE_TEST_ID', 'version': 1, diff --git a/tests/components/ecovacs/snapshots/test_binary_sensor.ambr b/tests/components/ecovacs/snapshots/test_binary_sensor.ambr index 62b356e379d..59e2f5a24b7 100644 --- a/tests/components/ecovacs/snapshots/test_binary_sensor.ambr +++ b/tests/components/ecovacs/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_button.ambr b/tests/components/ecovacs/snapshots/test_button.ambr index f21d019a7b1..2c657080c12 100644 --- a/tests/components/ecovacs/snapshots/test_button.ambr +++ b/tests/components/ecovacs/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -374,6 +382,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -420,6 +429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -466,6 +476,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -512,6 +523,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +570,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_diagnostics.ambr b/tests/components/ecovacs/snapshots/test_diagnostics.ambr index 38c8a9a5ab9..f9540e06038 100644 --- a/tests/components/ecovacs/snapshots/test_diagnostics.ambr +++ b/tests/components/ecovacs/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': None, 'version': 1, @@ -70,6 +72,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': None, 'version': 1, diff --git a/tests/components/ecovacs/snapshots/test_event.ambr b/tests/components/ecovacs/snapshots/test_event.ambr index 8f433560cd1..d29bf8dd57a 100644 --- a/tests/components/ecovacs/snapshots/test_event.ambr +++ b/tests/components/ecovacs/snapshots/test_event.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_init.ambr b/tests/components/ecovacs/snapshots/test_init.ambr index 9113445cc31..e403c937394 100644 --- a/tests/components/ecovacs/snapshots/test_init.ambr +++ b/tests/components/ecovacs/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/ecovacs/snapshots/test_lawn_mower.ambr b/tests/components/ecovacs/snapshots/test_lawn_mower.ambr index 29c710a5cb7..6367872c7f7 100644 --- a/tests/components/ecovacs/snapshots/test_lawn_mower.ambr +++ b/tests/components/ecovacs/snapshots/test_lawn_mower.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -39,6 +40,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_number.ambr b/tests/components/ecovacs/snapshots/test_number.ambr index c80132784e1..952fa4556b0 100644 --- a/tests/components/ecovacs/snapshots/test_number.ambr +++ b/tests/components/ecovacs/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_select.ambr b/tests/components/ecovacs/snapshots/test_select.ambr index 125e7f0cee8..354afca1178 100644 --- a/tests/components/ecovacs/snapshots/test_select.ambr +++ b/tests/components/ecovacs/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_sensor.ambr b/tests/components/ecovacs/snapshots/test_sensor.ambr index 755fcda9e7d..c4e5a5b1966 100644 --- a/tests/components/ecovacs/snapshots/test_sensor.ambr +++ b/tests/components/ecovacs/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -154,6 +157,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -201,6 +205,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -249,6 +254,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +302,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -347,6 +354,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -394,6 +402,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -440,6 +449,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -489,6 +499,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -539,6 +550,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -593,6 +605,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -640,6 +653,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -686,6 +700,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -732,6 +747,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -779,6 +795,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -827,6 +844,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -878,6 +896,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -925,6 +944,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -972,6 +992,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1018,6 +1039,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1065,6 +1087,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1112,6 +1135,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1164,6 +1188,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1217,6 +1242,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1267,6 +1293,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1321,6 +1348,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1368,6 +1396,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1415,6 +1444,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1461,6 +1491,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1507,6 +1538,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1554,6 +1586,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1602,6 +1635,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1653,6 +1687,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1700,6 +1735,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1747,6 +1783,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1793,6 +1830,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1840,6 +1878,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1889,6 +1928,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1939,6 +1979,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1993,6 +2034,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2040,6 +2082,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2086,6 +2129,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ecovacs/snapshots/test_switch.ambr b/tests/components/ecovacs/snapshots/test_switch.ambr index 59e891bea5e..48aa9d8fc17 100644 --- a/tests/components/ecovacs/snapshots/test_switch.ambr +++ b/tests/components/ecovacs/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -374,6 +382,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -420,6 +429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/eheimdigital/snapshots/test_climate.ambr b/tests/components/eheimdigital/snapshots/test_climate.ambr index 171d3d427fc..73c7cf638e8 100644 --- a/tests/components/eheimdigital/snapshots/test_climate.ambr +++ b/tests/components/eheimdigital/snapshots/test_climate.ambr @@ -19,6 +19,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -95,6 +96,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/eheimdigital/snapshots/test_light.ambr b/tests/components/eheimdigital/snapshots/test_light.ambr index 8df4745997e..a8b454f416e 100644 --- a/tests/components/eheimdigital/snapshots/test_light.ambr +++ b/tests/components/eheimdigital/snapshots/test_light.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -76,6 +77,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -139,6 +141,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -202,6 +205,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -265,6 +269,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/elgato/snapshots/test_button.ambr b/tests/components/elgato/snapshots/test_button.ambr index dcf9d1c87d0..81a817f2738 100644 --- a/tests/components/elgato/snapshots/test_button.ambr +++ b/tests/components/elgato/snapshots/test_button.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -133,6 +136,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/elgato/snapshots/test_light.ambr b/tests/components/elgato/snapshots/test_light.ambr index 4bb4644ab86..84f7ca45843 100644 --- a/tests/components/elgato/snapshots/test_light.ambr +++ b/tests/components/elgato/snapshots/test_light.ambr @@ -52,6 +52,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -82,6 +83,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -169,6 +171,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -199,6 +202,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -286,6 +290,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -316,6 +321,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/elgato/snapshots/test_sensor.ambr b/tests/components/elgato/snapshots/test_sensor.ambr index be0ec0a56c5..f64893798e9 100644 --- a/tests/components/elgato/snapshots/test_sensor.ambr +++ b/tests/components/elgato/snapshots/test_sensor.ambr @@ -24,6 +24,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -114,6 +116,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -207,6 +211,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -243,6 +248,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -300,6 +306,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +340,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -390,6 +398,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -426,6 +435,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/elgato/snapshots/test_switch.ambr b/tests/components/elgato/snapshots/test_switch.ambr index ba95160d28a..254e4deb7d9 100644 --- a/tests/components/elgato/snapshots/test_switch.ambr +++ b/tests/components/elgato/snapshots/test_switch.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -49,6 +50,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -131,6 +134,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/elmax/snapshots/test_alarm_control_panel.ambr b/tests/components/elmax/snapshots/test_alarm_control_panel.ambr index f175fc707bb..2bf3aa48430 100644 --- a/tests/components/elmax/snapshots/test_alarm_control_panel.ambr +++ b/tests/components/elmax/snapshots/test_alarm_control_panel.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/elmax/snapshots/test_binary_sensor.ambr b/tests/components/elmax/snapshots/test_binary_sensor.ambr index 3c3f63b44ca..7515547406e 100644 --- a/tests/components/elmax/snapshots/test_binary_sensor.ambr +++ b/tests/components/elmax/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/elmax/snapshots/test_cover.ambr b/tests/components/elmax/snapshots/test_cover.ambr index 0dbea416934..8cb230e1523 100644 --- a/tests/components/elmax/snapshots/test_cover.ambr +++ b/tests/components/elmax/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/elmax/snapshots/test_switch.ambr b/tests/components/elmax/snapshots/test_switch.ambr index 0ae1942e7e0..f5845223717 100644 --- a/tests/components/elmax/snapshots/test_switch.ambr +++ b/tests/components/elmax/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/emoncms/snapshots/test_sensor.ambr b/tests/components/emoncms/snapshots/test_sensor.ambr index 210196ce414..6dc19155863 100644 --- a/tests/components/emoncms/snapshots/test_sensor.ambr +++ b/tests/components/emoncms/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/energenie_power_sockets/snapshots/test_switch.ambr b/tests/components/energenie_power_sockets/snapshots/test_switch.ambr index d462d6ca6d4..99595168157 100644 --- a/tests/components/energenie_power_sockets/snapshots/test_switch.ambr +++ b/tests/components/energenie_power_sockets/snapshots/test_switch.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -114,6 +116,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/energyzero/snapshots/test_sensor.ambr b/tests/components/energyzero/snapshots/test_sensor.ambr index 452f4ae748e..5407ac8f0e9 100644 --- a/tests/components/energyzero/snapshots/test_sensor.ambr +++ b/tests/components/energyzero/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -201,6 +205,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -249,6 +254,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -297,6 +303,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -345,6 +352,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -393,6 +401,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -443,6 +452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -492,6 +502,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/enphase_envoy/snapshots/test_binary_sensor.ambr b/tests/components/enphase_envoy/snapshots/test_binary_sensor.ambr index e9bf8378d79..e4810c21226 100644 --- a/tests/components/enphase_envoy/snapshots/test_binary_sensor.ambr +++ b/tests/components/enphase_envoy/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/enphase_envoy/snapshots/test_diagnostics.ambr b/tests/components/enphase_envoy/snapshots/test_diagnostics.ambr index 4254ffe961a..152cf803258 100644 --- a/tests/components/enphase_envoy/snapshots/test_diagnostics.ambr +++ b/tests/components/enphase_envoy/snapshots/test_diagnostics.ambr @@ -20,6 +20,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, @@ -31,6 +33,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -68,6 +75,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -119,6 +127,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -168,6 +177,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -218,6 +228,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -266,6 +277,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -303,6 +319,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -346,6 +363,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': 'integration', 'domain': 'sensor', @@ -449,6 +467,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, @@ -460,6 +480,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -497,6 +522,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -548,6 +574,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -597,6 +624,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -647,6 +675,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -695,6 +724,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -732,6 +766,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -775,6 +810,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': 'integration', 'domain': 'sensor', @@ -918,6 +954,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, @@ -929,6 +967,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -966,6 +1009,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1017,6 +1061,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1066,6 +1111,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1116,6 +1162,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1164,6 +1211,11 @@ 'config_entries': list([ '45a36e55aaddb2007c5f6602e0c38e72', ]), + 'config_entries_subentries': dict({ + '45a36e55aaddb2007c5f6602e0c38e72': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -1201,6 +1253,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1244,6 +1297,7 @@ 'categories': dict({ }), 'config_entry_id': '45a36e55aaddb2007c5f6602e0c38e72', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': 'integration', 'domain': 'sensor', diff --git a/tests/components/enphase_envoy/snapshots/test_number.ambr b/tests/components/enphase_envoy/snapshots/test_number.ambr index b7e799c9ac8..eb8f5266f32 100644 --- a/tests/components/enphase_envoy/snapshots/test_number.ambr +++ b/tests/components/enphase_envoy/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -125,6 +127,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -181,6 +184,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -237,6 +241,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -293,6 +298,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +355,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -405,6 +412,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/enphase_envoy/snapshots/test_select.ambr b/tests/components/enphase_envoy/snapshots/test_select.ambr index f091879d9fc..d8238926dfd 100644 --- a/tests/components/enphase_envoy/snapshots/test_select.ambr +++ b/tests/components/enphase_envoy/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -186,6 +189,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -245,6 +249,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -302,6 +307,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -359,6 +365,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -418,6 +425,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -477,6 +485,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +543,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -591,6 +601,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -650,6 +661,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -709,6 +721,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -766,6 +779,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/enphase_envoy/snapshots/test_sensor.ambr b/tests/components/enphase_envoy/snapshots/test_sensor.ambr index 0f251b5e859..c1e2c9270e2 100644 --- a/tests/components/enphase_envoy/snapshots/test_sensor.ambr +++ b/tests/components/enphase_envoy/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -63,6 +64,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -119,6 +121,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -176,6 +179,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -233,6 +237,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +287,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -331,6 +337,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -388,6 +395,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -445,6 +453,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -502,6 +511,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -557,6 +567,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -613,6 +624,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -668,6 +680,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -724,6 +737,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -781,6 +795,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -835,6 +850,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -889,6 +905,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -946,6 +963,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1003,6 +1021,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1060,6 +1079,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1117,6 +1137,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1172,6 +1193,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1218,6 +1240,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1270,6 +1293,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1328,6 +1352,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1382,6 +1407,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1439,6 +1465,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1492,6 +1519,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1545,6 +1573,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1602,6 +1631,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1659,6 +1689,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1716,6 +1747,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1765,6 +1797,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1812,6 +1845,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1867,6 +1901,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1920,6 +1955,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1968,6 +2004,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2016,6 +2053,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2064,6 +2102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2111,6 +2150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2159,6 +2199,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2207,6 +2248,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2255,6 +2297,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2303,6 +2346,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2351,6 +2395,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2399,6 +2444,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2449,6 +2495,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2504,6 +2551,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2552,6 +2600,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2602,6 +2651,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2659,6 +2709,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2716,6 +2767,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2773,6 +2825,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2830,6 +2883,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2887,6 +2941,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2942,6 +2997,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2998,6 +3054,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3053,6 +3110,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3109,6 +3167,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3166,6 +3225,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3220,6 +3280,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3274,6 +3335,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3328,6 +3390,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3382,6 +3445,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3436,6 +3500,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3490,6 +3555,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3544,6 +3610,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3598,6 +3665,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3655,6 +3723,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3712,6 +3781,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3769,6 +3839,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3826,6 +3897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3883,6 +3955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3940,6 +4013,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3997,6 +4071,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4054,6 +4129,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4111,6 +4187,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4168,6 +4245,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4223,6 +4301,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4269,6 +4348,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4315,6 +4395,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4361,6 +4442,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4407,6 +4489,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4453,6 +4536,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4499,6 +4583,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4545,6 +4630,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4597,6 +4683,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4655,6 +4742,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4713,6 +4801,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4771,6 +4860,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4829,6 +4919,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4887,6 +4978,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4945,6 +5037,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5003,6 +5096,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5057,6 +5151,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5114,6 +5209,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5171,6 +5267,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5228,6 +5325,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5285,6 +5383,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5338,6 +5437,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5391,6 +5491,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5444,6 +5545,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5497,6 +5599,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5550,6 +5653,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5603,6 +5707,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5656,6 +5761,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5709,6 +5815,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5766,6 +5873,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5823,6 +5931,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5880,6 +5989,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5935,6 +6045,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5983,6 +6094,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6033,6 +6145,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6090,6 +6203,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6147,6 +6261,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6204,6 +6319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6261,6 +6377,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6318,6 +6435,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6375,6 +6493,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6432,6 +6551,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6489,6 +6609,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6538,6 +6659,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6585,6 +6707,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6633,6 +6756,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6681,6 +6805,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6728,6 +6853,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6776,6 +6902,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6824,6 +6951,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6874,6 +7002,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6929,6 +7058,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6977,6 +7107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7027,6 +7158,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7084,6 +7216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7141,6 +7274,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7198,6 +7332,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7255,6 +7390,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7312,6 +7448,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7367,6 +7504,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7423,6 +7561,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7478,6 +7617,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7534,6 +7674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7591,6 +7732,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7645,6 +7787,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7699,6 +7842,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7753,6 +7897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7807,6 +7952,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7861,6 +8007,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7915,6 +8062,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7969,6 +8117,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8023,6 +8172,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8080,6 +8230,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8137,6 +8288,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8194,6 +8346,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8251,6 +8404,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8308,6 +8462,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8365,6 +8520,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8422,6 +8578,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8479,6 +8636,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8536,6 +8694,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8593,6 +8752,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8648,6 +8808,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8694,6 +8855,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8740,6 +8902,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8786,6 +8949,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8832,6 +8996,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8878,6 +9043,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8924,6 +9090,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8970,6 +9137,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9022,6 +9190,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9080,6 +9249,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9138,6 +9308,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9196,6 +9367,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9254,6 +9426,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9312,6 +9485,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9370,6 +9544,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9428,6 +9603,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9482,6 +9658,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9539,6 +9716,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9596,6 +9774,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9653,6 +9832,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9710,6 +9890,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9763,6 +9944,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9816,6 +9998,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9869,6 +10052,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9922,6 +10106,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9975,6 +10160,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10028,6 +10214,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10081,6 +10268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10134,6 +10322,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10191,6 +10380,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10248,6 +10438,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10305,6 +10496,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10360,6 +10552,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10408,6 +10601,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10458,6 +10652,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10515,6 +10710,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10572,6 +10768,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10629,6 +10826,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10686,6 +10884,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10743,6 +10942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10800,6 +11000,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10857,6 +11058,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10914,6 +11116,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10963,6 +11166,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11010,6 +11214,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11058,6 +11263,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11106,6 +11312,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11153,6 +11360,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11201,6 +11409,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11249,6 +11458,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11296,6 +11506,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11344,6 +11555,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11394,6 +11606,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11451,6 +11664,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11508,6 +11722,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11565,6 +11780,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11620,6 +11836,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11668,6 +11885,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11718,6 +11936,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11775,6 +11994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11832,6 +12052,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11889,6 +12110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11946,6 +12168,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12003,6 +12226,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12060,6 +12284,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12117,6 +12342,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12174,6 +12400,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12231,6 +12458,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12288,6 +12516,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12345,6 +12574,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12402,6 +12632,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12459,6 +12690,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12516,6 +12748,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12573,6 +12806,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12628,6 +12862,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12682,6 +12917,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12736,6 +12972,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12790,6 +13027,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12846,6 +13084,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12903,6 +13142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12960,6 +13200,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13017,6 +13258,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13072,6 +13314,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13126,6 +13369,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13180,6 +13424,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13234,6 +13479,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13290,6 +13536,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13347,6 +13594,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13404,6 +13652,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13461,6 +13710,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13518,6 +13768,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13572,6 +13823,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13626,6 +13878,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13680,6 +13933,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13734,6 +13988,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13788,6 +14043,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13842,6 +14098,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13896,6 +14153,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13950,6 +14208,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14004,6 +14263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14058,6 +14318,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14112,6 +14373,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14166,6 +14428,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14223,6 +14486,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14280,6 +14544,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14337,6 +14602,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14394,6 +14660,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14451,6 +14718,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14508,6 +14776,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14565,6 +14834,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14622,6 +14892,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14679,6 +14950,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14736,6 +15008,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14793,6 +15066,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14850,6 +15124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14907,6 +15182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14964,6 +15240,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15021,6 +15298,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15078,6 +15356,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15135,6 +15414,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15192,6 +15472,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15249,6 +15530,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15306,6 +15588,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15363,6 +15646,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15420,6 +15704,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15477,6 +15762,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15534,6 +15820,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15591,6 +15878,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15648,6 +15936,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15705,6 +15994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15760,6 +16050,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15806,6 +16097,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15852,6 +16144,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15898,6 +16191,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15944,6 +16238,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15990,6 +16285,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16036,6 +16332,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16082,6 +16379,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16128,6 +16426,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16174,6 +16473,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16220,6 +16520,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16266,6 +16567,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16318,6 +16620,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16376,6 +16679,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16434,6 +16738,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16492,6 +16797,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16550,6 +16856,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16608,6 +16915,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16666,6 +16974,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16724,6 +17033,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16782,6 +17092,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16840,6 +17151,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16898,6 +17210,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16956,6 +17269,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17010,6 +17324,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17067,6 +17382,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17124,6 +17440,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17181,6 +17498,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17238,6 +17556,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17291,6 +17610,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17344,6 +17664,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17397,6 +17718,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17450,6 +17772,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17503,6 +17826,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17556,6 +17880,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17609,6 +17934,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17662,6 +17988,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17715,6 +18042,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17768,6 +18096,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17821,6 +18150,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17874,6 +18204,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17931,6 +18262,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17988,6 +18320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18045,6 +18378,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18100,6 +18434,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18148,6 +18483,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18198,6 +18534,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18255,6 +18592,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18312,6 +18650,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18369,6 +18708,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18426,6 +18766,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18483,6 +18824,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18540,6 +18882,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18597,6 +18940,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18654,6 +18998,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18711,6 +19056,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18768,6 +19114,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18825,6 +19172,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18882,6 +19230,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18939,6 +19288,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18996,6 +19346,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19053,6 +19404,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19110,6 +19462,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19159,6 +19512,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19208,6 +19562,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19265,6 +19620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19322,6 +19678,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19379,6 +19736,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19436,6 +19794,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19493,6 +19852,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19550,6 +19910,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19607,6 +19968,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19664,6 +20026,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19721,6 +20084,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19778,6 +20142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19835,6 +20200,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19892,6 +20258,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19949,6 +20316,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20006,6 +20374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20063,6 +20432,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20118,6 +20488,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20172,6 +20543,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20226,6 +20598,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20280,6 +20653,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20336,6 +20710,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20393,6 +20768,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20450,6 +20826,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20507,6 +20884,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20562,6 +20940,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20616,6 +20995,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20670,6 +21050,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20724,6 +21105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20780,6 +21162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20837,6 +21220,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20894,6 +21278,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -20951,6 +21336,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21008,6 +21394,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21062,6 +21449,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21116,6 +21504,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21170,6 +21559,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21224,6 +21614,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21278,6 +21669,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21332,6 +21724,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21386,6 +21779,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21440,6 +21834,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21497,6 +21892,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21554,6 +21950,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21611,6 +22008,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21668,6 +22066,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21725,6 +22124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21782,6 +22182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21839,6 +22240,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21896,6 +22298,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -21953,6 +22356,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22010,6 +22414,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22067,6 +22472,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22124,6 +22530,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22181,6 +22588,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22238,6 +22646,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22295,6 +22704,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22352,6 +22762,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22409,6 +22820,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22466,6 +22878,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22523,6 +22936,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22578,6 +22992,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22624,6 +23039,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22670,6 +23086,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22716,6 +23133,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22762,6 +23180,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22808,6 +23227,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22854,6 +23274,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22900,6 +23321,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -22952,6 +23374,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23010,6 +23433,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23068,6 +23492,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23126,6 +23551,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23184,6 +23610,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23242,6 +23669,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23300,6 +23728,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23358,6 +23787,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23412,6 +23842,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23469,6 +23900,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23526,6 +23958,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23583,6 +24016,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23640,6 +24074,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23693,6 +24128,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23746,6 +24182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23799,6 +24236,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23852,6 +24290,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23905,6 +24344,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -23958,6 +24398,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24011,6 +24452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24064,6 +24506,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24121,6 +24564,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24178,6 +24622,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24235,6 +24680,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24292,6 +24738,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24349,6 +24796,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24406,6 +24854,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24463,6 +24912,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24520,6 +24970,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24577,6 +25028,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24634,6 +25086,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24691,6 +25144,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24748,6 +25202,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24797,6 +25252,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24846,6 +25302,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24903,6 +25360,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -24958,6 +25416,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25014,6 +25473,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25071,6 +25531,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25125,6 +25586,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25182,6 +25644,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25237,6 +25700,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25289,6 +25753,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25343,6 +25808,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25396,6 +25862,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25453,6 +25920,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25510,6 +25978,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -25559,6 +26028,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/enphase_envoy/snapshots/test_switch.ambr b/tests/components/enphase_envoy/snapshots/test_switch.ambr index a022e476d5c..77b682cb948 100644 --- a/tests/components/enphase_envoy/snapshots/test_switch.ambr +++ b/tests/components/enphase_envoy/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/esphome/snapshots/test_diagnostics.ambr b/tests/components/esphome/snapshots/test_diagnostics.ambr index 4f7ea679b20..8f1711e829e 100644 --- a/tests/components/esphome/snapshots/test_diagnostics.ambr +++ b/tests/components/esphome/snapshots/test_diagnostics.ambr @@ -20,6 +20,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'ESPHome Device', 'unique_id': '11:22:33:44:55:aa', 'version': 1, diff --git a/tests/components/esphome/test_diagnostics.py b/tests/components/esphome/test_diagnostics.py index 832e7d6572f..0beeae71df3 100644 --- a/tests/components/esphome/test_diagnostics.py +++ b/tests/components/esphome/test_diagnostics.py @@ -79,6 +79,7 @@ async def test_diagnostics_with_bluetooth( "pref_disable_new_entities": False, "pref_disable_polling": False, "source": "user", + "subentries": [], "title": "Mock Title", "unique_id": "11:22:33:44:55:aa", "version": 1, diff --git a/tests/components/event/test_init.py b/tests/components/event/test_init.py index c6828c2c290..bc43a234ffc 100644 --- a/tests/components/event/test_init.py +++ b/tests/components/event/test_init.py @@ -17,7 +17,7 @@ from homeassistant.components.event import ( from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.const import CONF_PLATFORM, STATE_UNKNOWN from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import STORAGE_KEY as RESTORE_STATE_KEY from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -297,7 +297,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test event platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) diff --git a/tests/components/filesize/snapshots/test_sensor.ambr b/tests/components/filesize/snapshots/test_sensor.ambr index 339d64acf91..e7f6f9d042b 100644 --- a/tests/components/filesize/snapshots/test_sensor.ambr +++ b/tests/components/filesize/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flexit_bacnet/snapshots/test_binary_sensor.ambr b/tests/components/flexit_bacnet/snapshots/test_binary_sensor.ambr index f983d834927..0b45e1f19be 100644 --- a/tests/components/flexit_bacnet/snapshots/test_binary_sensor.ambr +++ b/tests/components/flexit_bacnet/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flexit_bacnet/snapshots/test_climate.ambr b/tests/components/flexit_bacnet/snapshots/test_climate.ambr index 790c377b1f2..d15fc291a16 100644 --- a/tests/components/flexit_bacnet/snapshots/test_climate.ambr +++ b/tests/components/flexit_bacnet/snapshots/test_climate.ambr @@ -19,6 +19,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flexit_bacnet/snapshots/test_number.ambr b/tests/components/flexit_bacnet/snapshots/test_number.ambr index e2875c140cc..622ec81e45d 100644 --- a/tests/components/flexit_bacnet/snapshots/test_number.ambr +++ b/tests/components/flexit_bacnet/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -125,6 +127,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -182,6 +185,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +243,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +301,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -353,6 +359,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -410,6 +417,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -467,6 +475,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -524,6 +533,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -581,6 +591,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flexit_bacnet/snapshots/test_sensor.ambr b/tests/components/flexit_bacnet/snapshots/test_sensor.ambr index 2c65bd53a6e..b265a4402dc 100644 --- a/tests/components/flexit_bacnet/snapshots/test_sensor.ambr +++ b/tests/components/flexit_bacnet/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -112,6 +114,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +165,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -210,6 +214,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +263,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -308,6 +314,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +369,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -412,6 +420,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -460,6 +469,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -510,6 +520,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -562,6 +573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -612,6 +624,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -662,6 +675,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -710,6 +724,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flexit_bacnet/snapshots/test_switch.ambr b/tests/components/flexit_bacnet/snapshots/test_switch.ambr index 1df1c12e791..0e27c2e938a 100644 --- a/tests/components/flexit_bacnet/snapshots/test_switch.ambr +++ b/tests/components/flexit_bacnet/snapshots/test_switch.ambr @@ -1,4 +1,52 @@ # serializer version: 1 +# name: test_switches[switch.device_name_cooker_hood_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': None, + 'entity_id': 'switch.device_name_cooker_hood_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Cooker hood mode', + 'platform': 'flexit_bacnet', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'cooker_hood_mode', + 'unique_id': '0000-0001-cooker_hood_mode', + 'unit_of_measurement': None, + }) +# --- +# name: test_switches[switch.device_name_cooker_hood_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'switch', + 'friendly_name': 'Device Name Cooker hood mode', + }), + 'context': , + 'entity_id': 'switch.device_name_cooker_hood_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- # name: test_switches[switch.device_name_electric_heater-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -6,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/flick_electric/__init__.py b/tests/components/flick_electric/__init__.py index 36936cad047..3632ce204aa 100644 --- a/tests/components/flick_electric/__init__.py +++ b/tests/components/flick_electric/__init__.py @@ -7,15 +7,26 @@ from homeassistant.components.flick_electric.const import ( CONF_SUPPLY_NODE_REF, ) from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry CONF = { - CONF_USERNAME: "test-username", + CONF_USERNAME: "9973debf-963f-49b0-9a73-ba9c3400cbed@anonymised.example.com", CONF_PASSWORD: "test-password", - CONF_ACCOUNT_ID: "1234", - CONF_SUPPLY_NODE_REF: "123", + CONF_ACCOUNT_ID: "134800", + CONF_SUPPLY_NODE_REF: "/network/nz/supply_nodes/ed7617df-4b10-4c8a-a05d-deadbeef8299", } +async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: + """Fixture for setting up the component.""" + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + def _mock_flick_price(): return FlickPrice( { diff --git a/tests/components/flick_electric/conftest.py b/tests/components/flick_electric/conftest.py new file mode 100644 index 00000000000..2abfafab55d --- /dev/null +++ b/tests/components/flick_electric/conftest.py @@ -0,0 +1,105 @@ +"""Flick Electric tests configuration.""" + +from collections.abc import Generator +from unittest.mock import AsyncMock, patch + +import json_api_doc +from pyflick import FlickPrice +import pytest + +from homeassistant.components.flick_electric.const import CONF_ACCOUNT_ID, DOMAIN +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME + +from . import CONF + +from tests.common import MockConfigEntry, load_json_value_fixture + + +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Mock a config entry.""" + return MockConfigEntry( + domain=DOMAIN, + title="123 Fake Street, Newtown, Wellington 6021", + data={**CONF}, + version=2, + entry_id="974e52a5c0724d17b7ed876dd6ff4bc8", + unique_id=CONF[CONF_ACCOUNT_ID], + ) + + +@pytest.fixture +def mock_old_config_entry() -> MockConfigEntry: + """Mock an outdated config entry.""" + return MockConfigEntry( + domain=DOMAIN, + data={ + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], + }, + title=CONF[CONF_USERNAME], + unique_id=CONF[CONF_USERNAME], + version=1, + ) + + +@pytest.fixture +def mock_flick_client() -> Generator[AsyncMock]: + """Mock a Flick Electric client.""" + with ( + patch( + "homeassistant.components.flick_electric.FlickAPI", + autospec=True, + ) as mock_api, + patch( + "homeassistant.components.flick_electric.config_flow.FlickAPI", + new=mock_api, + ), + patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", + return_value="123456789abcdef", + ), + ): + api = mock_api.return_value + + api.getCustomerAccounts.return_value = json_api_doc.deserialize( + load_json_value_fixture("accounts.json", DOMAIN) + ) + api.getPricing.return_value = FlickPrice( + json_api_doc.deserialize( + load_json_value_fixture("rated_period.json", DOMAIN) + ) + ) + + yield api + + +@pytest.fixture +def mock_flick_client_multiple() -> Generator[AsyncMock]: + """Mock a Flick Electric with multiple accounts.""" + with ( + patch( + "homeassistant.components.flick_electric.FlickAPI", + autospec=True, + ) as mock_api, + patch( + "homeassistant.components.flick_electric.config_flow.FlickAPI", + new=mock_api, + ), + patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", + return_value="123456789abcdef", + ), + ): + api = mock_api.return_value + + api.getCustomerAccounts.return_value = json_api_doc.deserialize( + load_json_value_fixture("accounts_multi.json", DOMAIN) + ) + api.getPricing.return_value = FlickPrice( + json_api_doc.deserialize( + load_json_value_fixture("rated_period.json", DOMAIN) + ) + ) + + yield api diff --git a/tests/components/flick_electric/fixtures/accounts.json b/tests/components/flick_electric/fixtures/accounts.json new file mode 100644 index 00000000000..a1c08ecd7c0 --- /dev/null +++ b/tests/components/flick_electric/fixtures/accounts.json @@ -0,0 +1,105 @@ +{ + "data": [ + { + "id": "134800", + "type": "customer_account", + "attributes": { + "account_number": "10123404", + "billing_name": "9973debf-963f-49b0-9a73-Ba9c3400cbed@Anonymised Example", + "billing_email": null, + "address": "123 Fake Street, Newtown, Wellington 6021", + "brand": "flick", + "vulnerability_state": "none", + "medical_dependency": false, + "status": "active", + "start_at": "2023-03-02T00:00:00.000+13:00", + "end_at": null, + "application_id": "5dfc4978-07de-4d18-8ef7-055603805ba6", + "active": true, + "on_join_journey": false, + "placeholder": false + }, + "relationships": { + "user": { + "data": { + "id": "106676", + "type": "customer_user" + } + }, + "sign_up": { + "data": { + "id": "877039", + "type": "customer_sign_up" + } + }, + "main_customer": { + "data": { + "id": "108335", + "type": "customer_customer" + } + }, + "main_consumer": { + "data": { + "id": "108291", + "type": "customer_icp_consumer" + } + }, + "primary_contact": { + "data": { + "id": "121953", + "type": "customer_contact" + } + }, + "default_payment_method": { + "data": { + "id": "602801", + "type": "customer_payment_method" + } + }, + "phone_numbers": { + "data": [ + { + "id": "111604", + "type": "customer_phone_number" + } + ] + }, + "payment_methods": { + "data": [ + { + "id": "602801", + "type": "customer_payment_method" + } + ] + } + } + } + ], + "included": [ + { + "id": "108291", + "type": "customer_icp_consumer", + "attributes": { + "start_date": "2023-03-02", + "end_date": null, + "icp_number": "0001234567UNB12", + "supply_node_ref": "/network/nz/supply_nodes/ed7617df-4b10-4c8a-a05d-deadbeef8299", + "physical_address": "123 FAKE STREET,NEWTOWN,WELLINGTON,6021" + } + } + ], + "meta": { + "verb": "get", + "type": "customer_account", + "params": [], + "permission": { + "uri": "flick:customer_app:resource:account:list", + "data_context": null + }, + "host": "https://api.flickuat.com", + "service": "customer", + "path": "/accounts", + "description": "Returns the accounts viewable by the current user", + "respond_with_array": true + } +} diff --git a/tests/components/flick_electric/fixtures/accounts_multi.json b/tests/components/flick_electric/fixtures/accounts_multi.json new file mode 100644 index 00000000000..7c1f3fba2ef --- /dev/null +++ b/tests/components/flick_electric/fixtures/accounts_multi.json @@ -0,0 +1,144 @@ +{ + "data": [ + { + "id": "134800", + "type": "customer_account", + "attributes": { + "account_number": "10123404", + "billing_name": "9973debf-963f-49b0-9a73-Ba9c3400cbed@Anonymised Example", + "billing_email": null, + "address": "123 Fake Street, Newtown, Wellington 6021", + "brand": "flick", + "vulnerability_state": "none", + "medical_dependency": false, + "status": "active", + "start_at": "2023-03-02T00:00:00.000+13:00", + "end_at": null, + "application_id": "5dfc4978-07de-4d18-8ef7-055603805ba6", + "active": true, + "on_join_journey": false, + "placeholder": false + }, + "relationships": { + "user": { + "data": { + "id": "106676", + "type": "customer_user" + } + }, + "sign_up": { + "data": { + "id": "877039", + "type": "customer_sign_up" + } + }, + "main_customer": { + "data": { + "id": "108335", + "type": "customer_customer" + } + }, + "main_consumer": { + "data": { + "id": "108291", + "type": "customer_icp_consumer" + } + }, + "primary_contact": { + "data": { + "id": "121953", + "type": "customer_contact" + } + }, + "default_payment_method": { + "data": { + "id": "602801", + "type": "customer_payment_method" + } + }, + "phone_numbers": { + "data": [ + { + "id": "111604", + "type": "customer_phone_number" + } + ] + }, + "payment_methods": { + "data": [ + { + "id": "602801", + "type": "customer_payment_method" + } + ] + } + } + }, + { + "id": "123456", + "type": "customer_account", + "attributes": { + "account_number": "123123123", + "billing_name": "9973debf-963f-49b0-9a73-Ba9c3400cbed@Anonymised Example", + "billing_email": null, + "address": "456 Fake Street, Newtown, Wellington 6021", + "brand": "flick", + "vulnerability_state": "none", + "medical_dependency": false, + "status": "active", + "start_at": "2023-03-02T00:00:00.000+13:00", + "end_at": null, + "application_id": "5dfc4978-07de-4d18-8ef7-055603805ba6", + "active": true, + "on_join_journey": false, + "placeholder": false + }, + "relationships": { + "main_consumer": { + "data": { + "id": "11223344", + "type": "customer_icp_consumer" + } + } + } + } + ], + "included": [ + { + "id": "108291", + "type": "customer_icp_consumer", + "attributes": { + "start_date": "2023-03-02", + "end_date": null, + "icp_number": "0001234567UNB12", + "supply_node_ref": "/network/nz/supply_nodes/ed7617df-4b10-4c8a-a05d-deadbeef8299", + "physical_address": "123 FAKE STREET,NEWTOWN,WELLINGTON,6021" + } + }, + { + "id": "11223344", + "type": "customer_icp_consumer", + "attributes": { + "start_date": "2023-03-02", + "end_date": null, + "icp_number": "9991234567UNB12", + "supply_node_ref": "/network/nz/supply_nodes/ed7617df-4b10-4c8a-a05d-deadbeef1234", + "physical_address": "456 FAKE STREET,NEWTOWN,WELLINGTON,6021" + } + } + ], + "meta": { + "verb": "get", + "type": "customer_account", + "params": [], + "permission": { + "uri": "flick:customer_app:resource:account:list", + "data_context": null + }, + "host": "https://api.flickuat.com", + "service": "customer", + "path": "/accounts", + "description": "Returns the accounts viewable by the current user", + "respond_with_array": true + } +} diff --git a/tests/components/flick_electric/fixtures/rated_period.json b/tests/components/flick_electric/fixtures/rated_period.json new file mode 100644 index 00000000000..8e6ce96a9b7 --- /dev/null +++ b/tests/components/flick_electric/fixtures/rated_period.json @@ -0,0 +1,112 @@ +{ + "data": { + "id": "_2025-02-09 05:30:00 UTC..2025-02-09 05:59:59 UTC", + "type": "rating_rated_period", + "attributes": { + "start_at": "2025-02-09T05:30:00.000Z", + "end_at": "2025-02-09T05:59:59.000Z", + "status": "final", + "cost": "0.20011", + "import_cost": "0.20011", + "export_cost": null, + "cost_unit": "NZD", + "quantity": "1.0", + "import_quantity": "1.0", + "export_quantity": null, + "quantity_unit": "kwh", + "renewable_quantity": null, + "generation_price_contract": null + }, + "relationships": { + "components": { + "data": [ + { + "id": "213507464_1_kwh_generation_UN_24_default_2025-02-09 05:30:00 UTC..2025-02-09 05:59:59 UTC", + "type": "rating_component" + }, + { + "id": "213507464_1_kwh_network_UN_24_offpeak_2025-02-09 05:30:00 UTC..2025-02-09 05:59:59 UTC", + "type": "rating_component" + } + ] + } + } + }, + "included": [ + { + "id": "213507464_1_kwh_generation_UN_24_default_2025-02-09 05:30:00 UTC..2025-02-09 05:59:59 UTC", + "type": "rating_component", + "attributes": { + "charge_method": "kwh", + "charge_setter": "generation", + "value": "0.20011", + "quantity": "1.0", + "unit_code": "NZD", + "charge_per": "kwh", + "flow_direction": "import", + "content_code": "UN", + "hours_of_availability": 24, + "channel_number": 1, + "meter_serial_number": "213507464", + "price_name": "default", + "applicable_periods": [], + "single_unit_price": "0.20011", + "billable": true, + "renewable_quantity": null, + "generation_price_contract": "FLICK_FLAT_2024_04_01_midpoint" + } + }, + { + "id": "213507464_1_kwh_network_UN_24_offpeak_2025-02-09 05:30:00 UTC..2025-02-09 05:59:59 UTC", + "type": "rating_component", + "attributes": { + "charge_method": "kwh", + "charge_setter": "network", + "value": "0.0406", + "quantity": "1.0", + "unit_code": "NZD", + "charge_per": "kwh", + "flow_direction": "import", + "content_code": "UN", + "hours_of_availability": 24, + "channel_number": 1, + "meter_serial_number": "213507464", + "price_name": "offpeak", + "applicable_periods": [], + "single_unit_price": "0.0406", + "billable": false, + "renewable_quantity": null, + "generation_price_contract": "FLICK_FLAT_2024_04_01_midpoint" + } + } + ], + "meta": { + "verb": "get", + "type": "rating_rated_period", + "params": [ + { + "name": "supply_node_ref", + "type": "String", + "description": "The supply node to rate", + "example": "/network/nz/supply_nodes/bccd6f52-448b-4edf-a0c1-459ee67d215b", + "required": true + }, + { + "name": "as_at", + "type": "DateTime", + "description": "The time to rate the supply node at; defaults to the current time", + "example": "2023-04-01T15:20:15-07:00", + "required": false + } + ], + "permission": { + "uri": "flick:rating:resource:rated_period:show", + "data_context": "supply_node" + }, + "host": "https://api.flickuat.com", + "service": "rating", + "path": "/rated_period", + "description": "Fetch a rated period for a supply node in a specific point in time", + "respond_with_array": false + } +} diff --git a/tests/components/flick_electric/test_config_flow.py b/tests/components/flick_electric/test_config_flow.py index 7ac605f1c8c..c14303278a3 100644 --- a/tests/components/flick_electric/test_config_flow.py +++ b/tests/components/flick_electric/test_config_flow.py @@ -1,6 +1,6 @@ """Test the Flick Electric config flow.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch from pyflick.authentication import AuthException from pyflick.types import APIException @@ -16,10 +16,16 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType -from . import CONF, _mock_flick_price +from . import CONF, setup_integration from tests.common import MockConfigEntry +# From test fixtures +ACCOUNT_NAME_1 = "123 Fake Street, Newtown, Wellington 6021" +ACCOUNT_NAME_2 = "456 Fake Street, Newtown, Wellington 6021" +ACCOUNT_ID_2 = "123456" +SUPPLY_NODE_REF_2 = "/network/nz/supply_nodes/ed7617df-4b10-4c8a-a05d-deadbeef1234" + async def _flow_submit(hass: HomeAssistant) -> ConfigFlowResult: return await hass.config_entries.flow.async_init( @@ -32,7 +38,7 @@ async def _flow_submit(hass: HomeAssistant) -> ConfigFlowResult: ) -async def test_form(hass: HomeAssistant) -> None: +async def test_form(hass: HomeAssistant, mock_flick_client: AsyncMock) -> None: """Test we get the form with only one, with no account picker.""" result = await hass.config_entries.flow.async_init( @@ -41,48 +47,24 @@ async def test_form(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - } - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - patch( - "homeassistant.components.flick_electric.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - await hass.async_block_till_done() + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], + }, + ) + await hass.async_block_till_done() assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "123 Fake St" + assert result2["title"] == ACCOUNT_NAME_1 assert result2["data"] == CONF - assert result2["result"].unique_id == "1234" - assert len(mock_setup_entry.mock_calls) == 1 + assert result2["result"].unique_id == CONF[CONF_ACCOUNT_ID] -async def test_form_multi_account(hass: HomeAssistant) -> None: +async def test_form_multi_account( + hass: HomeAssistant, mock_flick_client_multiple: AsyncMock +) -> None: """Test the form when multiple accounts are available.""" result = await hass.config_entries.flow.async_init( @@ -91,272 +73,114 @@ async def test_form_multi_account(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - patch( - "homeassistant.components.flick_electric.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - await hass.async_block_till_done() + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], + }, + ) + await hass.async_block_till_done() - assert result2["type"] is FlowResultType.FORM - assert result2["step_id"] == "select_account" - assert len(mock_setup_entry.mock_calls) == 0 + assert result2["type"] is FlowResultType.FORM + assert result2["step_id"] == "select_account" - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], - {"account_id": "5678"}, - ) + result3 = await hass.config_entries.flow.async_configure( + result2["flow_id"], + {CONF_ACCOUNT_ID: ACCOUNT_ID_2}, + ) - await hass.async_block_till_done() + await hass.async_block_till_done() - assert result3["type"] is FlowResultType.CREATE_ENTRY - assert result3["title"] == "456 Fake St" - assert result3["data"] == { - **CONF, - CONF_SUPPLY_NODE_REF: "456", - CONF_ACCOUNT_ID: "5678", - } - assert result3["result"].unique_id == "5678" - assert len(mock_setup_entry.mock_calls) == 1 + assert result3["type"] is FlowResultType.CREATE_ENTRY + assert result3["title"] == ACCOUNT_NAME_2 + assert result3["data"] == { + **CONF, + CONF_SUPPLY_NODE_REF: SUPPLY_NODE_REF_2, + CONF_ACCOUNT_ID: ACCOUNT_ID_2, + } + assert result3["result"].unique_id == ACCOUNT_ID_2 -async def test_reauth_token(hass: HomeAssistant) -> None: +async def test_reauth_token( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: """Test reauth flow when username/password is wrong.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={**CONF}, - title="123 Fake St", - unique_id="1234", - version=2, + await setup_integration(hass, mock_config_entry) + + with patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", + side_effect=AuthException, + ): + result = await mock_config_entry.start_reauth_flow(hass) + + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": "invalid_auth"} + assert result["step_id"] == "user" + + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: CONF[CONF_USERNAME], CONF_PASSWORD: CONF[CONF_PASSWORD]}, ) - entry.add_to_hass(hass) - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - side_effect=AuthException, - ), - ): - result = await entry.start_reauth_flow(hass) - - assert result["type"] is FlowResultType.FORM - assert result["errors"] == {"base": "invalid_auth"} - assert result["step_id"] == "user" - - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - patch( - "homeassistant.config_entries.ConfigEntries.async_update_entry", - return_value=True, - ) as mock_update_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - - assert result2["type"] is FlowResultType.ABORT - assert result2["reason"] == "reauth_successful" - assert len(mock_update_entry.mock_calls) > 0 + assert result2["type"] is FlowResultType.ABORT + assert result2["reason"] == "reauth_successful" -async def test_form_reauth_migrate(hass: HomeAssistant) -> None: +async def test_form_reauth_migrate( + hass: HomeAssistant, + mock_old_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: """Test reauth flow for v1 with single account.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={ - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - title="123 Fake St", - unique_id="test-username", - version=1, - ) - entry.add_to_hass(hass) + mock_old_config_entry.add_to_hass(hass) + result = await mock_old_config_entry.start_reauth_flow(hass) - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - ): - result = await entry.start_reauth_flow(hass) - - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "reauth_successful" - assert entry.version == 2 - assert entry.unique_id == "1234" - assert entry.data == CONF + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reauth_successful" + assert mock_old_config_entry.version == 2 + assert mock_old_config_entry.unique_id == CONF[CONF_ACCOUNT_ID] + assert mock_old_config_entry.data == CONF -async def test_form_reauth_migrate_multi_account(hass: HomeAssistant) -> None: +async def test_form_reauth_migrate_multi_account( + hass: HomeAssistant, + mock_old_config_entry: MockConfigEntry, + mock_flick_client_multiple: AsyncMock, +) -> None: """Test the form when multiple accounts are available.""" + mock_old_config_entry.add_to_hass(hass) + result = await mock_old_config_entry.start_reauth_flow(hass) - entry = MockConfigEntry( - domain=DOMAIN, - data={ - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - title="123 Fake St", - unique_id="test-username", - version=1, + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "select_account" + + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_ACCOUNT_ID: CONF[CONF_ACCOUNT_ID]}, ) - entry.add_to_hass(hass) - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - ): - result = await entry.start_reauth_flow(hass) + await hass.async_block_till_done() - assert result["type"] is FlowResultType.FORM - assert result["step_id"] == "select_account" + assert result2["type"] is FlowResultType.ABORT + assert result2["reason"] == "reauth_successful" - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {"account_id": "5678"}, - ) - - await hass.async_block_till_done() - - assert result2["type"] is FlowResultType.ABORT - assert result2["reason"] == "reauth_successful" - - assert entry.version == 2 - assert entry.unique_id == "5678" - assert entry.data == { - **CONF, - CONF_ACCOUNT_ID: "5678", - CONF_SUPPLY_NODE_REF: "456", - } + assert mock_old_config_entry.version == 2 + assert mock_old_config_entry.unique_id == CONF[CONF_ACCOUNT_ID] + assert mock_old_config_entry.data == CONF -async def test_form_duplicate_account(hass: HomeAssistant) -> None: +async def test_form_duplicate_account( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: """Test uniqueness for account_id.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={**CONF, CONF_ACCOUNT_ID: "1234", CONF_SUPPLY_NODE_REF: "123"}, - title="123 Fake St", - unique_id="1234", - version=2, - ) - entry.add_to_hass(hass) + await setup_integration(hass, mock_config_entry) - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - } - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - ): - result = await _flow_submit(hass) + result = await _flow_submit(hass) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "already_configured" @@ -398,7 +222,9 @@ async def test_form_generic_exception(hass: HomeAssistant) -> None: assert result["errors"] == {"base": "unknown"} -async def test_form_select_account_cannot_connect(hass: HomeAssistant) -> None: +async def test_form_select_account_cannot_connect( + hass: HomeAssistant, mock_flick_client_multiple: AsyncMock +) -> None: """Test we handle connection errors for select account.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -406,38 +232,16 @@ async def test_form_select_account_cannot_connect(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - side_effect=APIException, - ), + with patch.object( + mock_flick_client_multiple, + "getPricing", + side_effect=APIException, ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], }, ) await hass.async_block_till_done() @@ -447,7 +251,7 @@ async def test_form_select_account_cannot_connect(hass: HomeAssistant) -> None: result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], - {"account_id": "5678"}, + {CONF_ACCOUNT_ID: CONF[CONF_ACCOUNT_ID]}, ) assert result3["type"] is FlowResultType.FORM @@ -455,7 +259,9 @@ async def test_form_select_account_cannot_connect(hass: HomeAssistant) -> None: assert result3["errors"] == {"base": "cannot_connect"} -async def test_form_select_account_invalid_auth(hass: HomeAssistant) -> None: +async def test_form_select_account_invalid_auth( + hass: HomeAssistant, mock_flick_client_multiple: AsyncMock +) -> None: """Test we handle auth errors for select account.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -463,65 +269,41 @@ async def test_form_select_account_invalid_auth(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - side_effect=AuthException, - ), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - await hass.async_block_till_done() + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], + }, + ) + await hass.async_block_till_done() - assert result2["type"] is FlowResultType.FORM - assert result2["step_id"] == "select_account" + assert result2["type"] is FlowResultType.FORM + assert result2["step_id"] == "select_account" with ( patch( "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", side_effect=AuthException, ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", + patch.object( + mock_flick_client_multiple, + "getPricing", side_effect=AuthException, ), ): result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], - {"account_id": "5678"}, + {CONF_ACCOUNT_ID: CONF[CONF_ACCOUNT_ID]}, ) assert result3["type"] is FlowResultType.ABORT assert result3["reason"] == "no_permissions" -async def test_form_select_account_failed_to_connect(hass: HomeAssistant) -> None: +async def test_form_select_account_failed_to_connect( + hass: HomeAssistant, mock_flick_client_multiple: AsyncMock +) -> None: """Test we handle connection errors for select account.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -529,115 +311,56 @@ async def test_form_select_account_failed_to_connect(hass: HomeAssistant) -> Non assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - side_effect=AuthException, - ), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - await hass.async_block_till_done() + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], + }, + ) + await hass.async_block_till_done() - assert result2["type"] is FlowResultType.FORM - assert result2["step_id"] == "select_account" + assert result2["type"] is FlowResultType.FORM + assert result2["step_id"] == "select_account" with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", + patch.object( + mock_flick_client_multiple, + "getCustomerAccounts", side_effect=APIException, ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", + patch.object( + mock_flick_client_multiple, + "getPricing", side_effect=APIException, ), ): result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], - {"account_id": "5678"}, + {CONF_ACCOUNT_ID: CONF[CONF_ACCOUNT_ID]}, ) assert result3["type"] is FlowResultType.FORM assert result3["errors"] == {"base": "cannot_connect"} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - patch( - "homeassistant.components.flick_electric.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result4 = await hass.config_entries.flow.async_configure( - result3["flow_id"], - {"account_id": "5678"}, - ) + result4 = await hass.config_entries.flow.async_configure( + result3["flow_id"], + {CONF_ACCOUNT_ID: ACCOUNT_ID_2}, + ) - assert result4["type"] is FlowResultType.CREATE_ENTRY - assert result4["title"] == "456 Fake St" - assert result4["data"] == { - **CONF, - CONF_SUPPLY_NODE_REF: "456", - CONF_ACCOUNT_ID: "5678", - } - assert result4["result"].unique_id == "5678" - assert len(mock_setup_entry.mock_calls) == 1 + assert result4["type"] is FlowResultType.CREATE_ENTRY + assert result4["title"] == ACCOUNT_NAME_2 + assert result4["data"] == { + **CONF, + CONF_SUPPLY_NODE_REF: SUPPLY_NODE_REF_2, + CONF_ACCOUNT_ID: ACCOUNT_ID_2, + } + assert result4["result"].unique_id == ACCOUNT_ID_2 -async def test_form_select_account_no_accounts(hass: HomeAssistant) -> None: +async def test_form_select_account_no_accounts( + hass: HomeAssistant, mock_flick_client: AsyncMock +) -> None: """Test we handle connection errors for select account.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -645,28 +368,23 @@ async def test_form_select_account_no_accounts(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.config_flow.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "closed", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - ], - ), + with patch.object( + mock_flick_client, + "getCustomerAccounts", + return_value=[ + { + "id": "1234", + "status": "closed", + "address": "123 Fake St", + "main_consumer": {"supply_node_ref": "123"}, + }, + ], ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", + CONF_USERNAME: CONF[CONF_USERNAME], + CONF_PASSWORD: CONF[CONF_PASSWORD], }, ) await hass.async_block_till_done() diff --git a/tests/components/flick_electric/test_init.py b/tests/components/flick_electric/test_init.py index e022b6e03bc..d420a78ccfc 100644 --- a/tests/components/flick_electric/test_init.py +++ b/tests/components/flick_electric/test_init.py @@ -1,135 +1,154 @@ """Test the Flick Electric config flow.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch -from pyflick.authentication import AuthException +import jwt +from pyflick.types import APIException, AuthException +import pytest -from homeassistant.components.flick_electric.const import CONF_ACCOUNT_ID, DOMAIN +from homeassistant.components.flick_electric import CONF_ID_TOKEN, HassFlickAuth +from homeassistant.components.flick_electric.const import ( + CONF_ACCOUNT_ID, + CONF_TOKEN_EXPIRY, +) from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant +from homeassistant.util import dt as dt_util -from . import CONF, _mock_flick_price +from . import CONF, setup_integration from tests.common import MockConfigEntry - -async def test_init_auth_failure_triggers_auth(hass: HomeAssistant) -> None: - """Test reauth flow is triggered when username/password is wrong.""" - with ( - patch( - "homeassistant.components.flick_electric.HassFlickAuth.async_get_access_token", - side_effect=AuthException, - ), - ): - entry = MockConfigEntry( - domain=DOMAIN, - data={**CONF}, - title="123 Fake St", - unique_id="1234", - version=2, - ) - entry.add_to_hass(hass) - - # Ensure setup fails - assert not await hass.config_entries.async_setup(entry.entry_id) - assert entry.state is ConfigEntryState.SETUP_ERROR - - # Ensure reauth flow is triggered - await hass.async_block_till_done() - assert len(hass.config_entries.flow.async_progress()) == 1 +NEW_TOKEN = jwt.encode( + {"exp": dt_util.now().timestamp() + 86400}, "secret", algorithm="HS256" +) +EXISTING_TOKEN = jwt.encode( + {"exp": dt_util.now().timestamp() + 3600}, "secret", algorithm="HS256" +) +EXPIRED_TOKEN = jwt.encode( + {"exp": dt_util.now().timestamp() - 3600}, "secret", algorithm="HS256" +) -async def test_init_migration_single_account(hass: HomeAssistant) -> None: +@pytest.mark.parametrize( + ("exception", "config_entry_state"), + [ + (AuthException, ConfigEntryState.SETUP_ERROR), + (APIException, ConfigEntryState.SETUP_RETRY), + ], +) +async def test_init_auth_failure_triggers_auth( + hass: HomeAssistant, + mock_flick_client: AsyncMock, + mock_config_entry: MockConfigEntry, + exception: Exception, + config_entry_state: ConfigEntryState, +) -> None: + """Test integration handles initialisation errors.""" + with patch.object(mock_flick_client, "getPricing", side_effect=exception): + await setup_integration(hass, mock_config_entry) + + assert mock_config_entry.state == config_entry_state + + +async def test_init_migration_single_account( + hass: HomeAssistant, + mock_old_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: """Test migration with single account.""" - with ( - patch( - "homeassistant.components.flick_electric.HassFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - } - ], - ), - patch( - "homeassistant.components.flick_electric.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - ): - entry = MockConfigEntry( - domain=DOMAIN, - data={ - CONF_USERNAME: CONF[CONF_USERNAME], - CONF_PASSWORD: CONF[CONF_PASSWORD], - }, - title=CONF_USERNAME, - unique_id=CONF_USERNAME, - version=1, - ) - entry.add_to_hass(hass) + await setup_integration(hass, mock_old_config_entry) - assert await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - assert len(hass.config_entries.flow.async_progress()) == 0 - assert entry.state is ConfigEntryState.LOADED - assert entry.version == 2 - assert entry.unique_id == CONF[CONF_ACCOUNT_ID] - assert entry.data == CONF + assert len(hass.config_entries.flow.async_progress()) == 0 + assert mock_old_config_entry.state is ConfigEntryState.LOADED + assert mock_old_config_entry.version == 2 + assert mock_old_config_entry.unique_id == CONF[CONF_ACCOUNT_ID] + assert mock_old_config_entry.data == CONF -async def test_init_migration_multi_account_reauth(hass: HomeAssistant) -> None: +async def test_init_migration_multi_account_reauth( + hass: HomeAssistant, + mock_old_config_entry: MockConfigEntry, + mock_flick_client_multiple: AsyncMock, +) -> None: """Test migration triggers reauth with multiple accounts.""" - with ( - patch( - "homeassistant.components.flick_electric.HassFlickAuth.async_get_access_token", - return_value="123456789abcdef", - ), - patch( - "homeassistant.components.flick_electric.FlickAPI.getCustomerAccounts", - return_value=[ - { - "id": "1234", - "status": "active", - "address": "123 Fake St", - "main_consumer": {"supply_node_ref": "123"}, - }, - { - "id": "5678", - "status": "active", - "address": "456 Fake St", - "main_consumer": {"supply_node_ref": "456"}, - }, - ], - ), - patch( - "homeassistant.components.flick_electric.FlickAPI.getPricing", - return_value=_mock_flick_price(), - ), - ): - entry = MockConfigEntry( - domain=DOMAIN, - data={ - CONF_USERNAME: CONF[CONF_USERNAME], - CONF_PASSWORD: CONF[CONF_PASSWORD], - }, - title=CONF_USERNAME, - unique_id=CONF_USERNAME, - version=1, - ) - entry.add_to_hass(hass) + await setup_integration(hass, mock_old_config_entry) - # ensure setup fails - assert not await hass.config_entries.async_setup(entry.entry_id) - assert entry.state is ConfigEntryState.MIGRATION_ERROR - await hass.async_block_till_done() + assert mock_old_config_entry.state is ConfigEntryState.MIGRATION_ERROR - # Ensure reauth flow is triggered - await hass.async_block_till_done() - assert len(hass.config_entries.flow.async_progress()) == 1 + # Ensure reauth flow is triggered + await hass.async_block_till_done() + assert len(hass.config_entries.flow.async_progress()) == 1 + + +async def test_fetch_fresh_token( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: + """Test fetching a fresh token.""" + await setup_integration(hass, mock_config_entry) + + with patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.get_new_token", + return_value={CONF_ID_TOKEN: NEW_TOKEN}, + ) as mock_get_new_token: + auth = HassFlickAuth(hass, mock_config_entry) + + assert await auth.async_get_access_token() == NEW_TOKEN + assert mock_get_new_token.call_count == 1 + + +async def test_reuse_token( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: + """Test reusing entry token.""" + await setup_integration(hass, mock_config_entry) + + hass.config_entries.async_update_entry( + mock_config_entry, + data={ + **mock_config_entry.data, + CONF_ACCESS_TOKEN: {CONF_ID_TOKEN: EXISTING_TOKEN}, + CONF_TOKEN_EXPIRY: dt_util.now().timestamp() + 3600, + }, + ) + + with patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.get_new_token", + return_value={CONF_ID_TOKEN: NEW_TOKEN}, + ) as mock_get_new_token: + auth = HassFlickAuth(hass, mock_config_entry) + + assert await auth.async_get_access_token() == EXISTING_TOKEN + assert mock_get_new_token.call_count == 0 + + +async def test_fetch_expired_token( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_flick_client: AsyncMock, +) -> None: + """Test fetching token when existing token is expired.""" + await setup_integration(hass, mock_config_entry) + + hass.config_entries.async_update_entry( + mock_config_entry, + data={ + **mock_config_entry.data, + CONF_ACCESS_TOKEN: {CONF_ID_TOKEN: EXPIRED_TOKEN}, + CONF_TOKEN_EXPIRY: dt_util.now().timestamp() - 3600, + }, + ) + + with patch( + "homeassistant.components.flick_electric.config_flow.SimpleFlickAuth.get_new_token", + return_value={CONF_ID_TOKEN: NEW_TOKEN}, + ) as mock_get_new_token: + auth = HassFlickAuth(hass, mock_config_entry) + + assert await auth.async_get_access_token() == NEW_TOKEN + assert mock_get_new_token.call_count == 1 diff --git a/tests/components/flo/snapshots/test_init.ambr b/tests/components/flo/snapshots/test_init.ambr new file mode 100644 index 00000000000..edba0ebe162 --- /dev/null +++ b/tests/components/flo/snapshots/test_init.ambr @@ -0,0 +1,75 @@ +# serializer version: 1 +# name: test_setup_entry + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + tuple( + 'mac', + '11:11:11:11:11:11', + ), + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'flo', + '98765', + ), + }), + 'is_new': False, + 'labels': set({ + }), + 'manufacturer': 'Flo by Moen', + 'model': 'flo_device_075_v2', + 'model_id': None, + 'name': 'Smart water shutoff', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': '111111111111', + 'suggested_area': None, + 'sw_version': '6.1.1', + 'via_device_id': None, + }), + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + tuple( + 'mac', + '1a:2b:3c:4d:5e:6f', + ), + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'flo', + '32839', + ), + }), + 'is_new': False, + 'labels': set({ + }), + 'manufacturer': 'Flo by Moen', + 'model': 'puck_v1', + 'model_id': None, + 'name': 'Kitchen sink', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': '111111111112', + 'suggested_area': None, + 'sw_version': '1.1.15', + 'via_device_id': None, + }), + ]) +# --- diff --git a/tests/components/flo/test_binary_sensor.py b/tests/components/flo/test_binary_sensor.py index 23a84734b0d..9c174abb0d6 100644 --- a/tests/components/flo/test_binary_sensor.py +++ b/tests/components/flo/test_binary_sensor.py @@ -2,18 +2,8 @@ import pytest -from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN -from homeassistant.const import ( - ATTR_FRIENDLY_NAME, - CONF_PASSWORD, - CONF_USERNAME, - STATE_OFF, - STATE_ON, -) +from homeassistant.const import ATTR_FRIENDLY_NAME, STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from .common import TEST_PASSWORD, TEST_USER_ID from tests.common import MockConfigEntry @@ -24,13 +14,9 @@ async def test_binary_sensors( ) -> None: """Test Flo by Moen sensors.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 - valve_state = hass.states.get( "binary_sensor.smart_water_shutoff_pending_system_alerts" ) diff --git a/tests/components/flo/test_device.py b/tests/components/flo/test_device.py index c3e26e77370..b89d5a1e68c 100644 --- a/tests/components/flo/test_device.py +++ b/tests/components/flo/test_device.py @@ -7,13 +7,8 @@ from aioflo.errors import RequestError from freezegun.api import FrozenDateTimeFactory import pytest -from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN -from homeassistant.components.flo.coordinator import FloDeviceDataUpdateCoordinator -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, STATE_UNAVAILABLE +from homeassistant.const import STATE_UNAVAILABLE from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from .common import TEST_PASSWORD, TEST_USER_ID from tests.common import MockConfigEntry, async_fire_time_changed from tests.test_util.aiohttp import AiohttpClientMocker @@ -28,59 +23,8 @@ async def test_device( ) -> None: """Test Flo by Moen devices.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 - - valve: FloDeviceDataUpdateCoordinator = hass.data[FLO_DOMAIN][ - config_entry.entry_id - ]["devices"][0] - assert valve.api_client is not None - assert valve.available - assert valve.consumption_today == 3.674 - assert valve.current_flow_rate == 0 - assert valve.current_psi == 54.20000076293945 - assert valve.current_system_mode == "home" - assert valve.target_system_mode == "home" - assert valve.firmware_version == "6.1.1" - assert valve.device_type == "flo_device_v2" - assert valve.id == "98765" - assert valve.last_heard_from_time == "2020-07-24T12:45:00Z" - assert valve.location_id == "mmnnoopp" - assert valve.hass is not None - assert valve.temperature == 70 - assert valve.mac_address == "111111111111" - assert valve.model == "flo_device_075_v2" - assert valve.manufacturer == "Flo by Moen" - assert valve.device_name == "Smart Water Shutoff" - assert valve.rssi == -47 - assert valve.pending_info_alerts_count == 0 - assert valve.pending_critical_alerts_count == 0 - assert valve.pending_warning_alerts_count == 2 - assert valve.has_alerts is True - assert valve.last_known_valve_state == "open" - assert valve.target_valve_state == "open" - - detector: FloDeviceDataUpdateCoordinator = hass.data[FLO_DOMAIN][ - config_entry.entry_id - ]["devices"][1] - assert detector.api_client is not None - assert detector.available - assert detector.device_type == "puck_oem" - assert detector.id == "32839" - assert detector.last_heard_from_time == "2021-03-07T14:05:00Z" - assert detector.location_id == "mmnnoopp" - assert detector.hass is not None - assert detector.temperature == 61 - assert detector.humidity == 43 - assert detector.water_detected is False - assert detector.mac_address == "1a2b3c4d5e6f" - assert detector.model == "puck_v1" - assert detector.manufacturer == "Flo by Moen" - assert detector.device_name == "Kitchen Sink" - assert detector.serial_number == "111111111112" call_count = aioclient_mock.call_count diff --git a/tests/components/flo/test_init.py b/tests/components/flo/test_init.py index 805a6278395..c1983b898da 100644 --- a/tests/components/flo/test_init.py +++ b/tests/components/flo/test_init.py @@ -1,25 +1,32 @@ """Test init.""" import pytest +from syrupy import SnapshotAssertion -from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from .common import TEST_PASSWORD, TEST_USER_ID +from homeassistant.helpers import device_registry as dr from tests.common import MockConfigEntry @pytest.mark.usefixtures("aioclient_mock_fixture") -async def test_setup_entry(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: +async def test_setup_entry( + hass: HomeAssistant, + config_entry: MockConfigEntry, + device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, +) -> None: """Test migration of config entry from v1.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 + assert config_entry.state is ConfigEntryState.LOADED + + assert ( + dr.async_entries_for_config_entry(device_registry, config_entry.entry_id) + == snapshot + ) assert await hass.config_entries.async_unload(config_entry.entry_id) + assert config_entry.state is ConfigEntryState.NOT_LOADED diff --git a/tests/components/flo/test_sensor.py b/tests/components/flo/test_sensor.py index 0c763927296..828e4f3b4d5 100644 --- a/tests/components/flo/test_sensor.py +++ b/tests/components/flo/test_sensor.py @@ -2,15 +2,12 @@ import pytest -from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorStateClass -from homeassistant.const import ATTR_ENTITY_ID, CONF_PASSWORD, CONF_USERNAME +from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM -from .common import TEST_PASSWORD, TEST_USER_ID - from tests.common import MockConfigEntry from tests.test_util.aiohttp import AiohttpClientMocker @@ -20,13 +17,9 @@ async def test_sensors(hass: HomeAssistant, config_entry: MockConfigEntry) -> No """Test Flo by Moen sensors.""" hass.config.units = US_CUSTOMARY_SYSTEM config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 - # we should have 5 entities for the valve assert ( hass.states.get("sensor.smart_water_shutoff_current_system_mode").state @@ -95,13 +88,9 @@ async def test_manual_update_entity( ) -> None: """Test manual update entity via service homeasasistant/update_entity.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 - await async_setup_component(hass, "homeassistant", {}) call_count = aioclient_mock.call_count diff --git a/tests/components/flo/test_services.py b/tests/components/flo/test_services.py index 565f39f69fe..980d5906a56 100644 --- a/tests/components/flo/test_services.py +++ b/tests/components/flo/test_services.py @@ -13,11 +13,8 @@ from homeassistant.components.flo.switch import ( SERVICE_SET_SLEEP_MODE, SYSTEM_MODE_HOME, ) -from homeassistant.const import ATTR_ENTITY_ID, CONF_PASSWORD, CONF_USERNAME +from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from .common import TEST_PASSWORD, TEST_USER_ID from tests.common import MockConfigEntry from tests.test_util.aiohttp import AiohttpClientMocker @@ -33,12 +30,9 @@ async def test_services( ) -> None: """Test Flo services.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 assert aioclient_mock.call_count == 8 await hass.services.async_call( diff --git a/tests/components/flo/test_switch.py b/tests/components/flo/test_switch.py index 5c124d312a7..86fa8dd522d 100644 --- a/tests/components/flo/test_switch.py +++ b/tests/components/flo/test_switch.py @@ -2,13 +2,9 @@ import pytest -from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, STATE_OFF, STATE_ON +from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from .common import TEST_PASSWORD, TEST_USER_ID from tests.common import MockConfigEntry @@ -19,13 +15,9 @@ async def test_valve_switches( ) -> None: """Test Flo by Moen valve switches.""" config_entry.add_to_hass(hass) - assert await async_setup_component( - hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} - ) + assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert len(hass.data[FLO_DOMAIN][config_entry.entry_id]["devices"]) == 2 - entity_id = "switch.smart_water_shutoff_shutoff_valve" assert hass.states.get(entity_id).state == STATE_ON diff --git a/tests/components/folder_watcher/snapshots/test_event.ambr b/tests/components/folder_watcher/snapshots/test_event.ambr index 04405e0694b..1101380703a 100644 --- a/tests/components/folder_watcher/snapshots/test_event.ambr +++ b/tests/components/folder_watcher/snapshots/test_event.ambr @@ -14,6 +14,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/forecast_solar/snapshots/test_init.ambr b/tests/components/forecast_solar/snapshots/test_init.ambr index 6ae4c2f6198..c0db54c2d4e 100644 --- a/tests/components/forecast_solar/snapshots/test_init.ambr +++ b/tests/components/forecast_solar/snapshots/test_init.ambr @@ -23,6 +23,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Green House', 'unique_id': 'unique', 'version': 2, diff --git a/tests/components/fritz/snapshots/test_button.ambr b/tests/components/fritz/snapshots/test_button.ambr index ed0b0e72160..748d8c1ba29 100644 --- a/tests/components/fritz/snapshots/test_button.ambr +++ b/tests/components/fritz/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fritz/snapshots/test_diagnostics.ambr b/tests/components/fritz/snapshots/test_diagnostics.ambr index 53f7093a21b..9b5b8c9353a 100644 --- a/tests/components/fritz/snapshots/test_diagnostics.ambr +++ b/tests/components/fritz/snapshots/test_diagnostics.ambr @@ -61,6 +61,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/fritz/snapshots/test_sensor.ambr b/tests/components/fritz/snapshots/test_sensor.ambr index 50744815aa5..5ff0e448b15 100644 --- a/tests/components/fritz/snapshots/test_sensor.ambr +++ b/tests/components/fritz/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -249,6 +254,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -298,6 +304,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -345,6 +352,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -392,6 +400,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -439,6 +448,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -487,6 +497,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +545,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -581,6 +593,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -629,6 +642,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -677,6 +691,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -727,6 +742,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fritz/snapshots/test_switch.ambr b/tests/components/fritz/snapshots/test_switch.ambr index b34a3626fe2..a1097d3333b 100644 --- a/tests/components/fritz/snapshots/test_switch.ambr +++ b/tests/components/fritz/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -382,6 +390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -482,6 +492,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -529,6 +540,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fritz/snapshots/test_update.ambr b/tests/components/fritz/snapshots/test_update.ambr index 3c7880d01e7..746823e9dc9 100644 --- a/tests/components/fritz/snapshots/test_update.ambr +++ b/tests/components/fritz/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fronius/snapshots/test_diagnostics.ambr b/tests/components/fronius/snapshots/test_diagnostics.ambr index 010de06e276..b112839835a 100644 --- a/tests/components/fronius/snapshots/test_diagnostics.ambr +++ b/tests/components/fronius/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/fronius/snapshots/test_sensor.ambr b/tests/components/fronius/snapshots/test_sensor.ambr index 81770893273..5384e9c6389 100644 --- a/tests/components/fronius/snapshots/test_sensor.ambr +++ b/tests/components/fronius/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -363,6 +370,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -508,6 +516,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -655,6 +664,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -704,6 +714,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -750,6 +761,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -807,6 +819,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -866,6 +879,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -917,6 +931,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -968,6 +983,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1019,6 +1035,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1070,6 +1087,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1121,6 +1139,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1172,6 +1191,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1223,6 +1243,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1274,6 +1295,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1323,6 +1345,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1377,6 +1400,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1433,6 +1457,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1483,6 +1508,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1533,6 +1559,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1583,6 +1610,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1633,6 +1661,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1683,6 +1712,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1733,6 +1763,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1784,6 +1815,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1835,6 +1867,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1886,6 +1919,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1937,6 +1971,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1988,6 +2023,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2039,6 +2075,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2090,6 +2127,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2141,6 +2179,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2192,6 +2231,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2243,6 +2283,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2294,6 +2335,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2345,6 +2387,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2396,6 +2439,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2447,6 +2491,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2498,6 +2543,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2549,6 +2595,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2600,6 +2647,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2649,6 +2697,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2697,6 +2746,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2748,6 +2798,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2799,6 +2850,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2850,6 +2902,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2901,6 +2954,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2952,6 +3006,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3003,6 +3058,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3054,6 +3110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3104,6 +3161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3154,6 +3212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3205,6 +3264,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3256,6 +3316,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3305,6 +3366,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3352,6 +3414,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3401,6 +3464,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3452,6 +3516,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3503,6 +3568,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3554,6 +3620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3605,6 +3672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3656,6 +3724,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3707,6 +3776,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3758,6 +3828,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3809,6 +3880,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3858,6 +3930,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4003,6 +4076,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4150,6 +4224,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4199,6 +4274,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4245,6 +4321,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4302,6 +4379,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4361,6 +4439,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4412,6 +4491,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4463,6 +4543,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4512,6 +4593,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4567,6 +4649,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4624,6 +4707,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4675,6 +4759,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4726,6 +4811,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4777,6 +4863,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4828,6 +4915,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4879,6 +4967,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4930,6 +5019,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4981,6 +5071,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5032,6 +5123,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5081,6 +5173,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5135,6 +5228,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5191,6 +5285,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5241,6 +5336,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5291,6 +5387,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5341,6 +5438,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5391,6 +5489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5441,6 +5540,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5491,6 +5591,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5542,6 +5643,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5593,6 +5695,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5644,6 +5747,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5695,6 +5799,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5746,6 +5851,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5797,6 +5903,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5848,6 +5955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5899,6 +6007,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5950,6 +6059,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6001,6 +6111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6052,6 +6163,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6103,6 +6215,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6154,6 +6267,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6205,6 +6319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6256,6 +6371,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6307,6 +6423,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6358,6 +6475,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6407,6 +6525,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6455,6 +6574,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6506,6 +6626,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6557,6 +6678,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6608,6 +6730,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6659,6 +6782,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6710,6 +6834,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6761,6 +6886,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6812,6 +6938,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6863,6 +6990,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6914,6 +7042,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6965,6 +7094,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7015,6 +7145,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7065,6 +7196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7116,6 +7248,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7167,6 +7300,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7218,6 +7352,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7269,6 +7404,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7320,6 +7456,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7371,6 +7508,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7422,6 +7560,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7471,6 +7610,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7616,6 +7756,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7763,6 +7904,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7812,6 +7954,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7858,6 +8001,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7904,6 +8048,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7961,6 +8106,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8020,6 +8166,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8071,6 +8218,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8122,6 +8270,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8173,6 +8322,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8224,6 +8374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8275,6 +8426,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8326,6 +8478,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8377,6 +8530,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8426,6 +8580,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8571,6 +8726,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8718,6 +8874,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8767,6 +8924,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8813,6 +8971,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8859,6 +9018,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8916,6 +9076,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8975,6 +9136,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9024,6 +9186,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9078,6 +9241,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9134,6 +9298,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9185,6 +9350,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9235,6 +9401,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9286,6 +9453,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9337,6 +9505,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9387,6 +9556,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9435,6 +9605,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9483,6 +9654,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9534,6 +9706,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9585,6 +9758,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9636,6 +9810,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9687,6 +9862,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9738,6 +9914,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9789,6 +9966,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9840,6 +10018,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9890,6 +10069,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9940,6 +10120,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fujitsu_fglair/snapshots/test_climate.ambr b/tests/components/fujitsu_fglair/snapshots/test_climate.ambr index 31b143c6f95..21c5b3429f4 100644 --- a/tests/components/fujitsu_fglair/snapshots/test_climate.ambr +++ b/tests/components/fujitsu_fglair/snapshots/test_climate.ambr @@ -28,6 +28,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +123,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fujitsu_fglair/snapshots/test_sensor.ambr b/tests/components/fujitsu_fglair/snapshots/test_sensor.ambr index 89738cc4a66..751ad3cd2d9 100644 --- a/tests/components/fujitsu_fglair/snapshots/test_sensor.ambr +++ b/tests/components/fujitsu_fglair/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fyta/snapshots/test_binary_sensor.ambr b/tests/components/fyta/snapshots/test_binary_sensor.ambr index c90db22bc7f..1218a3da71c 100644 --- a/tests/components/fyta/snapshots/test_binary_sensor.ambr +++ b/tests/components/fyta/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +148,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -191,6 +195,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -237,6 +242,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -283,6 +289,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -330,6 +337,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -376,6 +384,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -423,6 +432,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -469,6 +479,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -515,6 +526,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -561,6 +573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -607,6 +620,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -653,6 +667,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -700,6 +715,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fyta/snapshots/test_diagnostics.ambr b/tests/components/fyta/snapshots/test_diagnostics.ambr index a252e81952c..24206fbb875 100644 --- a/tests/components/fyta/snapshots/test_diagnostics.ambr +++ b/tests/components/fyta/snapshots/test_diagnostics.ambr @@ -19,6 +19,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'fyta_user', 'unique_id': None, 'version': 1, diff --git a/tests/components/fyta/snapshots/test_image.ambr b/tests/components/fyta/snapshots/test_image.ambr index 95e25e0a4d7..cb39efb4500 100644 --- a/tests/components/fyta/snapshots/test_image.ambr +++ b/tests/components/fyta/snapshots/test_image.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/fyta/snapshots/test_sensor.ambr b/tests/components/fyta/snapshots/test_sensor.ambr index 8b75579f557..c43a7446f11 100644 --- a/tests/components/fyta/snapshots/test_sensor.ambr +++ b/tests/components/fyta/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -163,6 +166,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -220,6 +224,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -278,6 +283,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +339,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -389,6 +396,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -446,6 +454,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -501,6 +510,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -556,6 +566,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +625,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -669,6 +681,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -717,6 +730,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -775,6 +789,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -832,6 +847,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -881,6 +897,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -930,6 +947,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -987,6 +1005,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1044,6 +1063,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1102,6 +1122,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1157,6 +1178,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1213,6 +1235,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1270,6 +1293,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1325,6 +1349,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1380,6 +1405,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1438,6 +1464,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1493,6 +1520,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1541,6 +1569,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1599,6 +1628,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/garages_amsterdam/snapshots/test_binary_sensor.ambr b/tests/components/garages_amsterdam/snapshots/test_binary_sensor.ambr index 5f6511090ee..b93a8656ecc 100644 --- a/tests/components/garages_amsterdam/snapshots/test_binary_sensor.ambr +++ b/tests/components/garages_amsterdam/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/garages_amsterdam/snapshots/test_sensor.ambr b/tests/components/garages_amsterdam/snapshots/test_sensor.ambr index 2c579631bae..3453817da10 100644 --- a/tests/components/garages_amsterdam/snapshots/test_sensor.ambr +++ b/tests/components/garages_amsterdam/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -155,6 +158,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/gardena_bluetooth/snapshots/test_config_flow.ambr b/tests/components/gardena_bluetooth/snapshots/test_config_flow.ambr index 6d521b1f2c8..10f23759fae 100644 --- a/tests/components/gardena_bluetooth/snapshots/test_config_flow.ambr +++ b/tests/components/gardena_bluetooth/snapshots/test_config_flow.ambr @@ -66,10 +66,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'bluetooth', + 'subentries': list([ + ]), 'title': 'Gardena Water Computer', 'unique_id': '00000000-0000-0000-0000-000000000001', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Gardena Water Computer', 'type': , 'version': 1, @@ -223,10 +227,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Gardena Water Computer', 'unique_id': '00000000-0000-0000-0000-000000000001', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Gardena Water Computer', 'type': , 'version': 1, diff --git a/tests/components/gardena_bluetooth/snapshots/test_init.ambr b/tests/components/gardena_bluetooth/snapshots/test_init.ambr index 71195918bb1..8dc9d220e85 100644 --- a/tests/components/gardena_bluetooth/snapshots/test_init.ambr +++ b/tests/components/gardena_bluetooth/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/geniushub/snapshots/test_binary_sensor.ambr b/tests/components/geniushub/snapshots/test_binary_sensor.ambr index fcc256b5232..c295ab8d10a 100644 --- a/tests/components/geniushub/snapshots/test_binary_sensor.ambr +++ b/tests/components/geniushub/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/geniushub/snapshots/test_climate.ambr b/tests/components/geniushub/snapshots/test_climate.ambr index eb372de784e..8f897c84559 100644 --- a/tests/components/geniushub/snapshots/test_climate.ambr +++ b/tests/components/geniushub/snapshots/test_climate.ambr @@ -16,6 +16,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -96,6 +97,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -178,6 +180,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -260,6 +263,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +346,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -423,6 +428,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -503,6 +509,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/geniushub/snapshots/test_sensor.ambr b/tests/components/geniushub/snapshots/test_sensor.ambr index 874f24cff95..aaf3030d4a4 100644 --- a/tests/components/geniushub/snapshots/test_sensor.ambr +++ b/tests/components/geniushub/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -203,6 +207,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +261,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -309,6 +315,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +369,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -415,6 +423,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -468,6 +477,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -521,6 +531,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -574,6 +585,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -629,6 +641,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -684,6 +697,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -739,6 +753,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -794,6 +809,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -849,6 +865,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -904,6 +921,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/geniushub/snapshots/test_switch.ambr b/tests/components/geniushub/snapshots/test_switch.ambr index 6c3c95af477..cc0451b4e94 100644 --- a/tests/components/geniushub/snapshots/test_switch.ambr +++ b/tests/components/geniushub/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -61,6 +62,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -116,6 +118,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/gios/snapshots/test_diagnostics.ambr b/tests/components/gios/snapshots/test_diagnostics.ambr index 71e0afdc495..890edc00482 100644 --- a/tests/components/gios/snapshots/test_diagnostics.ambr +++ b/tests/components/gios/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Home', 'unique_id': '123', 'version': 1, diff --git a/tests/components/gios/snapshots/test_sensor.ambr b/tests/components/gios/snapshots/test_sensor.ambr index c67cc3e4d7c..ab8a2359d0c 100644 --- a/tests/components/gios/snapshots/test_sensor.ambr +++ b/tests/components/gios/snapshots/test_sensor.ambr @@ -15,6 +15,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -73,6 +74,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -181,6 +184,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -243,6 +247,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -301,6 +306,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -363,6 +369,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -421,6 +428,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -483,6 +491,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -541,6 +550,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -603,6 +613,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -661,6 +672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -723,6 +735,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/glances/snapshots/test_sensor.ambr b/tests/components/glances/snapshots/test_sensor.ambr index 662e95c6a1c..baac4c5b056 100644 --- a/tests/components/glances/snapshots/test_sensor.ambr +++ b/tests/components/glances/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -107,6 +109,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -317,6 +323,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -368,6 +375,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +430,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +485,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -530,6 +540,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -584,6 +595,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -633,6 +645,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -682,6 +695,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -731,6 +745,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -780,6 +795,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -831,6 +847,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -881,6 +898,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -932,6 +950,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -983,6 +1002,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1033,6 +1053,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1084,6 +1105,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1135,6 +1157,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1185,6 +1208,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1235,6 +1259,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1288,6 +1313,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1339,6 +1365,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1393,6 +1420,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1447,6 +1475,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1501,6 +1530,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1555,6 +1585,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1606,6 +1637,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1656,6 +1688,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1705,6 +1738,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/goodwe/snapshots/test_diagnostics.ambr b/tests/components/goodwe/snapshots/test_diagnostics.ambr index f52e47688e8..40ed22195d5 100644 --- a/tests/components/goodwe/snapshots/test_diagnostics.ambr +++ b/tests/components/goodwe/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/google_assistant/snapshots/test_diagnostics.ambr b/tests/components/google_assistant/snapshots/test_diagnostics.ambr index edbbdb1ba28..1ecedbd1173 100644 --- a/tests/components/google_assistant/snapshots/test_diagnostics.ambr +++ b/tests/components/google_assistant/snapshots/test_diagnostics.ambr @@ -15,6 +15,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'import', + 'subentries': list([ + ]), 'title': '1234', 'unique_id': '1234', 'version': 1, diff --git a/tests/components/google_drive/snapshots/test_backup.ambr b/tests/components/google_drive/snapshots/test_backup.ambr index 2f3df3eed7f..891eb0e1cbe 100644 --- a/tests/components/google_drive/snapshots/test_backup.ambr +++ b/tests/components/google_drive/snapshots/test_backup.ambr @@ -136,7 +136,7 @@ }), ), tuple( - 'upload_file', + 'resumable_upload_file', tuple( dict({ 'description': '{"addons": [{"name": "Test", "slug": "test", "version": "1.0.0"}], "backup_id": "test-backup", "date": "2025-01-01T01:23:45.678Z", "database_included": true, "extra_metadata": {"with_automatic_settings": false}, "folders": [], "homeassistant_included": true, "homeassistant_version": "2024.12.0", "name": "Test", "protected": false, "size": 987}', @@ -151,6 +151,7 @@ }), }), "CoreBackupReaderWriter.async_receive_backup..open_backup() -> 'AsyncIterator[bytes]'", + 987, ), dict({ 'timeout': dict({ @@ -207,7 +208,7 @@ }), ), tuple( - 'upload_file', + 'resumable_upload_file', tuple( dict({ 'description': '{"addons": [{"name": "Test", "slug": "test", "version": "1.0.0"}], "backup_id": "test-backup", "date": "2025-01-01T01:23:45.678Z", "database_included": true, "extra_metadata": {"with_automatic_settings": false}, "folders": [], "homeassistant_included": true, "homeassistant_version": "2024.12.0", "name": "Test", "protected": false, "size": 987}', @@ -222,6 +223,7 @@ }), }), "CoreBackupReaderWriter.async_receive_backup..open_backup() -> 'AsyncIterator[bytes]'", + 987, ), dict({ 'timeout': dict({ diff --git a/tests/components/google_drive/test_backup.py b/tests/components/google_drive/test_backup.py index 115a30a3eb6..70431e2049f 100644 --- a/tests/components/google_drive/test_backup.py +++ b/tests/components/google_drive/test_backup.py @@ -281,7 +281,7 @@ async def test_agents_upload( snapshot: SnapshotAssertion, ) -> None: """Test agent upload backup.""" - mock_api.upload_file = AsyncMock(return_value=None) + mock_api.resumable_upload_file = AsyncMock(return_value=None) client = await hass_client() @@ -306,7 +306,7 @@ async def test_agents_upload( assert f"Uploading backup: {TEST_AGENT_BACKUP.backup_id}" in caplog.text assert f"Uploaded backup: {TEST_AGENT_BACKUP.backup_id}" in caplog.text - mock_api.upload_file.assert_called_once() + mock_api.resumable_upload_file.assert_called_once() assert [tuple(mock_call) for mock_call in mock_api.mock_calls] == snapshot @@ -322,7 +322,7 @@ async def test_agents_upload_create_folder_if_missing( mock_api.create_file = AsyncMock( return_value={"id": "new folder id", "name": "Home Assistant"} ) - mock_api.upload_file = AsyncMock(return_value=None) + mock_api.resumable_upload_file = AsyncMock(return_value=None) client = await hass_client() @@ -348,7 +348,7 @@ async def test_agents_upload_create_folder_if_missing( assert f"Uploaded backup: {TEST_AGENT_BACKUP.backup_id}" in caplog.text mock_api.create_file.assert_called_once() - mock_api.upload_file.assert_called_once() + mock_api.resumable_upload_file.assert_called_once() assert [tuple(mock_call) for mock_call in mock_api.mock_calls] == snapshot @@ -359,7 +359,9 @@ async def test_agents_upload_fail( mock_api: MagicMock, ) -> None: """Test agent upload backup fails.""" - mock_api.upload_file = AsyncMock(side_effect=GoogleDriveApiError("some error")) + mock_api.resumable_upload_file = AsyncMock( + side_effect=GoogleDriveApiError("some error") + ) client = await hass_client() diff --git a/tests/components/google_generative_ai_conversation/snapshots/test_conversation.ambr b/tests/components/google_generative_ai_conversation/snapshots/test_conversation.ambr index c89981e67bb..1fe02ac2536 100644 --- a/tests/components/google_generative_ai_conversation/snapshots/test_conversation.ambr +++ b/tests/components/google_generative_ai_conversation/snapshots/test_conversation.ambr @@ -1,446 +1,4 @@ # serializer version: 1 -# name: test_chat_history[models/gemini-1.0-pro-False] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-1.0-pro', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': None, - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'role': 'user', - }), - dict({ - 'parts': 'Ok', - 'role': 'model', - }), - dict({ - 'parts': '1st user request', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - '1st user request', - ), - dict({ - }), - ), - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-1.0-pro', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': None, - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'role': 'user', - }), - dict({ - 'parts': 'Ok', - 'role': 'model', - }), - dict({ - 'parts': '1st user request', - 'role': 'user', - }), - dict({ - 'parts': '1st model response', - 'role': 'model', - }), - dict({ - 'parts': '2nd user request', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - '2nd user request', - ), - dict({ - }), - ), - ]) -# --- -# name: test_chat_history[models/gemini-1.5-pro-True] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-1.5-pro', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': '1st user request', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - '1st user request', - ), - dict({ - }), - ), - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-1.5-pro', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': '1st user request', - 'role': 'user', - }), - dict({ - 'parts': '1st model response', - 'role': 'model', - }), - dict({ - 'parts': '2nd user request', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - '2nd user request', - ), - dict({ - }), - ), - ]) -# --- -# name: test_default_prompt[config_entry_options0-0-None] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-2.0-flash', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': 'hello', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - 'hello', - ), - dict({ - }), - ), - ]) -# --- -# name: test_default_prompt[config_entry_options0-0-conversation.google_generative_ai_conversation] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-2.0-flash', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': 'hello', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - 'hello', - ), - dict({ - }), - ), - ]) -# --- -# name: test_default_prompt[config_entry_options1-1-None] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-2.0-flash', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': 'hello', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - 'hello', - ), - dict({ - }), - ), - ]) -# --- -# name: test_default_prompt[config_entry_options1-1-conversation.google_generative_ai_conversation] - list([ - tuple( - '', - tuple( - ), - dict({ - 'generation_config': dict({ - 'max_output_tokens': 150, - 'temperature': 1.0, - 'top_k': 64, - 'top_p': 0.95, - }), - 'model_name': 'models/gemini-2.0-flash', - 'safety_settings': dict({ - 'DANGEROUS': 'BLOCK_MEDIUM_AND_ABOVE', - 'HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', - 'HATE': 'BLOCK_MEDIUM_AND_ABOVE', - 'SEXUAL': 'BLOCK_MEDIUM_AND_ABOVE', - }), - 'system_instruction': ''' - Current time is 05:00:00. Today's date is 2024-05-24. - You are a voice assistant for Home Assistant. - Answer questions about the world truthfully. - Answer in plain text. Keep it simple and to the point. - - ''', - 'tools': None, - }), - ), - tuple( - '().start_chat', - tuple( - ), - dict({ - 'history': list([ - dict({ - 'parts': 'hello', - 'role': 'user', - }), - ]), - }), - ), - tuple( - '().start_chat().send_message_async', - tuple( - 'hello', - ), - dict({ - }), - ), - ]) -# --- # name: test_function_call list([ tuple( diff --git a/tests/components/google_generative_ai_conversation/test_conversation.py b/tests/components/google_generative_ai_conversation/test_conversation.py index 72a5390f4b1..9b255666a67 100644 --- a/tests/components/google_generative_ai_conversation/test_conversation.py +++ b/tests/components/google_generative_ai_conversation/test_conversation.py @@ -13,20 +13,16 @@ import voluptuous as vol from homeassistant.components import conversation from homeassistant.components.conversation import trace -from homeassistant.components.google_generative_ai_conversation.const import ( - CONF_CHAT_MODEL, -) from homeassistant.components.google_generative_ai_conversation.conversation import ( _escape_decode, _format_schema, ) -from homeassistant.const import ATTR_SUPPORTED_FEATURES, CONF_LLM_HASS_API +from homeassistant.const import CONF_LLM_HASS_API from homeassistant.core import Context, HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import intent, llm from tests.common import MockConfigEntry -from tests.typing import WebSocketGenerator @pytest.fixture(autouse=True) @@ -43,143 +39,6 @@ def mock_ulid_tools(): yield -@pytest.mark.parametrize( - "agent_id", [None, "conversation.google_generative_ai_conversation"] -) -@pytest.mark.parametrize( - ("config_entry_options", "expected_features"), - [ - ({}, 0), - ( - {CONF_LLM_HASS_API: llm.LLM_API_ASSIST}, - conversation.ConversationEntityFeature.CONTROL, - ), - ], -) -@pytest.mark.usefixtures("mock_init_component") -async def test_default_prompt( - hass: HomeAssistant, - mock_config_entry: MockConfigEntry, - snapshot: SnapshotAssertion, - agent_id: str | None, - config_entry_options: {}, - expected_features: conversation.ConversationEntityFeature, - hass_ws_client: WebSocketGenerator, -) -> None: - """Test that the default prompt works.""" - entry = MockConfigEntry(title=None) - entry.add_to_hass(hass) - - if agent_id is None: - agent_id = mock_config_entry.entry_id - - hass.config_entries.async_update_entry( - mock_config_entry, - options={**mock_config_entry.options, **config_entry_options}, - ) - - with ( - patch("google.generativeai.GenerativeModel") as mock_model, - patch( - "homeassistant.components.google_generative_ai_conversation.conversation.llm.AssistAPI._async_get_tools", - return_value=[], - ) as mock_get_tools, - patch( - "homeassistant.components.google_generative_ai_conversation.conversation.llm.AssistAPI._async_get_api_prompt", - return_value="", - ), - ): - mock_chat = AsyncMock() - mock_model.return_value.start_chat.return_value = mock_chat - chat_response = MagicMock() - mock_chat.send_message_async.return_value = chat_response - mock_part = MagicMock() - mock_part.function_call = None - mock_part.text = "Hi there!\n" - chat_response.parts = [mock_part] - result = await conversation.async_converse( - hass, - "hello", - None, - Context(), - agent_id=agent_id, - ) - - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE - assert result.response.as_dict()["speech"]["plain"]["speech"] == "Hi there!" - assert [tuple(mock_call) for mock_call in mock_model.mock_calls] == snapshot - assert mock_get_tools.called == (CONF_LLM_HASS_API in config_entry_options) - - state = hass.states.get("conversation.google_generative_ai_conversation") - assert state.attributes[ATTR_SUPPORTED_FEATURES] == expected_features - - -@pytest.mark.parametrize( - ("model_name", "supports_system_instruction"), - [("models/gemini-1.5-pro", True), ("models/gemini-1.0-pro", False)], -) -@pytest.mark.usefixtures("mock_init_component") -async def test_chat_history( - hass: HomeAssistant, - mock_config_entry: MockConfigEntry, - model_name: str, - supports_system_instruction: bool, - snapshot: SnapshotAssertion, -) -> None: - """Test that the agent keeps track of the chat history.""" - hass.config_entries.async_update_entry( - mock_config_entry, options={CONF_CHAT_MODEL: model_name} - ) - with patch("google.generativeai.GenerativeModel") as mock_model: - mock_chat = AsyncMock() - mock_model.return_value.start_chat.return_value = mock_chat - chat_response = MagicMock() - mock_chat.send_message_async.return_value = chat_response - mock_part = MagicMock() - mock_part.function_call = None - mock_part.text = "1st model response" - chat_response.parts = [mock_part] - if supports_system_instruction: - mock_chat.history = [] - else: - mock_chat.history = [ - {"role": "user", "parts": "prompt"}, - {"role": "model", "parts": "Ok"}, - ] - mock_chat.history += [ - {"role": "user", "parts": "1st user request"}, - {"role": "model", "parts": "1st model response"}, - ] - result = await conversation.async_converse( - hass, - "1st user request", - None, - Context(), - agent_id=mock_config_entry.entry_id, - ) - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE - assert ( - result.response.as_dict()["speech"]["plain"]["speech"] - == "1st model response" - ) - mock_part.text = "2nd model response" - chat_response.parts = [mock_part] - result = await conversation.async_converse( - hass, - "2nd user request", - result.conversation_id, - Context(), - agent_id=mock_config_entry.entry_id, - ) - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE - assert ( - result.response.as_dict()["speech"]["plain"]["speech"] - == "2nd model response" - ) - - assert [tuple(mock_call) for mock_call in mock_model.mock_calls] == snapshot - - @patch( "homeassistant.components.google_generative_ai_conversation.conversation.llm.AssistAPI._async_get_tools" ) @@ -539,10 +398,10 @@ async def test_empty_response( @pytest.mark.usefixtures("mock_init_component") -async def test_invalid_llm_api( +async def test_converse_error( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: - """Test handling of invalid llm api.""" + """Test handling ChatLog raising ConverseError.""" hass.config_entries.async_update_entry( mock_config_entry, options={**mock_config_entry.options, CONF_LLM_HASS_API: "invalid_llm_api"}, @@ -563,73 +422,6 @@ async def test_invalid_llm_api( ) -async def test_template_error( - hass: HomeAssistant, mock_config_entry: MockConfigEntry -) -> None: - """Test that template error handling works.""" - hass.config_entries.async_update_entry( - mock_config_entry, - options={ - "prompt": "talk like a {% if True %}smarthome{% else %}pirate please.", - }, - ) - with patch("google.generativeai.GenerativeModel"): - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - result = await conversation.async_converse( - hass, "hello", None, Context(), agent_id=mock_config_entry.entry_id - ) - - assert result.response.response_type == intent.IntentResponseType.ERROR, result - assert result.response.error_code == "unknown", result - - -async def test_template_variables( - hass: HomeAssistant, mock_config_entry: MockConfigEntry -) -> None: - """Test that template variables work.""" - context = Context(user_id="12345") - mock_user = MagicMock() - mock_user.id = "12345" - mock_user.name = "Test User" - - hass.config_entries.async_update_entry( - mock_config_entry, - options={ - "prompt": ( - "The user name is {{ user_name }}. " - "The user id is {{ llm_context.context.user_id }}." - ), - }, - ) - with ( - patch("google.generativeai.GenerativeModel") as mock_model, - patch("homeassistant.auth.AuthManager.async_get_user", return_value=mock_user), - ): - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - mock_chat = AsyncMock() - mock_model.return_value.start_chat.return_value = mock_chat - chat_response = MagicMock() - mock_chat.send_message_async.return_value = chat_response - mock_part = MagicMock() - mock_part.text = "Model response" - mock_part.function_call = None - chat_response.parts = [mock_part] - result = await conversation.async_converse( - hass, "hello", None, context, agent_id=mock_config_entry.entry_id - ) - - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE, ( - result - ) - assert ( - "The user name is Test User." - in mock_model.mock_calls[0][2]["system_instruction"] - ) - assert "The user id is 12345." in mock_model.mock_calls[0][2]["system_instruction"] - - @pytest.mark.usefixtures("mock_init_component") async def test_conversation_agent( hass: HomeAssistant, mock_config_entry: MockConfigEntry diff --git a/tests/components/gree/snapshots/test_climate.ambr b/tests/components/gree/snapshots/test_climate.ambr index 4f62be5cded..9111b909f04 100644 --- a/tests/components/gree/snapshots/test_climate.ambr +++ b/tests/components/gree/snapshots/test_climate.ambr @@ -93,6 +93,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/gree/snapshots/test_switch.ambr b/tests/components/gree/snapshots/test_switch.ambr index 71c6d3ea71d..836641cb2ab 100644 --- a/tests/components/gree/snapshots/test_switch.ambr +++ b/tests/components/gree/snapshots/test_switch.ambr @@ -71,6 +71,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -133,6 +135,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -164,6 +167,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -195,6 +199,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , diff --git a/tests/components/guardian/test_diagnostics.py b/tests/components/guardian/test_diagnostics.py index faba2103000..4487d0b6ac6 100644 --- a/tests/components/guardian/test_diagnostics.py +++ b/tests/components/guardian/test_diagnostics.py @@ -42,6 +42,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "data": { "valve_controller": { diff --git a/tests/components/habitica/fixtures/user.json b/tests/components/habitica/fixtures/user.json index 255d9c7c3b5..58eca2837b6 100644 --- a/tests/components/habitica/fixtures/user.json +++ b/tests/components/habitica/fixtures/user.json @@ -2,8 +2,18 @@ "success": true, "data": { "api_user": "test-api-user", - "profile": { "name": "test-user" }, - "auth": { "local": { "username": "test-username" } }, + "profile": { + "name": "test-user", + "blurb": "My mind is a swirling miasma of scintillating thoughts and turgid ideas.", + "imageUrl": "https://pbs.twimg.com/profile_images/378800000771780608/a32e71fe6a64eba6773c20d289eddc8e.png" + }, + "auth": { + "local": { "username": "test-username" }, + "timestamps": { + "created": "2013-12-02T22:23:29.249Z", + "loggedin": "2025-02-02T03:14:33.864Z" + } + }, "stats": { "buffs": { "str": 26, @@ -143,6 +153,26 @@ "trinkets": 0 } } - } + }, + "webhooks": [ + { + "id": "43a67e37-1bae-4b11-8d3d-6c4b1b480231", + "type": "taskActivity", + "label": "My Webhook", + "url": "https://some-webhook-url.com", + "enabled": true, + "failures": 0, + "options": { + "created": false, + "updated": false, + "deleted": false, + "checklistScored": false, + "scored": true + }, + "createdAt": "2025-02-08T22:06:08.894Z", + "updatedAt": "2025-02-08T22:06:17.195Z" + } + ], + "loginIncentives": 241 } } diff --git a/tests/components/habitica/snapshots/test_binary_sensor.ambr b/tests/components/habitica/snapshots/test_binary_sensor.ambr index 0a4076a6135..ffe4ce83d0e 100644 --- a/tests/components/habitica/snapshots/test_binary_sensor.ambr +++ b/tests/components/habitica/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/habitica/snapshots/test_button.ambr b/tests/components/habitica/snapshots/test_button.ambr index 76a0198d5b2..5c6ad640039 100644 --- a/tests/components/habitica/snapshots/test_button.ambr +++ b/tests/components/habitica/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -286,6 +292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +340,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -379,6 +387,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -425,6 +434,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -472,6 +482,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -518,6 +529,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -564,6 +576,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -611,6 +624,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -658,6 +672,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -704,6 +719,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -751,6 +767,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -798,6 +815,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -845,6 +863,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -891,6 +910,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -937,6 +957,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -984,6 +1005,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1030,6 +1052,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1077,6 +1100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1124,6 +1148,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1171,6 +1196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1218,6 +1244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1264,6 +1291,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/habitica/snapshots/test_calendar.ambr b/tests/components/habitica/snapshots/test_calendar.ambr index 8be45ccc0fd..2948f31f1cf 100644 --- a/tests/components/habitica/snapshots/test_calendar.ambr +++ b/tests/components/habitica/snapshots/test_calendar.ambr @@ -906,6 +906,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -959,6 +960,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1011,6 +1013,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1063,6 +1066,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/habitica/snapshots/test_diagnostics.ambr b/tests/components/habitica/snapshots/test_diagnostics.ambr index 2fe3513a646..718aea99ebc 100644 --- a/tests/components/habitica/snapshots/test_diagnostics.ambr +++ b/tests/components/habitica/snapshots/test_diagnostics.ambr @@ -8,48 +8,31 @@ 'habitica_data': dict({ 'tasks': list([ dict({ - 'alias': None, 'attribute': 'str', 'byHabitica': False, 'challenge': dict({ - 'broken': None, - 'id': None, - 'shortName': None, - 'taskId': None, - 'winner': None, }), 'checklist': list([ ]), 'collapseChecklist': False, - 'completed': None, 'counterDown': 0, 'counterUp': 0, 'createdAt': '2024-10-10T15:57:14.287000+00:00', - 'date': None, 'daysOfMonth': list([ ]), 'down': False, - 'everyX': None, 'frequency': 'daily', 'group': dict({ - 'assignedDate': None, 'assignedUsers': list([ ]), 'assignedUsersDetail': dict({ }), - 'assigningUsername': None, 'completedBy': dict({ - 'date': None, - 'userId': None, }), - 'id': None, - 'managerNotes': None, - 'taskId': None, }), 'history': list([ ]), 'id': '30923acd-3b4c-486d-9ef3-c8f57cf56049', - 'isDue': None, 'nextDue': list([ ]), 'notes': 'task notes', @@ -65,8 +48,6 @@ 'th': False, 'w': True, }), - 'startDate': None, - 'streak': None, 'tags': list([ ]), 'text': 'task text', @@ -77,51 +58,30 @@ 'value': 0.0, 'weeksOfMonth': list([ ]), - 'yesterDaily': None, }), dict({ - 'alias': None, 'attribute': 'str', 'byHabitica': True, 'challenge': dict({ - 'broken': None, - 'id': None, - 'shortName': None, - 'taskId': None, - 'winner': None, }), 'checklist': list([ ]), 'collapseChecklist': False, 'completed': False, - 'counterDown': None, - 'counterUp': None, 'createdAt': '2024-10-10T15:57:14.290000+00:00', - 'date': None, 'daysOfMonth': list([ ]), - 'down': None, - 'everyX': None, - 'frequency': None, 'group': dict({ - 'assignedDate': None, 'assignedUsers': list([ ]), 'assignedUsersDetail': dict({ }), - 'assigningUsername': None, 'completedBy': dict({ - 'date': None, - 'userId': None, }), - 'id': None, - 'managerNotes': None, - 'taskId': None, }), 'history': list([ ]), 'id': 'e6e06dc6-c887-4b86-b175-b99cc2e20fdf', - 'isDue': None, 'nextDue': list([ ]), 'notes': 'task notes', @@ -137,63 +97,38 @@ 'th': False, 'w': True, }), - 'startDate': None, - 'streak': None, 'tags': list([ ]), 'text': 'task text', 'type': 'todo', - 'up': None, 'updatedAt': '2024-11-27T19:34:29.001000+00:00', 'userId': 'ffce870c-3ff3-4fa4-bad1-87612e52b8e7', 'value': -6.418582324043852, 'weeksOfMonth': list([ ]), - 'yesterDaily': None, }), dict({ - 'alias': None, 'attribute': 'str', 'byHabitica': False, 'challenge': dict({ - 'broken': None, - 'id': None, - 'shortName': None, - 'taskId': None, - 'winner': None, }), 'checklist': list([ ]), 'collapseChecklist': False, - 'completed': None, - 'counterDown': None, - 'counterUp': None, 'createdAt': '2024-10-10T15:57:14.290000+00:00', - 'date': None, 'daysOfMonth': list([ ]), - 'down': None, - 'everyX': None, - 'frequency': None, 'group': dict({ - 'assignedDate': None, 'assignedUsers': list([ ]), 'assignedUsersDetail': dict({ }), - 'assigningUsername': None, 'completedBy': dict({ - 'date': None, - 'userId': None, }), - 'id': None, - 'managerNotes': None, - 'taskId': None, }), 'history': list([ ]), 'id': '2fbf11a5-ab1e-4fb7-97f0-dfb5c45c96a9', - 'isDue': None, 'nextDue': list([ ]), 'notes': 'task notes', @@ -209,106 +144,73 @@ 'th': False, 'w': True, }), - 'startDate': None, - 'streak': None, 'tags': list([ ]), 'text': 'task text', 'type': 'reward', - 'up': None, 'updatedAt': '2024-10-10T15:57:14.290000+00:00', 'userId': 'ffce870c-3ff3-4fa4-bad1-87612e52b8e7', 'value': 10.0, 'weeksOfMonth': list([ ]), - 'yesterDaily': None, }), dict({ - 'alias': None, 'attribute': 'str', 'byHabitica': False, 'challenge': dict({ - 'broken': None, - 'id': None, - 'shortName': None, - 'taskId': None, - 'winner': None, }), 'checklist': list([ ]), 'collapseChecklist': False, 'completed': False, - 'counterDown': None, - 'counterUp': None, 'createdAt': '2024-10-10T15:57:14.304000+00:00', - 'date': None, 'daysOfMonth': list([ ]), - 'down': None, 'everyX': 1, 'frequency': 'weekly', 'group': dict({ - 'assignedDate': None, 'assignedUsers': list([ ]), 'assignedUsersDetail': dict({ }), - 'assigningUsername': None, 'completedBy': dict({ - 'date': None, - 'userId': None, }), - 'id': None, - 'managerNotes': None, - 'taskId': None, }), 'history': list([ dict({ 'completed': True, 'date': '2024-10-30T19:37:01.817000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': 1.0, }), dict({ 'completed': True, 'date': '2024-10-31T23:33:14.890000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': 1.9747, }), dict({ 'completed': False, 'date': '2024-11-05T18:25:04.730000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': 1.024043774264157, }), dict({ 'completed': False, 'date': '2024-11-21T15:09:07.573000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': 0.049944135963563174, }), dict({ 'completed': False, 'date': '2024-11-22T00:41:21.228000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': -0.9487768368544092, }), dict({ 'completed': False, 'date': '2024-11-27T19:34:28.973000+00:00', 'isDue': True, - 'scoredDown': None, - 'scoredUp': None, 'value': -1.973387732005249, }), ]), @@ -341,7 +243,6 @@ ]), 'text': 'task text', 'type': 'daily', - 'up': None, 'updatedAt': '2024-11-27T19:34:29.001000+00:00', 'userId': 'ffce870c-3ff3-4fa4-bad1-87612e52b8e7', 'value': -1.973387732005249, @@ -352,60 +253,23 @@ ]), 'user': dict({ 'achievements': dict({ - 'backToBasics': None, - 'boneCollector': None, 'challenges': list([ ]), 'completedTask': True, 'createdTask': True, - 'dustDevil': None, - 'fedPet': None, - 'goodAsGold': None, - 'hatchedPet': None, - 'joinedChallenge': None, - 'joinedGuild': None, - 'partyUp': None, 'perfect': 2, - 'primedForPainting': None, - 'purchasedEquipment': None, 'quests': dict({ - 'atom1': None, - 'atom2': None, - 'atom3': None, - 'bewilder': None, - 'burnout': None, - 'dilatory': None, - 'dilatory_derby': None, - 'dysheartener': None, - 'evilsanta': None, - 'evilsanta2': None, - 'gryphon': None, - 'harpy': None, - 'stressbeast': None, - 'vice1': None, - 'vice3': None, }), - 'seeingRed': None, - 'shadyCustomer': None, 'streak': 0, - 'tickledPink': None, 'ultimateGearSets': dict({ 'healer': False, 'rogue': False, 'warrior': False, 'wizard': False, }), - 'violetsAreBlue': None, }), 'auth': dict({ - 'apple': None, - 'facebook': None, - 'google': None, 'local': dict({ - 'email': None, - 'has_password': None, - 'lowerCaseUsername': None, - 'username': None, }), 'timestamps': dict({ 'created': '2024-10-10T15:57:01.106000+00:00', @@ -414,17 +278,11 @@ }), }), 'backer': dict({ - 'npc': None, - 'tier': None, - 'tokensApplied': None, }), 'balance': 0.0, 'challenges': list([ ]), 'contributor': dict({ - 'contributions': None, - 'level': None, - 'text': None, }), 'extra': dict({ }), @@ -433,23 +291,17 @@ 'armoireEnabled': True, 'armoireOpened': False, 'cardReceived': False, - 'chatRevoked': None, - 'chatShadowMuted': None, 'classSelected': False, 'communityGuidelinesAccepted': True, 'cronCount': 6, 'customizationsNotification': True, 'dropsEnabled': False, 'itemsEnabled': True, - 'lastFreeRebirth': None, 'lastNewStuffRead': '', 'lastWeeklyRecap': '2024-10-10T15:57:01.106000+00:00', - 'lastWeeklyRecapDiscriminator': None, 'levelDrops': dict({ }), - 'mathUpdates': None, 'newStuff': False, - 'onboardingEmailsPhase': None, 'rebirthEnabled': False, 'recaptureEmailsPhase': 0, 'rewrite': True, @@ -508,101 +360,53 @@ 'history': dict({ 'exp': list([ dict({ - 'completed': None, 'date': '2024-10-30T19:37:01.970000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 24.0, }), dict({ - 'completed': None, 'date': '2024-10-31T23:33:14.972000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 48.0, }), dict({ - 'completed': None, 'date': '2024-11-05T18:25:04.681000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 66.0, }), dict({ - 'completed': None, 'date': '2024-11-21T15:09:07.501000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 66.0, }), dict({ - 'completed': None, 'date': '2024-11-22T00:41:21.137000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 66.0, }), dict({ - 'completed': None, 'date': '2024-11-27T19:34:28.887000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': 66.0, }), ]), 'todos': list([ dict({ - 'completed': None, 'date': '2024-10-30T19:37:01.970000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -5.0, }), dict({ - 'completed': None, 'date': '2024-10-31T23:33:14.972000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -10.129783523135325, }), dict({ - 'completed': None, 'date': '2024-11-05T18:25:04.681000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -16.396221153338182, }), dict({ - 'completed': None, 'date': '2024-11-21T15:09:07.501000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -22.8326979965846, }), dict({ - 'completed': None, 'date': '2024-11-22T00:41:21.137000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -29.448636229365235, }), dict({ - 'completed': None, 'date': '2024-11-27T19:34:28.887000+00:00', - 'isDue': None, - 'scoredDown': None, - 'scoredUp': None, 'value': -36.25425987861077, }), ]), @@ -643,23 +447,13 @@ 'gear': dict({ 'costume': dict({ 'armor': 'armor_base_0', - 'back': None, - 'body': None, - 'eyewear': None, 'head': 'head_base_0', - 'headAccessory': None, 'shield': 'shield_base_0', - 'weapon': None, }), 'equipped': dict({ 'armor': 'armor_base_0', - 'back': None, - 'body': None, - 'eyewear': None, 'head': 'head_base_0', - 'headAccessory': None, 'shield': 'shield_base_0', - 'weapon': None, }), 'owned': dict({ 'armor_special_bardRobes': True, @@ -736,7 +530,6 @@ }), 'lastCron': '2024-11-27T19:34:28.887000+00:00', 'loginIncentives': 6, - 'needsCron': None, 'newMessages': dict({ }), 'notifications': list([ @@ -747,7 +540,6 @@ 'orderAscending': 'ascending', 'quest': dict({ 'RSVPNeeded': True, - 'completed': None, 'key': 'dustbunnies', 'progress': dict({ 'collect': dict({ @@ -759,37 +551,31 @@ }), }), 'permissions': dict({ - 'challengeAdmin': None, - 'coupons': None, - 'fullAccess': None, - 'moderator': None, - 'news': None, - 'userSupport': None, }), 'pinnedItems': list([ dict({ - 'Type': 'marketGear', 'path': 'gear.flat.weapon_warrior_0', + 'type': 'marketGear', }), dict({ - 'Type': 'marketGear', 'path': 'gear.flat.armor_warrior_1', + 'type': 'marketGear', }), dict({ - 'Type': 'marketGear', 'path': 'gear.flat.shield_warrior_1', + 'type': 'marketGear', }), dict({ - 'Type': 'marketGear', 'path': 'gear.flat.head_warrior_1', + 'type': 'marketGear', }), dict({ - 'Type': 'potion', 'path': 'potion', + 'type': 'potion', }), dict({ - 'Type': 'armoire', 'path': 'armoire', + 'type': 'armoire', }), ]), 'pinnedItemsOrder': list([ @@ -798,7 +584,6 @@ 'advancedCollapsed': False, 'allocationMode': 'flat', 'autoEquip': True, - 'automaticAllocation': None, 'background': 'violet', 'chair': 'none', 'costume': False, @@ -888,9 +673,6 @@ }), }), 'profile': dict({ - 'blurb': None, - 'imageUrl': None, - 'name': None, }), 'purchased': dict({ 'ads': False, @@ -904,21 +686,11 @@ }), 'hair': dict({ }), - 'mobileChat': None, 'plan': dict({ 'consecutive': dict({ - 'count': None, - 'gemCapExtra': None, - 'offset': None, - 'trinkets': None, }), - 'dateUpdated': None, - 'extraMonths': None, - 'gemsBought': None, 'mysteryItems': list([ ]), - 'perkMonthCount': None, - 'quantity': None, }), 'shirt': dict({ }), @@ -928,81 +700,73 @@ }), 'pushDevices': list([ ]), - 'secret': None, 'stats': dict({ - 'Class': 'warrior', - 'Int': 0, - 'Str': 0, 'buffs': dict({ - 'Int': 0, - 'Str': 0, 'con': 0, + 'int': 0, 'per': 0, 'seafoam': False, 'shinySeed': False, 'snowball': False, 'spookySparkles': False, 'stealth': 0, + 'str': 0, 'streaks': False, }), + 'class': 'warrior', 'con': 0, 'exp': 41, 'gp': 11.100978952781748, 'hp': 25.40000000000002, + 'int': 0, 'lvl': 2, 'maxHealth': 50, 'maxMP': 32, 'mp': 32.0, 'per': 0, 'points': 2, + 'str': 0, 'toNextLevel': 50, 'training': dict({ - 'Int': 0, - 'Str': 0.0, 'con': 0, + 'int': 0, 'per': 0, + 'str': 0.0, }), }), 'tags': list([ dict({ 'challenge': True, - 'group': None, 'id': 'c1a35186-9895-4ac0-9cd7-49e7bb875695', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': '53d1deb8-ed2b-4f94-bbfc-955e9e92aa98', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': '29bf6a99-536f-446b-838f-a81d41e1ed4d', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': '1b1297e7-4fd8-460a-b148-e92d7bcfa9a5', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': '05e6cf40-48ea-415a-9b8b-e2ecad258ef6', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': 'fe53f179-59d8-4c28-9bf7-b9068ab552a4', 'name': 'tag', }), dict({ 'challenge': True, - 'group': None, 'id': 'c44e9e8c-4bff-42df-98d5-1a1a7b69eada', 'name': 'tag', }), diff --git a/tests/components/habitica/snapshots/test_sensor.ambr b/tests/components/habitica/snapshots/test_sensor.ambr index 9050db1946d..881326f76d8 100644 --- a/tests/components/habitica/snapshots/test_sensor.ambr +++ b/tests/components/habitica/snapshots/test_sensor.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -151,7 +154,12 @@ # name: test_sensors[sensor.test_user_display_name-state] StateSnapshot({ 'attributes': ReadOnlyDict({ + 'blurb': 'My mind is a swirling miasma of scintillating thoughts and turgid ideas.', + 'entity_picture': 'https://pbs.twimg.com/profile_images/378800000771780608/a32e71fe6a64eba6773c20d289eddc8e.png', 'friendly_name': 'test-user Display name', + 'joined': datetime.date(2013, 12, 2), + 'last_login': datetime.date(2025, 2, 1), + 'total_logins': 241, }), 'context': , 'entity_id': 'sensor.test_user_display_name', @@ -168,6 +176,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -219,6 +228,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -267,6 +277,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -318,6 +329,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -369,6 +381,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -575,6 +588,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -626,6 +640,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -677,6 +692,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -732,6 +748,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -778,6 +795,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -829,6 +847,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -876,6 +895,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -924,6 +944,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -975,6 +996,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1023,6 +1045,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1078,6 +1101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1129,6 +1153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1181,6 +1206,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1267,6 +1293,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1315,6 +1342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/habitica/snapshots/test_switch.ambr b/tests/components/habitica/snapshots/test_switch.ambr index a865df3a4f4..e8122f77c6e 100644 --- a/tests/components/habitica/snapshots/test_switch.ambr +++ b/tests/components/habitica/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/habitica/snapshots/test_todo.ambr b/tests/components/habitica/snapshots/test_todo.ambr index 9cd6d9a540f..88204d53ded 100644 --- a/tests/components/habitica/snapshots/test_todo.ambr +++ b/tests/components/habitica/snapshots/test_todo.ambr @@ -113,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +161,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/hassio/test_backup.py b/tests/components/hassio/test_backup.py index 0dd2adc99ed..7547e3e3586 100644 --- a/tests/components/hassio/test_backup.py +++ b/tests/components/hassio/test_backup.py @@ -661,8 +661,8 @@ async def test_agent_get_backup( ( SupervisorBadRequestError("blah"), { - "success": False, - "error": {"code": "unknown_error", "message": "Unknown error"}, + "success": True, + "result": {"agent_errors": {"hassio.local": "blah"}, "backup": None}, }, ), ( @@ -733,8 +733,8 @@ async def test_agent_delete_backup( ( SupervisorBadRequestError("blah"), { - "success": False, - "error": {"code": "unknown_error", "message": "Unknown error"}, + "success": True, + "result": {"agent_errors": {"hassio.local": "blah"}}, }, ), ( diff --git a/tests/components/hassio/test_update.py b/tests/components/hassio/test_update.py index 332f2050cf2..83af302e1ce 100644 --- a/tests/components/hassio/test_update.py +++ b/tests/components/hassio/test_update.py @@ -10,6 +10,9 @@ from aiohasupervisor.models import HomeAssistantUpdateOptions, StoreAddonUpdate import pytest from homeassistant.components.backup import BackupManagerError, ManagerBackup + +# pylint: disable-next=hass-component-root-import +from homeassistant.components.backup.manager import AgentBackupStatus from homeassistant.components.hassio import DOMAIN from homeassistant.components.hassio.const import REQUEST_REFRESH_DELAY from homeassistant.const import __version__ as HAVERSION @@ -348,34 +351,40 @@ async def test_update_addon_with_backup( ( { "backup-1": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "other"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "other"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "test"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-6": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "test"}, with_automatic_settings=True, diff --git a/tests/components/hassio/test_websocket_api.py b/tests/components/hassio/test_websocket_api.py index bcac19e0fa3..e752b53ae7a 100644 --- a/tests/components/hassio/test_websocket_api.py +++ b/tests/components/hassio/test_websocket_api.py @@ -9,6 +9,9 @@ from aiohasupervisor.models import HomeAssistantUpdateOptions, StoreAddonUpdate import pytest from homeassistant.components.backup import BackupManagerError, ManagerBackup + +# pylint: disable-next=hass-component-root-import +from homeassistant.components.backup.manager import AgentBackupStatus from homeassistant.components.hassio import DOMAIN from homeassistant.components.hassio.const import ( ATTR_DATA, @@ -467,34 +470,40 @@ async def test_update_addon_with_backup( ( { "backup-1": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-10T04:45:00+01:00", with_automatic_settings=True, spec=ManagerBackup, ), "backup-2": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", with_automatic_settings=False, spec=ManagerBackup, ), "backup-3": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "other"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-4": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "other"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-5": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-11T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "test"}, with_automatic_settings=True, spec=ManagerBackup, ), "backup-6": MagicMock( + agents={"hassio.local": MagicMock(spec=AgentBackupStatus)}, date="2024-11-12T04:45:00+01:00", extra_metadata={"supervisor.addon_update": "test"}, with_automatic_settings=True, diff --git a/tests/components/heos/conftest.py b/tests/components/heos/conftest.py index 5ec809b10e9..39937a8355f 100644 --- a/tests/components/heos/conftest.py +++ b/tests/components/heos/conftest.py @@ -110,6 +110,7 @@ def system_info_fixture() -> HeosSystem: "1.0.0", "127.0.0.1", NetworkType.WIRED, + True, ) return HeosSystem( "user@user.com", @@ -123,6 +124,7 @@ def system_info_fixture() -> HeosSystem: "1.0.0", "127.0.0.2", NetworkType.WIFI, + True, ), ], ) @@ -140,6 +142,7 @@ def players_fixture() -> dict[int, HeosPlayer]: model="HEOS Drive HS2" if i == 1 else "Speaker", serial="123456", version="1.0.0", + supported_version=True, line_out=LineOutLevelType.VARIABLE, is_muted=False, available=True, diff --git a/tests/components/heos/snapshots/test_diagnostics.ambr b/tests/components/heos/snapshots/test_diagnostics.ambr index 1df2d172142..98ce8a7bcbf 100644 --- a/tests/components/heos/snapshots/test_diagnostics.ambr +++ b/tests/components/heos/snapshots/test_diagnostics.ambr @@ -15,6 +15,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'HEOS System (via 127.0.0.1)', 'unique_id': 'heos', 'version': 1, @@ -105,6 +107,7 @@ 'name': 'Test Player', 'network': 'wired', 'serial': '**REDACTED**', + 'supported_version': True, 'version': '1.0.0', }), 'hosts': list([ @@ -114,6 +117,7 @@ 'name': 'Test Player', 'network': 'wired', 'serial': '**REDACTED**', + 'supported_version': True, 'version': '1.0.0', }), dict({ @@ -122,6 +126,7 @@ 'name': 'Test Player 2', 'network': 'wifi', 'serial': '**REDACTED**', + 'supported_version': True, 'version': '1.0.0', }), ]), @@ -133,6 +138,7 @@ 'name': 'Test Player', 'network': 'wired', 'serial': '**REDACTED**', + 'supported_version': True, 'version': '1.0.0', }), ]), @@ -156,6 +162,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'HEOS System (via 127.0.0.1)', 'unique_id': 'heos', 'version': 1, @@ -276,6 +284,7 @@ 'area_id': None, 'categories': dict({ }), + 'config_subentry_id': None, 'disabled_by': None, 'entity_category': None, 'entity_id': 'media_player.test_player', @@ -371,6 +380,7 @@ 'serial': '**REDACTED**', 'shuffle': False, 'state': 'stop', + 'supported_version': True, 'version': '1.0.0', 'volume': 25, }), diff --git a/tests/components/heos/test_diagnostics.py b/tests/components/heos/test_diagnostics.py index 2a7deccfb33..fb71682fb48 100644 --- a/tests/components/heos/test_diagnostics.py +++ b/tests/components/heos/test_diagnostics.py @@ -88,6 +88,7 @@ async def test_device_diagnostics( "created_at", "modified_at", "config_entries", + "config_entries_subentries", "id", "primary_config_entry", "config_entry_id", diff --git a/tests/components/home_connect/test_config_flow.py b/tests/components/home_connect/test_config_flow.py index 343d648e543..c35678e4e5f 100644 --- a/tests/components/home_connect/test_config_flow.py +++ b/tests/components/home_connect/test_config_flow.py @@ -1,7 +1,8 @@ """Test the Home Connect config flow.""" +from collections.abc import Awaitable, Callable from http import HTTPStatus -from unittest.mock import patch +from unittest.mock import MagicMock, patch from aiohomeconnect.const import OAUTH2_AUTHORIZE, OAUTH2_TOKEN import pytest @@ -93,3 +94,57 @@ async def test_prevent_multiple_config_entries( assert result["type"] == "abort" assert result["reason"] == "single_instance_allowed" + + +@pytest.mark.usefixtures("current_request_with_host") +async def test_reauth_flow( + hass: HomeAssistant, + config_entry: MockConfigEntry, + integration_setup: Callable[[MagicMock], Awaitable[bool]], + setup_credentials: None, + client: MagicMock, + hass_client_no_auth: ClientSessionGenerator, + aioclient_mock: AiohttpClientMocker, +) -> None: + """Test reauth flow.""" + result = await config_entry.start_reauth_flow(hass) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reauth_confirm" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + state = config_entry_oauth2_flow._encode_jwt( + hass, + { + "flow_id": result["flow_id"], + "redirect_uri": "https://example.com/auth/external/callback", + }, + ) + + _client = await hass_client_no_auth() + resp = await _client.get(f"/auth/external/callback?code=abcd&state={state}") + assert resp.status == HTTPStatus.OK + assert resp.headers["content-type"] == "text/html; charset=utf-8" + + aioclient_mock.post( + OAUTH2_TOKEN, + json={ + "refresh_token": "mock-refresh-token", + "access_token": "mock-access-token", + "type": "Bearer", + "expires_in": 60, + }, + ) + + with patch( + "homeassistant.components.home_connect.async_setup_entry", return_value=True + ) as mock_setup_entry: + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + await hass.async_block_till_done() + + assert len(hass.config_entries.async_entries(DOMAIN)) == 1 + assert len(mock_setup_entry.mock_calls) == 1 + + await hass.async_block_till_done() + assert result["type"] == FlowResultType.ABORT + assert result["reason"] == "reauth_successful" diff --git a/tests/components/home_connect/test_init.py b/tests/components/home_connect/test_init.py index b3d1c4e531f..009c40b662d 100644 --- a/tests/components/home_connect/test_init.py +++ b/tests/components/home_connect/test_init.py @@ -6,7 +6,7 @@ from unittest.mock import MagicMock, patch from aiohomeconnect.const import OAUTH2_TOKEN from aiohomeconnect.model import OptionKey, ProgramKey, SettingKey, StatusKey -from aiohomeconnect.model.error import HomeConnectError +from aiohomeconnect.model.error import HomeConnectError, UnauthorizedError import pytest import requests_mock import respx @@ -216,7 +216,16 @@ async def test_token_refresh_success( ) +@pytest.mark.parametrize( + ("exception", "expected_state"), + [ + (HomeConnectError(), ConfigEntryState.SETUP_RETRY), + (UnauthorizedError("error.key"), ConfigEntryState.SETUP_ERROR), + ], +) async def test_client_error( + exception: HomeConnectError, + expected_state: ConfigEntryState, config_entry: MockConfigEntry, integration_setup: Callable[[MagicMock], Awaitable[bool]], setup_credentials: None, @@ -224,10 +233,10 @@ async def test_client_error( ) -> None: """Test client errors during setup integration.""" client_with_exception.get_home_appliances.return_value = None - client_with_exception.get_home_appliances.side_effect = HomeConnectError() + client_with_exception.get_home_appliances.side_effect = exception assert config_entry.state == ConfigEntryState.NOT_LOADED assert not await integration_setup(client_with_exception) - assert config_entry.state == ConfigEntryState.SETUP_RETRY + assert config_entry.state == expected_state assert client_with_exception.get_home_appliances.call_count == 1 diff --git a/tests/components/homekit_controller/snapshots/test_init.ambr b/tests/components/homekit_controller/snapshots/test_init.ambr index 2bd5e7faf75..a41964d98cc 100644 --- a/tests/components/homekit_controller/snapshots/test_init.ambr +++ b/tests/components/homekit_controller/snapshots/test_init.ambr @@ -7,6 +7,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -42,6 +47,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -85,6 +91,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -135,6 +142,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -185,6 +193,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -233,6 +242,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -277,6 +287,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -321,6 +332,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -373,6 +385,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -432,6 +445,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -482,6 +496,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -522,6 +537,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -562,6 +578,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -605,6 +622,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -640,6 +662,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -680,6 +703,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -715,6 +743,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -756,6 +785,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -797,6 +827,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'camera', @@ -840,6 +871,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -884,6 +916,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -923,6 +956,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -958,6 +996,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -999,6 +1038,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -1040,6 +1080,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'camera', @@ -1083,6 +1124,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1127,6 +1169,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -1166,6 +1209,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -1201,6 +1249,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -1242,6 +1291,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -1283,6 +1333,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'camera', @@ -1326,6 +1377,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1370,6 +1422,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -1413,6 +1466,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -1448,6 +1506,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'alarm_control_panel', @@ -1492,6 +1551,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -1538,6 +1598,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'number', @@ -1582,6 +1643,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -1621,6 +1683,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -1656,6 +1723,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -1697,6 +1765,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -1740,6 +1809,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -1787,6 +1857,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -1822,6 +1897,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'alarm_control_panel', @@ -1866,6 +1942,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -1916,6 +1993,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -1977,6 +2055,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'number', @@ -2021,6 +2100,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -2064,6 +2144,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -2099,6 +2184,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -2142,6 +2228,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2189,6 +2276,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -2224,6 +2316,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -2265,6 +2358,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -2306,6 +2400,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'camera', @@ -2356,6 +2451,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -2414,6 +2510,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2458,6 +2555,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2504,6 +2602,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2549,6 +2648,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2592,6 +2692,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -2632,6 +2733,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -2675,6 +2777,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -2710,6 +2817,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -2753,6 +2861,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2798,6 +2907,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2843,6 +2953,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2888,6 +2999,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2933,6 +3045,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -2978,6 +3091,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -3021,6 +3135,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -3062,6 +3177,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -3106,6 +3222,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -3141,6 +3262,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -3182,6 +3304,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -3225,6 +3348,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -3267,6 +3391,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -3302,6 +3431,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -3343,6 +3473,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -3384,6 +3515,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -3424,6 +3556,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -3476,6 +3609,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -3540,6 +3674,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -3590,6 +3725,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -3636,6 +3772,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -3681,6 +3818,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -3723,6 +3861,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -3758,6 +3901,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -3799,6 +3943,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -3842,6 +3987,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -3884,6 +4030,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -3919,6 +4070,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -3960,6 +4112,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -4003,6 +4156,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -4049,6 +4203,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -4084,6 +4243,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -4125,6 +4285,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -4166,6 +4327,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -4206,6 +4368,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -4258,6 +4421,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -4322,6 +4486,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -4372,6 +4537,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -4418,6 +4584,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -4463,6 +4630,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -4509,6 +4677,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -4544,6 +4717,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -4585,6 +4759,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -4625,6 +4800,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -4660,6 +4840,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -4712,6 +4893,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -4775,6 +4957,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -4821,6 +5004,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -4866,6 +5050,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -4908,6 +5093,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -4943,6 +5133,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -4984,6 +5175,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -5027,6 +5219,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5069,6 +5262,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -5104,6 +5302,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -5145,6 +5344,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -5188,6 +5388,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5234,6 +5435,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -5269,6 +5475,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -5310,6 +5517,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -5351,6 +5559,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -5391,6 +5600,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -5447,6 +5657,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -5516,6 +5727,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -5566,6 +5778,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -5612,6 +5825,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5657,6 +5871,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5703,6 +5918,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -5738,6 +5958,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -5779,6 +6000,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -5820,6 +6042,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -5863,6 +6086,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5908,6 +6132,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -5951,6 +6176,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -5994,6 +6220,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -6029,6 +6260,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6075,6 +6307,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'number', @@ -6124,6 +6357,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -6170,6 +6404,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6215,6 +6450,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6261,6 +6497,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6306,6 +6543,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6352,6 +6590,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -6387,6 +6630,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6430,6 +6674,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6475,6 +6720,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6520,6 +6766,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6565,6 +6812,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -6608,6 +6856,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -6649,6 +6898,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -6692,6 +6942,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -6727,6 +6982,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6768,6 +7024,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6808,6 +7065,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6851,6 +7109,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -6899,6 +7158,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -6934,6 +7198,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -6975,6 +7240,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -7018,6 +7284,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7053,6 +7324,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7094,6 +7366,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -7138,6 +7411,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -7181,6 +7455,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7216,6 +7495,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7256,6 +7536,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7291,6 +7576,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7332,6 +7618,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -7376,6 +7663,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -7423,6 +7711,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7458,6 +7751,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7501,6 +7795,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -7545,6 +7840,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7580,6 +7880,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7620,6 +7921,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7655,6 +7961,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7698,6 +8005,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -7747,6 +8055,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -7782,6 +8095,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -7833,6 +8147,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -7887,6 +8202,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -7938,6 +8254,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -7984,6 +8301,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -8029,6 +8347,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -8071,6 +8390,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8106,6 +8430,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8150,6 +8475,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8185,6 +8515,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8225,6 +8556,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8260,6 +8596,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8305,6 +8642,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -8353,6 +8691,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -8400,6 +8739,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8435,6 +8779,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8476,6 +8821,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -8520,6 +8866,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -8563,6 +8910,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8598,6 +8950,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8638,6 +8991,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8673,6 +9031,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8714,6 +9073,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -8758,6 +9118,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -8805,6 +9166,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8840,6 +9206,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -8883,6 +9250,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -8927,6 +9295,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -8962,6 +9335,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9002,6 +9376,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9037,6 +9416,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9080,6 +9460,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -9130,6 +9511,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9165,6 +9551,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9205,6 +9592,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9240,6 +9632,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9283,6 +9676,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -9333,6 +9727,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9368,6 +9767,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9423,6 +9823,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -9482,6 +9883,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -9533,6 +9935,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -9579,6 +9982,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -9624,6 +10028,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -9666,6 +10071,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9701,6 +10111,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9745,6 +10156,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9780,6 +10196,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9820,6 +10237,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -9855,6 +10277,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -9903,6 +10326,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'humidifier', @@ -9956,6 +10380,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -10002,6 +10427,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10037,6 +10467,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10077,6 +10508,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10112,6 +10548,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10160,6 +10597,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'humidifier', @@ -10213,6 +10651,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -10259,6 +10698,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10294,6 +10738,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10334,6 +10779,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10369,6 +10819,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10419,6 +10870,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -10477,6 +10929,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -10524,6 +10977,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10559,6 +11017,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10616,6 +11075,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -10678,6 +11138,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -10724,6 +11185,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10759,6 +11225,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10808,6 +11275,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -10862,6 +11330,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -10897,6 +11370,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -10946,6 +11420,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -11000,6 +11475,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11035,6 +11515,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11084,6 +11565,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -11138,6 +11620,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11173,6 +11660,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11222,6 +11710,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -11276,6 +11765,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11311,6 +11805,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11360,6 +11855,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -11424,6 +11920,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11459,6 +11960,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11508,6 +12010,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -11572,6 +12075,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11607,6 +12115,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11652,6 +12161,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'event', @@ -11701,6 +12211,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'event', @@ -11750,6 +12261,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'event', @@ -11799,6 +12311,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'event', @@ -11846,6 +12359,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -11889,6 +12403,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -11924,6 +12443,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -11969,6 +12489,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12014,6 +12535,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12049,6 +12575,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12094,6 +12621,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12139,6 +12667,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12174,6 +12707,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12219,6 +12753,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12264,6 +12799,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12299,6 +12839,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12344,6 +12885,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12389,6 +12931,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12424,6 +12971,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12469,6 +13017,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12514,6 +13063,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12549,6 +13103,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12594,6 +13149,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12639,6 +13195,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12674,6 +13235,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12719,6 +13281,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12764,6 +13327,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12799,6 +13367,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12843,6 +13412,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -12878,6 +13452,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -12928,6 +13503,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -12987,6 +13563,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13022,6 +13603,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -13065,6 +13647,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -13108,6 +13691,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -13152,6 +13736,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13187,6 +13776,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -13230,6 +13820,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -13273,6 +13864,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -13313,6 +13905,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -13356,6 +13949,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13391,6 +13989,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -13441,6 +14040,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -13501,6 +14101,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -13547,6 +14148,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -13592,6 +14194,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -13638,6 +14241,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13673,6 +14281,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -13724,6 +14333,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'media_player', @@ -13776,6 +14386,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -13819,6 +14430,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13854,6 +14470,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -13897,6 +14514,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -13941,6 +14559,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -13976,6 +14599,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -14020,6 +14644,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -14055,6 +14684,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -14096,6 +14726,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -14136,6 +14767,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -14176,6 +14808,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -14216,6 +14849,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -14256,6 +14890,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -14299,6 +14934,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -14334,6 +14974,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -14379,6 +15020,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -14428,6 +15070,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -14463,6 +15110,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -14513,6 +15161,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -14570,6 +15219,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -14621,6 +15271,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'select', @@ -14667,6 +15318,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -14712,6 +15364,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -14758,6 +15411,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -14793,6 +15451,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -14843,6 +15502,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -14918,6 +15578,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -14977,6 +15638,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15030,6 +15692,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -15065,6 +15732,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -15106,6 +15774,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -15147,6 +15816,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'camera', @@ -15194,6 +15864,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'event', @@ -15241,6 +15912,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -15281,6 +15953,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -15324,6 +15997,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -15359,6 +16037,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -15400,6 +16079,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'binary_sensor', @@ -15441,6 +16121,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -15485,6 +16166,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -15520,6 +16206,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -15563,6 +16250,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15607,6 +16295,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15652,6 +16341,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15697,6 +16387,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15742,6 +16433,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -15788,6 +16480,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -15823,6 +16520,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -15864,6 +16562,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -15907,6 +16606,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -15950,6 +16650,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -15993,6 +16694,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -16036,6 +16738,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -16079,6 +16782,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -16122,6 +16826,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -16165,6 +16870,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -16211,6 +16917,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16246,6 +16957,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -16287,6 +16999,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -16331,6 +17044,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -16374,6 +17088,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16409,6 +17128,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -16449,6 +17169,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16484,6 +17209,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -16525,6 +17251,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -16569,6 +17296,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -16616,6 +17344,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16651,6 +17384,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -16692,6 +17426,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -16736,6 +17471,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -16779,6 +17515,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16814,6 +17555,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -16855,6 +17597,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -16899,6 +17642,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -16942,6 +17686,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -16977,6 +17726,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17018,6 +17768,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -17062,6 +17813,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -17105,6 +17857,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17140,6 +17897,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17180,6 +17938,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17215,6 +17978,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17256,6 +18020,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -17300,6 +18065,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -17347,6 +18113,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17382,6 +18153,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17423,6 +18195,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'lock', @@ -17467,6 +18240,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17502,6 +18280,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17545,6 +18324,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'fan', @@ -17595,6 +18375,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -17644,6 +18425,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17679,6 +18465,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17720,6 +18507,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -17766,6 +18554,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -17801,6 +18594,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -17852,6 +18646,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'climate', @@ -17907,6 +18702,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -17950,6 +18746,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -17990,6 +18787,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -18031,6 +18829,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -18072,6 +18871,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -18113,6 +18913,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', @@ -18157,6 +18958,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18192,6 +18998,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18235,6 +19042,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18280,6 +19088,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18325,6 +19134,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18371,6 +19181,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18406,6 +19221,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18446,6 +19262,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18481,6 +19302,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18524,6 +19346,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18569,6 +19392,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18614,6 +19438,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -18656,6 +19481,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18691,6 +19521,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18732,6 +19563,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -18778,6 +19610,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18813,6 +19650,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18854,6 +19692,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -18900,6 +19739,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -18935,6 +19779,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -18976,6 +19821,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'cover', @@ -19021,6 +19867,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -19056,6 +19907,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -19104,6 +19956,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'humidifier', @@ -19164,6 +20017,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'light', @@ -19235,6 +20089,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'number', @@ -19281,6 +20136,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -19327,6 +20183,11 @@ 'config_entries': list([ 'TestData', ]), + 'config_entries_subentries': dict({ + 'TestData': list([ + None, + ]), + }), 'configuration_url': None, 'connections': list([ ]), @@ -19362,6 +20223,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'button', @@ -19405,6 +20267,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'sensor', @@ -19448,6 +20311,7 @@ 'categories': dict({ }), 'config_entry_id': 'TestData', + 'config_subentry_id': None, 'device_class': None, 'disabled_by': None, 'domain': 'switch', diff --git a/tests/components/homewizard/snapshots/test_button.ambr b/tests/components/homewizard/snapshots/test_button.ambr index 6dd7fcc45d2..16cc62ad726 100644 --- a/tests/components/homewizard/snapshots/test_button.ambr +++ b/tests/components/homewizard/snapshots/test_button.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/homewizard/snapshots/test_config_flow.ambr b/tests/components/homewizard/snapshots/test_config_flow.ambr index 0a301fc3941..71e70f3a153 100644 --- a/tests/components/homewizard/snapshots/test_config_flow.ambr +++ b/tests/components/homewizard/snapshots/test_config_flow.ambr @@ -30,10 +30,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'zeroconf', + 'subentries': list([ + ]), 'title': 'P1 meter', 'unique_id': 'HWE-P1_5c2fafabcdef', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'P1 meter', 'type': , 'version': 1, @@ -74,10 +78,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'zeroconf', + 'subentries': list([ + ]), 'title': 'P1 meter', 'unique_id': 'HWE-P1_5c2fafabcdef', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'P1 meter', 'type': , 'version': 1, @@ -118,10 +126,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'zeroconf', + 'subentries': list([ + ]), 'title': 'Energy Socket', 'unique_id': 'HWE-SKT_5c2fafabcdef', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Energy Socket', 'type': , 'version': 1, @@ -158,10 +170,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'P1 meter', 'unique_id': 'HWE-P1_5c2fafabcdef', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'P1 meter', 'type': , 'version': 1, diff --git a/tests/components/homewizard/snapshots/test_number.ambr b/tests/components/homewizard/snapshots/test_number.ambr index b14028cd97c..1c901bda6f6 100644 --- a/tests/components/homewizard/snapshots/test_number.ambr +++ b/tests/components/homewizard/snapshots/test_number.ambr @@ -29,6 +29,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -121,6 +123,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -151,6 +154,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/homewizard/snapshots/test_sensor.ambr b/tests/components/homewizard/snapshots/test_sensor.ambr index 91b1e30e4f8..f68b5a57d2e 100644 --- a/tests/components/homewizard/snapshots/test_sensor.ambr +++ b/tests/components/homewizard/snapshots/test_sensor.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -44,6 +45,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -88,6 +90,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -129,6 +132,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -175,6 +179,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -216,6 +221,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -262,6 +268,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -303,6 +310,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +357,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -390,6 +399,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -436,6 +446,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -477,6 +488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -526,6 +538,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -567,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -616,6 +630,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -655,6 +670,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -699,6 +715,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -740,6 +757,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -786,6 +804,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -827,6 +846,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -872,6 +892,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -911,6 +932,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -954,6 +976,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -995,6 +1018,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1041,6 +1065,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1082,6 +1107,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1128,6 +1154,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1169,6 +1196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1215,6 +1243,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1256,6 +1285,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1302,6 +1332,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1343,6 +1374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1389,6 +1421,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1430,6 +1463,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1479,6 +1513,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1520,6 +1555,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1566,6 +1602,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1607,6 +1644,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1653,6 +1691,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1694,6 +1733,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1740,6 +1780,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1779,6 +1820,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1822,6 +1864,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1863,6 +1906,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1908,6 +1952,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -1949,6 +1994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1995,6 +2041,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2036,6 +2083,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2082,6 +2130,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2123,6 +2172,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2169,6 +2219,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2210,6 +2261,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2256,6 +2308,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2297,6 +2350,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2343,6 +2397,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2384,6 +2439,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2430,6 +2486,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2471,6 +2528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2517,6 +2575,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2558,6 +2617,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2604,6 +2664,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2645,6 +2706,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2691,6 +2753,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2732,6 +2795,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2778,6 +2842,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2819,6 +2884,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2865,6 +2931,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2906,6 +2973,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2955,6 +3023,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -2996,6 +3065,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3042,6 +3112,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3083,6 +3154,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3129,6 +3201,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3170,6 +3243,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3216,6 +3290,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3257,6 +3332,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3306,6 +3382,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3347,6 +3424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3396,6 +3474,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3437,6 +3516,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3486,6 +3566,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3527,6 +3608,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3573,6 +3655,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3614,6 +3697,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3660,6 +3744,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3701,6 +3786,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3747,6 +3833,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3788,6 +3875,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3834,6 +3922,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3875,6 +3964,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3921,6 +4011,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -3962,6 +4053,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4008,6 +4100,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4049,6 +4142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4095,6 +4189,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4134,6 +4229,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4177,6 +4273,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4218,6 +4315,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4263,6 +4361,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4302,6 +4401,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4347,6 +4447,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4388,6 +4489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4434,6 +4536,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4475,6 +4578,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4521,6 +4625,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4562,6 +4667,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4608,6 +4714,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4647,6 +4754,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4690,6 +4798,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4731,6 +4840,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4777,6 +4887,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4818,6 +4929,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4864,6 +4976,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4905,6 +5018,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4951,6 +5065,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -4992,6 +5107,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5038,6 +5154,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5079,6 +5196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5125,6 +5243,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5166,6 +5285,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5212,6 +5332,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5253,6 +5374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5299,6 +5421,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5340,6 +5463,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5386,6 +5510,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5427,6 +5552,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5473,6 +5599,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5514,6 +5641,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5560,6 +5688,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5601,6 +5730,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5647,6 +5777,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5686,6 +5817,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5729,6 +5861,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5768,6 +5901,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5813,6 +5947,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5854,6 +5989,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5903,6 +6039,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -5942,6 +6079,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5985,6 +6123,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6026,6 +6165,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6075,6 +6215,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6116,6 +6257,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6165,6 +6307,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6206,6 +6349,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6255,6 +6399,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6294,6 +6439,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6337,6 +6483,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6376,6 +6523,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6419,6 +6567,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6465,6 +6614,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6515,6 +6665,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6556,6 +6707,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6602,6 +6754,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6643,6 +6796,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6689,6 +6843,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6730,6 +6885,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6776,6 +6932,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6817,6 +6974,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6863,6 +7021,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6902,6 +7061,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6945,6 +7105,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -6984,6 +7145,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7027,6 +7189,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7066,6 +7229,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7109,6 +7273,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7148,6 +7313,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7191,6 +7357,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7230,6 +7397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7273,6 +7441,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7312,6 +7481,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7355,6 +7525,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7396,6 +7567,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7441,6 +7613,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7480,6 +7653,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7523,6 +7697,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -7564,6 +7739,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7609,6 +7785,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -7646,6 +7823,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7692,6 +7870,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -7729,6 +7908,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7775,6 +7955,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -7812,6 +7993,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7857,6 +8039,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -7894,6 +8077,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7940,6 +8124,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -7977,6 +8162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8023,6 +8209,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8062,6 +8249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8107,6 +8295,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8148,6 +8337,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8194,6 +8384,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8235,6 +8426,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8281,6 +8473,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8322,6 +8515,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8368,6 +8562,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8407,6 +8602,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8450,6 +8646,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8491,6 +8688,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8537,6 +8735,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8578,6 +8777,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8624,6 +8824,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8665,6 +8866,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8711,6 +8913,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8752,6 +8955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8798,6 +9002,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8839,6 +9044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8885,6 +9091,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -8926,6 +9133,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -8972,6 +9180,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9013,6 +9222,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9059,6 +9269,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9100,6 +9311,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9146,6 +9358,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9187,6 +9400,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9233,6 +9447,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9274,6 +9489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9320,6 +9536,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9361,6 +9578,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9407,6 +9625,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9446,6 +9665,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9489,6 +9709,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9528,6 +9749,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9573,6 +9795,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9614,6 +9837,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9663,6 +9887,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9702,6 +9927,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9745,6 +9971,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9786,6 +10013,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9835,6 +10063,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9876,6 +10105,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -9925,6 +10155,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -9966,6 +10197,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10015,6 +10247,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10054,6 +10287,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10097,6 +10331,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10136,6 +10371,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10179,6 +10415,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10225,6 +10462,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10275,6 +10513,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10316,6 +10555,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10362,6 +10602,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10403,6 +10644,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10449,6 +10691,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10490,6 +10733,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10536,6 +10780,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10577,6 +10822,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10623,6 +10869,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10662,6 +10909,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10705,6 +10953,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10744,6 +10993,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10787,6 +11037,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10826,6 +11077,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10869,6 +11121,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10908,6 +11161,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -10951,6 +11205,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -10990,6 +11245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11033,6 +11289,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11072,6 +11329,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11115,6 +11373,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11156,6 +11415,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11201,6 +11461,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11240,6 +11501,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11283,6 +11545,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11324,6 +11587,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11369,6 +11633,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -11406,6 +11671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11452,6 +11718,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -11489,6 +11756,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11535,6 +11803,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -11572,6 +11841,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11617,6 +11887,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -11654,6 +11925,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11700,6 +11972,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -11737,6 +12010,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11783,6 +12057,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11822,6 +12097,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11867,6 +12143,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11908,6 +12185,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -11954,6 +12232,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -11995,6 +12274,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12041,6 +12321,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12082,6 +12363,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12128,6 +12410,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12169,6 +12452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12215,6 +12499,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12256,6 +12541,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12302,6 +12588,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12343,6 +12630,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12389,6 +12677,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12430,6 +12719,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12476,6 +12766,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12517,6 +12808,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12563,6 +12855,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12604,6 +12897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12650,6 +12944,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12691,6 +12986,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12737,6 +13033,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12778,6 +13075,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12824,6 +13122,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12865,6 +13164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12911,6 +13211,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -12952,6 +13253,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -12998,6 +13300,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13039,6 +13342,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13085,6 +13389,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13124,6 +13429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13167,6 +13473,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13208,6 +13515,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13257,6 +13565,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13296,6 +13605,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13339,6 +13649,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13380,6 +13691,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13429,6 +13741,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13470,6 +13783,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13519,6 +13833,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13560,6 +13875,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13609,6 +13925,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13650,6 +13967,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13696,6 +14014,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13737,6 +14056,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13783,6 +14103,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13824,6 +14145,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13870,6 +14192,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13911,6 +14234,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -13957,6 +14281,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -13996,6 +14321,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14039,6 +14365,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14078,6 +14405,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14121,6 +14449,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14160,6 +14489,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14203,6 +14533,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14242,6 +14573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14285,6 +14617,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14324,6 +14657,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14367,6 +14701,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14406,6 +14741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14449,6 +14785,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14490,6 +14827,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14535,6 +14873,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14574,6 +14913,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14617,6 +14957,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14658,6 +14999,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14703,6 +15045,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14744,6 +15087,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14790,6 +15134,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14831,6 +15176,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14877,6 +15223,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -14918,6 +15265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -14967,6 +15315,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15008,6 +15357,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15057,6 +15407,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15096,6 +15447,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15139,6 +15491,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15180,6 +15533,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15225,6 +15579,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15266,6 +15621,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15312,6 +15668,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15353,6 +15710,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15399,6 +15757,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15440,6 +15799,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15486,6 +15846,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15527,6 +15888,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15573,6 +15935,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15614,6 +15977,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15660,6 +16024,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15701,6 +16066,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15750,6 +16116,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15791,6 +16158,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15837,6 +16205,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15878,6 +16247,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -15927,6 +16297,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -15968,6 +16339,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16014,6 +16386,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16055,6 +16428,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16101,6 +16475,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16140,6 +16515,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16183,6 +16559,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16224,6 +16601,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16269,6 +16647,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16310,6 +16689,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16356,6 +16736,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16397,6 +16778,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16442,6 +16824,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16481,6 +16864,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16524,6 +16908,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16565,6 +16950,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16610,6 +16996,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16651,6 +17038,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16697,6 +17085,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16738,6 +17127,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16784,6 +17174,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16825,6 +17216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16871,6 +17263,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16912,6 +17305,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -16958,6 +17352,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -16999,6 +17394,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17045,6 +17441,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17086,6 +17483,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17135,6 +17533,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17176,6 +17575,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17222,6 +17622,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17263,6 +17664,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17309,6 +17711,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17350,6 +17753,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17396,6 +17800,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17435,6 +17840,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17478,6 +17884,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17519,6 +17926,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17564,6 +17972,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17605,6 +18014,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17651,6 +18061,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17692,6 +18103,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17738,6 +18150,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17779,6 +18192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17825,6 +18239,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17866,6 +18281,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17912,6 +18328,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -17953,6 +18370,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -17999,6 +18417,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18040,6 +18459,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18086,6 +18506,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18127,6 +18548,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18173,6 +18595,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18214,6 +18637,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18260,6 +18684,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18301,6 +18726,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18347,6 +18773,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18388,6 +18815,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18434,6 +18862,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18475,6 +18904,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18521,6 +18951,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18562,6 +18993,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18611,6 +19043,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18652,6 +19085,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18698,6 +19132,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18739,6 +19174,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18785,6 +19221,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18826,6 +19263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18872,6 +19310,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -18913,6 +19352,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -18962,6 +19402,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19003,6 +19444,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19052,6 +19494,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19093,6 +19536,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19142,6 +19586,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19183,6 +19628,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19229,6 +19675,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19270,6 +19717,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19316,6 +19764,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19357,6 +19806,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19403,6 +19853,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19444,6 +19895,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19490,6 +19942,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19531,6 +19984,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19577,6 +20031,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19618,6 +20073,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19664,6 +20120,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19705,6 +20162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19751,6 +20209,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19790,6 +20249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -19833,6 +20293,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -19874,6 +20335,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/homewizard/snapshots/test_switch.ambr b/tests/components/homewizard/snapshots/test_switch.ambr index 8f6af16068d..cd21cb92819 100644 --- a/tests/components/homewizard/snapshots/test_switch.ambr +++ b/tests/components/homewizard/snapshots/test_switch.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -49,6 +50,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -131,6 +134,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -184,6 +188,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -214,6 +219,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -266,6 +272,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +303,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -348,6 +356,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -378,6 +387,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -431,6 +441,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -461,6 +472,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -513,6 +525,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -543,6 +556,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -595,6 +609,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -625,6 +640,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -677,6 +693,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -707,6 +724,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -759,6 +777,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -789,6 +808,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -841,6 +861,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -871,6 +892,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr index 16d9452e847..a077eb134d4 100644 --- a/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +148,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -238,6 +243,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower/snapshots/test_button.ambr b/tests/components/husqvarna_automower/snapshots/test_button.ambr index 2ce3aae3065..088850c1e07 100644 --- a/tests/components/husqvarna_automower/snapshots/test_button.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower/snapshots/test_device_tracker.ambr b/tests/components/husqvarna_automower/snapshots/test_device_tracker.ambr index 156eee9b8df..e94eea4087c 100644 --- a/tests/components/husqvarna_automower/snapshots/test_device_tracker.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr index a4dc986c2f9..2dab82451a6 100644 --- a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr @@ -183,6 +183,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Husqvarna Automower of Erika Mustermann', 'unique_id': '123', 'version': 1, diff --git a/tests/components/husqvarna_automower/snapshots/test_init.ambr b/tests/components/husqvarna_automower/snapshots/test_init.ambr index 036783dd6d0..1428a75d7b4 100644 --- a/tests/components/husqvarna_automower/snapshots/test_init.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'garden', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/husqvarna_automower/snapshots/test_number.ambr b/tests/components/husqvarna_automower/snapshots/test_number.ambr index b0ccce5800a..291aef83dbf 100644 --- a/tests/components/husqvarna_automower/snapshots/test_number.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -178,6 +181,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr index d57a829a997..02a64718276 100644 --- a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -260,6 +262,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -455,6 +458,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -504,6 +508,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -560,6 +565,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +620,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -663,6 +670,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -711,6 +719,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -760,6 +769,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -809,6 +819,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -869,6 +880,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -930,6 +942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -984,6 +997,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1038,6 +1052,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1092,6 +1107,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1146,6 +1162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1205,6 +1222,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1265,6 +1283,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1463,6 +1482,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1666,6 +1686,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1720,6 +1741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1780,6 +1802,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower/snapshots/test_switch.ambr b/tests/components/husqvarna_automower/snapshots/test_switch.ambr index 8f8f6b367c0..5e01694e924 100644 --- a/tests/components/husqvarna_automower/snapshots/test_switch.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/husqvarna_automower_ble/snapshots/test_init.ambr b/tests/components/husqvarna_automower_ble/snapshots/test_init.ambr index 1cc54020195..b7aa14ef0bf 100644 --- a/tests/components/husqvarna_automower_ble/snapshots/test_init.ambr +++ b/tests/components/husqvarna_automower_ble/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/hydrawise/snapshots/test_binary_sensor.ambr b/tests/components/hydrawise/snapshots/test_binary_sensor.ambr index 9886345595d..84e52a7f966 100644 --- a/tests/components/hydrawise/snapshots/test_binary_sensor.ambr +++ b/tests/components/hydrawise/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/hydrawise/snapshots/test_sensor.ambr b/tests/components/hydrawise/snapshots/test_sensor.ambr index dadf3c44789..3e475b1eeb1 100644 --- a/tests/components/hydrawise/snapshots/test_sensor.ambr +++ b/tests/components/hydrawise/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -61,6 +62,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -165,6 +168,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -220,6 +224,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +280,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -324,6 +330,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -372,6 +379,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -420,6 +428,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +485,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -525,6 +535,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -573,6 +584,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/hydrawise/snapshots/test_switch.ambr b/tests/components/hydrawise/snapshots/test_switch.ambr index 977bd15f004..9ad37ddbfbf 100644 --- a/tests/components/hydrawise/snapshots/test_switch.ambr +++ b/tests/components/hydrawise/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/hydrawise/snapshots/test_valve.ambr b/tests/components/hydrawise/snapshots/test_valve.ambr index cac08893324..197e7796a07 100644 --- a/tests/components/hydrawise/snapshots/test_valve.ambr +++ b/tests/components/hydrawise/snapshots/test_valve.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/igloohome/snapshots/test_sensor.ambr b/tests/components/igloohome/snapshots/test_sensor.ambr index f65baa484a0..9e17343d4fa 100644 --- a/tests/components/igloohome/snapshots/test_sensor.ambr +++ b/tests/components/igloohome/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/image/conftest.py b/tests/components/image/conftest.py index 06ef7db9f49..6879bc793bb 100644 --- a/tests/components/image/conftest.py +++ b/tests/components/image/conftest.py @@ -7,7 +7,10 @@ import pytest from homeassistant.components import image from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -123,7 +126,7 @@ class MockImageConfigEntry: self, hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test image platform via config entry.""" async_add_entities([self._entities]) diff --git a/tests/components/imgw_pib/snapshots/test_diagnostics.ambr b/tests/components/imgw_pib/snapshots/test_diagnostics.ambr index a98f60a2b3e..97453930c1e 100644 --- a/tests/components/imgw_pib/snapshots/test_diagnostics.ambr +++ b/tests/components/imgw_pib/snapshots/test_diagnostics.ambr @@ -15,6 +15,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'River Name (Station Name)', 'unique_id': '123', 'version': 1, diff --git a/tests/components/imgw_pib/snapshots/test_sensor.ambr b/tests/components/imgw_pib/snapshots/test_sensor.ambr index c7779f5d850..ccc6e46befa 100644 --- a/tests/components/imgw_pib/snapshots/test_sensor.ambr +++ b/tests/components/imgw_pib/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -63,6 +64,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/incomfort/snapshots/test_binary_sensor.ambr b/tests/components/incomfort/snapshots/test_binary_sensor.ambr index fe0d8edd0f0..518ea230705 100644 --- a/tests/components/incomfort/snapshots/test_binary_sensor.ambr +++ b/tests/components/incomfort/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -148,6 +151,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -195,6 +199,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -242,6 +247,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +296,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -337,6 +344,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -384,6 +392,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -431,6 +440,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -479,6 +489,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -526,6 +537,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -573,6 +585,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -620,6 +633,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -668,6 +682,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -715,6 +730,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -762,6 +778,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -809,6 +826,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -857,6 +875,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -904,6 +923,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/incomfort/snapshots/test_climate.ambr b/tests/components/incomfort/snapshots/test_climate.ambr index e0e8b9562dd..df3fe3f710b 100644 --- a/tests/components/incomfort/snapshots/test_climate.ambr +++ b/tests/components/incomfort/snapshots/test_climate.ambr @@ -12,6 +12,7 @@ 'min_temp': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -78,6 +79,7 @@ 'min_temp': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +146,7 @@ 'min_temp': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -210,6 +213,7 @@ 'min_temp': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/incomfort/snapshots/test_sensor.ambr b/tests/components/incomfort/snapshots/test_sensor.ambr index a69a64d964e..294a6094164 100644 --- a/tests/components/incomfort/snapshots/test_sensor.ambr +++ b/tests/components/incomfort/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/incomfort/snapshots/test_water_heater.ambr b/tests/components/incomfort/snapshots/test_water_heater.ambr index d2cd955a9fc..d3fc2b057fc 100644 --- a/tests/components/incomfort/snapshots/test_water_heater.ambr +++ b/tests/components/incomfort/snapshots/test_water_heater.ambr @@ -9,6 +9,7 @@ 'min_temp': 30.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/intellifire/snapshots/test_binary_sensor.ambr b/tests/components/intellifire/snapshots/test_binary_sensor.ambr index 1b85db51d68..afa3c1fa8a9 100644 --- a/tests/components/intellifire/snapshots/test_binary_sensor.ambr +++ b/tests/components/intellifire/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -341,6 +348,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -389,6 +397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -437,6 +446,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -485,6 +495,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -533,6 +544,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -581,6 +593,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -629,6 +642,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -676,6 +690,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -724,6 +739,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -771,6 +787,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/intellifire/snapshots/test_climate.ambr b/tests/components/intellifire/snapshots/test_climate.ambr index 36f719d2264..d0744424cff 100644 --- a/tests/components/intellifire/snapshots/test_climate.ambr +++ b/tests/components/intellifire/snapshots/test_climate.ambr @@ -14,6 +14,7 @@ 'target_temp_step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/intellifire/snapshots/test_sensor.ambr b/tests/components/intellifire/snapshots/test_sensor.ambr index d749da216ac..548c8d5a8aa 100644 --- a/tests/components/intellifire/snapshots/test_sensor.ambr +++ b/tests/components/intellifire/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -200,6 +204,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -248,6 +253,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -297,6 +303,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +356,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -401,6 +409,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -450,6 +459,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iotty/conftest.py b/tests/components/iotty/conftest.py index 51a23bf18c7..1ce645b402e 100644 --- a/tests/components/iotty/conftest.py +++ b/tests/components/iotty/conftest.py @@ -169,7 +169,7 @@ def mock_iotty() -> Generator[MagicMock]: def mock_coordinator() -> Generator[MagicMock]: """Mock IottyDataUpdateCoordinator.""" with patch( - "homeassistant.components.iotty.coordinator.IottyDataUpdateCoordinator", + "homeassistant.components.iotty.IottyDataUpdateCoordinator", autospec=True, ) as coordinator_mock: yield coordinator_mock diff --git a/tests/components/iotty/snapshots/test_switch.ambr b/tests/components/iotty/snapshots/test_switch.ambr index c6e8764cf37..16913d340f0 100644 --- a/tests/components/iotty/snapshots/test_switch.ambr +++ b/tests/components/iotty/snapshots/test_switch.ambr @@ -15,6 +15,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ipp/snapshots/test_sensor.ambr b/tests/components/ipp/snapshots/test_sensor.ambr index 3f910399ad8..f8e0578a6b9 100644 --- a/tests/components/ipp/snapshots/test_sensor.ambr +++ b/tests/components/ipp/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -73,6 +74,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -126,6 +128,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -232,6 +236,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -283,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -332,6 +338,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iqvia/snapshots/test_diagnostics.ambr b/tests/components/iqvia/snapshots/test_diagnostics.ambr index f2fa656cb0f..41cfedb0e29 100644 --- a/tests/components/iqvia/snapshots/test_diagnostics.ambr +++ b/tests/components/iqvia/snapshots/test_diagnostics.ambr @@ -358,6 +358,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/iron_os/conftest.py b/tests/components/iron_os/conftest.py index f14043c096e..63c7d129987 100644 --- a/tests/components/iron_os/conftest.py +++ b/tests/components/iron_os/conftest.py @@ -24,6 +24,7 @@ from pynecil import ( import pytest from homeassistant.components.iron_os import DOMAIN +from homeassistant.config_entries import SOURCE_IGNORE from homeassistant.const import CONF_ADDRESS from tests.common import MockConfigEntry @@ -110,6 +111,19 @@ def mock_config_entry() -> MockConfigEntry: ) +@pytest.fixture(name="config_entry_ignored") +def mock_config_entry_ignored() -> MockConfigEntry: + """Mock Pinecil configuration entry for ignored device.""" + return MockConfigEntry( + domain=DOMAIN, + title=DEFAULT_NAME, + data={}, + unique_id="c0:ff:ee:c0:ff:ee", + entry_id="1234567890", + source=SOURCE_IGNORE, + ) + + @pytest.fixture(name="ble_device") def mock_ble_device() -> Generator[MagicMock]: """Mock BLEDevice.""" diff --git a/tests/components/iron_os/snapshots/test_binary_sensor.ambr b/tests/components/iron_os/snapshots/test_binary_sensor.ambr index 17b49c1d687..c36c1cc42ff 100644 --- a/tests/components/iron_os/snapshots/test_binary_sensor.ambr +++ b/tests/components/iron_os/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_button.ambr b/tests/components/iron_os/snapshots/test_button.ambr index 64a71f5e424..c9ff9181515 100644 --- a/tests/components/iron_os/snapshots/test_button.ambr +++ b/tests/components/iron_os/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_number.ambr b/tests/components/iron_os/snapshots/test_number.ambr index fc4fe96d746..62fcd120201 100644 --- a/tests/components/iron_os/snapshots/test_number.ambr +++ b/tests/components/iron_os/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +126,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -234,6 +238,7 @@ 'step': 2.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +295,7 @@ 'step': 250, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -346,6 +352,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -402,6 +409,7 @@ 'step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -458,6 +466,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -514,6 +523,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +579,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -626,6 +637,7 @@ 'step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -682,6 +694,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -739,6 +752,7 @@ 'step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -796,6 +810,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -852,6 +867,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -909,6 +925,7 @@ 'step': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -966,6 +983,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1022,6 +1040,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_select.ambr b/tests/components/iron_os/snapshots/test_select.ambr index e3989fbf863..10aacc838df 100644 --- a/tests/components/iron_os/snapshots/test_select.ambr +++ b/tests/components/iron_os/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -75,6 +76,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -136,6 +138,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +196,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -249,6 +253,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -307,6 +312,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +371,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +429,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -479,6 +487,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_sensor.ambr b/tests/components/iron_os/snapshots/test_sensor.ambr index 0eb8e81fb4f..6a30aa6632b 100644 --- a/tests/components/iron_os/snapshots/test_sensor.ambr +++ b/tests/components/iron_os/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -210,6 +214,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -259,6 +264,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -325,6 +331,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -391,6 +398,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -450,6 +458,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -505,6 +514,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -559,6 +569,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -609,6 +620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -660,6 +672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_switch.ambr b/tests/components/iron_os/snapshots/test_switch.ambr index f13cdcfe666..a3d28e58d63 100644 --- a/tests/components/iron_os/snapshots/test_switch.ambr +++ b/tests/components/iron_os/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/snapshots/test_update.ambr b/tests/components/iron_os/snapshots/test_update.ambr index e0872d032ec..f2db3246158 100644 --- a/tests/components/iron_os/snapshots/test_update.ambr +++ b/tests/components/iron_os/snapshots/test_update.ambr @@ -9,6 +9,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/iron_os/test_config_flow.py b/tests/components/iron_os/test_config_flow.py index e1ac8fb9f00..88bef117c26 100644 --- a/tests/components/iron_os/test_config_flow.py +++ b/tests/components/iron_os/test_config_flow.py @@ -106,3 +106,28 @@ async def test_async_step_bluetooth_devices_already_setup( ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "already_configured" + + +@pytest.mark.usefixtures("discovery") +async def test_async_step_user_setup_replaces_igonored_device( + hass: HomeAssistant, config_entry_ignored: AsyncMock +) -> None: + """Test the user initiated form can replace an ignored device.""" + + config_entry_ignored.add_to_hass(hass) + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + USER_INPUT, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == DEFAULT_NAME + assert result["data"] == {} + assert result["result"].unique_id == "c0:ff:ee:c0:ff:ee" diff --git a/tests/components/israel_rail/snapshots/test_sensor.ambr b/tests/components/israel_rail/snapshots/test_sensor.ambr index f851f1cd726..610c2c53e22 100644 --- a/tests/components/israel_rail/snapshots/test_sensor.ambr +++ b/tests/components/israel_rail/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -197,6 +201,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -244,6 +249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ista_ecotrend/snapshots/test_init.ambr b/tests/components/ista_ecotrend/snapshots/test_init.ambr index c84d55c059c..7329eec7f70 100644 --- a/tests/components/ista_ecotrend/snapshots/test_init.ambr +++ b/tests/components/ista_ecotrend/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://ecotrend.ista.de/', 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://ecotrend.ista.de/', 'connections': set({ }), diff --git a/tests/components/ista_ecotrend/snapshots/test_sensor.ambr b/tests/components/ista_ecotrend/snapshots/test_sensor.ambr index b5056019c74..296ce26c7f2 100644 --- a/tests/components/ista_ecotrend/snapshots/test_sensor.ambr +++ b/tests/components/ista_ecotrend/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -61,6 +62,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -115,6 +117,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -169,6 +172,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -223,6 +227,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -277,6 +282,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -331,6 +337,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -385,6 +392,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -439,6 +447,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -492,6 +501,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -546,6 +556,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -600,6 +611,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -654,6 +666,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -708,6 +721,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -762,6 +776,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -816,6 +831,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ituran/snapshots/test_device_tracker.ambr b/tests/components/ituran/snapshots/test_device_tracker.ambr index 3b650f7927f..e73f0cfee24 100644 --- a/tests/components/ituran/snapshots/test_device_tracker.ambr +++ b/tests/components/ituran/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ituran/snapshots/test_init.ambr b/tests/components/ituran/snapshots/test_init.ambr index 1e64ef9e850..b97aef6027b 100644 --- a/tests/components/ituran/snapshots/test_init.ambr +++ b/tests/components/ituran/snapshots/test_init.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/ituran/snapshots/test_sensor.ambr b/tests/components/ituran/snapshots/test_sensor.ambr index c1512de912f..f96190fdbc2 100644 --- a/tests/components/ituran/snapshots/test_sensor.ambr +++ b/tests/components/ituran/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -200,6 +204,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -251,6 +256,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/kitchen_sink/snapshots/test_sensor.ambr b/tests/components/kitchen_sink/snapshots/test_sensor.ambr index bbf88c84eca..7b433c40170 100644 --- a/tests/components/kitchen_sink/snapshots/test_sensor.ambr +++ b/tests/components/kitchen_sink/snapshots/test_sensor.ambr @@ -69,3 +69,84 @@ }), }) # --- +# name: test_states_with_subentry + set({ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'power', + 'friendly_name': 'Outlet 1 Power', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.outlet_1_power', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '50', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'power', + 'friendly_name': 'Outlet 2 Power', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.outlet_2_power', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '1500', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Sensor test', + }), + 'context': , + 'entity_id': 'sensor.sensor_test', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '15', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Statistics issues Issue 1', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.statistics_issues_issue_1', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '100', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Statistics issues Issue 2', + 'state_class': , + 'unit_of_measurement': 'dogs', + }), + 'context': , + 'entity_id': 'sensor.statistics_issues_issue_2', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '100', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Statistics issues Issue 3', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.statistics_issues_issue_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '100', + }), + }) +# --- diff --git a/tests/components/kitchen_sink/snapshots/test_switch.ambr b/tests/components/kitchen_sink/snapshots/test_switch.ambr index fe4311ad711..5535554017f 100644 --- a/tests/components/kitchen_sink/snapshots/test_switch.ambr +++ b/tests/components/kitchen_sink/snapshots/test_switch.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -49,6 +50,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -81,6 +83,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -129,6 +132,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +163,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -191,6 +196,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/kitchen_sink/test_config_flow.py b/tests/components/kitchen_sink/test_config_flow.py index 5f163d1342e..1eea1c8036b 100644 --- a/tests/components/kitchen_sink/test_config_flow.py +++ b/tests/components/kitchen_sink/test_config_flow.py @@ -104,3 +104,85 @@ async def test_options_flow(hass: HomeAssistant) -> None: assert config_entry.options == {"section_1": {"bool": True, "int": 15}} await hass.async_block_till_done() + + +@pytest.mark.usefixtures("no_platforms") +async def test_subentry_flow(hass: HomeAssistant) -> None: + """Test config flow options.""" + config_entry = MockConfigEntry(domain=DOMAIN) + config_entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + result = await hass.config_entries.subentries.async_init( + (config_entry.entry_id, "entity"), + context={"source": config_entries.SOURCE_USER}, + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "add_sensor" + + result = await hass.config_entries.subentries.async_configure( + result["flow_id"], + user_input={"name": "Sensor 1", "state": 15}, + ) + assert result["type"] is FlowResultType.CREATE_ENTRY + subentry_id = list(config_entry.subentries)[0] + assert config_entry.subentries == { + subentry_id: config_entries.ConfigSubentry( + data={"state": 15}, + subentry_id=subentry_id, + subentry_type="entity", + title="Sensor 1", + unique_id=None, + ) + } + + await hass.async_block_till_done() + + +@pytest.mark.usefixtures("no_platforms") +async def test_subentry_reconfigure_flow(hass: HomeAssistant) -> None: + """Test config flow options.""" + subentry_id = "mock_id" + config_entry = MockConfigEntry( + domain=DOMAIN, + subentries_data=[ + config_entries.ConfigSubentryData( + data={"state": 15}, + subentry_id="mock_id", + subentry_type="entity", + title="Sensor 1", + unique_id=None, + ) + ], + ) + config_entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + result = await config_entry.start_subentry_reconfigure_flow( + hass, "entity", subentry_id + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reconfigure_sensor" + + result = await hass.config_entries.subentries.async_configure( + result["flow_id"], + user_input={"name": "Renamed sensor 1", "state": 5}, + ) + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + + assert config_entry.subentries == { + subentry_id: config_entries.ConfigSubentry( + data={"state": 5}, + subentry_id=subentry_id, + subentry_type="entity", + title="Renamed sensor 1", + unique_id=None, + ) + } + + await hass.async_block_till_done() diff --git a/tests/components/kitchen_sink/test_sensor.py b/tests/components/kitchen_sink/test_sensor.py index c4b5f03499e..f980e39f652 100644 --- a/tests/components/kitchen_sink/test_sensor.py +++ b/tests/components/kitchen_sink/test_sensor.py @@ -5,11 +5,14 @@ from unittest.mock import patch import pytest from syrupy.assertion import SnapshotAssertion +from homeassistant import config_entries from homeassistant.components.kitchen_sink import DOMAIN from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component +from tests.common import MockConfigEntry + @pytest.fixture async def sensor_only() -> None: @@ -21,14 +24,41 @@ async def sensor_only() -> None: yield -@pytest.fixture(autouse=True) +@pytest.fixture async def setup_comp(hass: HomeAssistant, sensor_only): """Set up demo component.""" assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) await hass.async_block_till_done() +@pytest.mark.usefixtures("setup_comp") async def test_states(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None: """Test the expected sensor entities are added.""" states = hass.states.async_all() assert set(states) == snapshot + + +@pytest.mark.usefixtures("sensor_only") +async def test_states_with_subentry( + hass: HomeAssistant, snapshot: SnapshotAssertion +) -> None: + """Test the expected sensor entities are added.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + subentries_data=[ + config_entries.ConfigSubentryData( + data={"state": 15}, + subentry_id="blabla", + subentry_type="entity", + title="Sensor test", + unique_id=None, + ) + ], + ) + config_entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + states = hass.states.async_all() + assert set(states) == snapshot diff --git a/tests/components/knocki/snapshots/test_event.ambr b/tests/components/knocki/snapshots/test_event.ambr index fba1c90b45d..65fecd59739 100644 --- a/tests/components/knocki/snapshots/test_event.ambr +++ b/tests/components/knocki/snapshots/test_event.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/kostal_plenticore/test_diagnostics.py b/tests/components/kostal_plenticore/test_diagnostics.py index 08f06684d9a..3a99a7f681d 100644 --- a/tests/components/kostal_plenticore/test_diagnostics.py +++ b/tests/components/kostal_plenticore/test_diagnostics.py @@ -57,6 +57,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "client": { "version": "api_version='0.2.0' hostname='scb' name='PUCK RESTful API' sw_version='01.16.05025'", diff --git a/tests/components/lacrosse_view/snapshots/test_diagnostics.ambr b/tests/components/lacrosse_view/snapshots/test_diagnostics.ambr index bfbfa2901a6..0975704b680 100644 --- a/tests/components/lacrosse_view/snapshots/test_diagnostics.ambr +++ b/tests/components/lacrosse_view/snapshots/test_diagnostics.ambr @@ -25,6 +25,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/lamarzocco/snapshots/test_binary_sensor.ambr b/tests/components/lamarzocco/snapshots/test_binary_sensor.ambr index 47bca8dcb63..6cd4e8cd5ae 100644 --- a/tests/components/lamarzocco/snapshots/test_binary_sensor.ambr +++ b/tests/components/lamarzocco/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_button.ambr b/tests/components/lamarzocco/snapshots/test_button.ambr index 64d47a11072..33aace5f97a 100644 --- a/tests/components/lamarzocco/snapshots/test_button.ambr +++ b/tests/components/lamarzocco/snapshots/test_button.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_calendar.ambr b/tests/components/lamarzocco/snapshots/test_calendar.ambr index 729eed5879a..74847892cfa 100644 --- a/tests/components/lamarzocco/snapshots/test_calendar.ambr +++ b/tests/components/lamarzocco/snapshots/test_calendar.ambr @@ -90,6 +90,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -123,6 +124,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_init.ambr b/tests/components/lamarzocco/snapshots/test_init.ambr index 67aa0b8bea8..4c210136bd2 100644 --- a/tests/components/lamarzocco/snapshots/test_init.ambr +++ b/tests/components/lamarzocco/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -43,6 +44,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/lamarzocco/snapshots/test_number.ambr b/tests/components/lamarzocco/snapshots/test_number.ambr index 49e4713aab1..0748c9384a9 100644 --- a/tests/components/lamarzocco/snapshots/test_number.ambr +++ b/tests/components/lamarzocco/snapshots/test_number.ambr @@ -30,6 +30,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -87,6 +88,7 @@ 'step': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +146,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -201,6 +204,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +262,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -315,6 +320,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -672,6 +678,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -729,6 +736,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -786,6 +794,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -843,6 +852,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -900,6 +910,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -957,6 +968,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1012,6 +1024,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1067,6 +1080,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_select.ambr b/tests/components/lamarzocco/snapshots/test_select.ambr index 325409a0b7f..2e88688652a 100644 --- a/tests/components/lamarzocco/snapshots/test_select.ambr +++ b/tests/components/lamarzocco/snapshots/test_select.ambr @@ -28,6 +28,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -85,6 +86,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -142,6 +144,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -199,6 +202,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -254,6 +258,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -311,6 +316,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_sensor.ambr b/tests/components/lamarzocco/snapshots/test_sensor.ambr index be2b1672cb9..996dff93433 100644 --- a/tests/components/lamarzocco/snapshots/test_sensor.ambr +++ b/tests/components/lamarzocco/snapshots/test_sensor.ambr @@ -24,6 +24,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -259,6 +264,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -313,6 +319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -367,6 +374,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -418,6 +426,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -468,6 +477,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_switch.ambr b/tests/components/lamarzocco/snapshots/test_switch.ambr index 72fe41c1392..085d9a16125 100644 --- a/tests/components/lamarzocco/snapshots/test_switch.ambr +++ b/tests/components/lamarzocco/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -39,6 +40,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lamarzocco/snapshots/test_update.ambr b/tests/components/lamarzocco/snapshots/test_update.ambr index 40f47a783d7..17d0528c3d8 100644 --- a/tests/components/lamarzocco/snapshots/test_update.ambr +++ b/tests/components/lamarzocco/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lawn_mower/test_init.py b/tests/components/lawn_mower/test_init.py index 0735d4541ff..be588b86e80 100644 --- a/tests/components/lawn_mower/test_init.py +++ b/tests/components/lawn_mower/test_init.py @@ -14,7 +14,7 @@ from homeassistant.components.lawn_mower import ( from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow from homeassistant.const import STATE_UNAVAILABLE, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -97,7 +97,7 @@ async def test_lawn_mower_setup(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test platform via config entry.""" async_add_entities([entity1]) diff --git a/tests/components/lcn/snapshots/test_binary_sensor.ambr b/tests/components/lcn/snapshots/test_binary_sensor.ambr index 0ad31437dd1..d2d697569d1 100644 --- a/tests/components/lcn/snapshots/test_binary_sensor.ambr +++ b/tests/components/lcn/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_climate.ambr b/tests/components/lcn/snapshots/test_climate.ambr index 443b13312d1..81745ca8515 100644 --- a/tests/components/lcn/snapshots/test_climate.ambr +++ b/tests/components/lcn/snapshots/test_climate.ambr @@ -13,6 +13,7 @@ 'min_temp': 0.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_cover.ambr b/tests/components/lcn/snapshots/test_cover.ambr index 82a19060d73..d399626537d 100644 --- a/tests/components/lcn/snapshots/test_cover.ambr +++ b/tests/components/lcn/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_light.ambr b/tests/components/lcn/snapshots/test_light.ambr index f53d1fdf2dc..638cddc15cd 100644 --- a/tests/components/lcn/snapshots/test_light.ambr +++ b/tests/components/lcn/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -121,6 +123,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_scene.ambr b/tests/components/lcn/snapshots/test_scene.ambr index c039c4ef951..a5576158621 100644 --- a/tests/components/lcn/snapshots/test_scene.ambr +++ b/tests/components/lcn/snapshots/test_scene.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_sensor.ambr b/tests/components/lcn/snapshots/test_sensor.ambr index 56776e3e0f6..f8d57ed8904 100644 --- a/tests/components/lcn/snapshots/test_sensor.ambr +++ b/tests/components/lcn/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lcn/snapshots/test_switch.ambr b/tests/components/lcn/snapshots/test_switch.ambr index 36145b8d4fd..bc69b0ed483 100644 --- a/tests/components/lcn/snapshots/test_switch.ambr +++ b/tests/components/lcn/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_binary_sensor.ambr b/tests/components/lektrico/snapshots/test_binary_sensor.ambr index 6a28e7c60de..b365ff84187 100644 --- a/tests/components/lektrico/snapshots/test_binary_sensor.ambr +++ b/tests/components/lektrico/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -382,6 +390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_button.ambr b/tests/components/lektrico/snapshots/test_button.ambr index 5070cd484c4..f9cb7189237 100644 --- a/tests/components/lektrico/snapshots/test_button.ambr +++ b/tests/components/lektrico/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_init.ambr b/tests/components/lektrico/snapshots/test_init.ambr index 63739e1c9d8..35183bf5d75 100644 --- a/tests/components/lektrico/snapshots/test_init.ambr +++ b/tests/components/lektrico/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/lektrico/snapshots/test_number.ambr b/tests/components/lektrico/snapshots/test_number.ambr index 30a37a25a09..57cf40567e7 100644 --- a/tests/components/lektrico/snapshots/test_number.ambr +++ b/tests/components/lektrico/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_select.ambr b/tests/components/lektrico/snapshots/test_select.ambr index 5a964f52ada..0f564abb146 100644 --- a/tests/components/lektrico/snapshots/test_select.ambr +++ b/tests/components/lektrico/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_sensor.ambr b/tests/components/lektrico/snapshots/test_sensor.ambr index 73ec88e6fa1..aa146f55776 100644 --- a/tests/components/lektrico/snapshots/test_sensor.ambr +++ b/tests/components/lektrico/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -203,6 +207,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -266,6 +271,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +334,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -392,6 +399,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -452,6 +460,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -501,6 +510,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lektrico/snapshots/test_switch.ambr b/tests/components/lektrico/snapshots/test_switch.ambr index 3f4a1693315..c55e96ac9a9 100644 --- a/tests/components/lektrico/snapshots/test_switch.ambr +++ b/tests/components/lektrico/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/letpot/snapshots/test_switch.ambr b/tests/components/letpot/snapshots/test_switch.ambr index 28ca9603760..1a36e555dd1 100644 --- a/tests/components/letpot/snapshots/test_switch.ambr +++ b/tests/components/letpot/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/letpot/snapshots/test_time.ambr b/tests/components/letpot/snapshots/test_time.ambr index 66f6648c202..9ca75003e56 100644 --- a/tests/components/letpot/snapshots/test_time.ambr +++ b/tests/components/letpot/snapshots/test_time.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lg_thinq/snapshots/test_climate.ambr b/tests/components/lg_thinq/snapshots/test_climate.ambr index 9369367a1f7..e2fcc2540f3 100644 --- a/tests/components/lg_thinq/snapshots/test_climate.ambr +++ b/tests/components/lg_thinq/snapshots/test_climate.ambr @@ -23,6 +23,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lg_thinq/snapshots/test_event.ambr b/tests/components/lg_thinq/snapshots/test_event.ambr index 025f4496aeb..dbb43ce0bb9 100644 --- a/tests/components/lg_thinq/snapshots/test_event.ambr +++ b/tests/components/lg_thinq/snapshots/test_event.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lg_thinq/snapshots/test_number.ambr b/tests/components/lg_thinq/snapshots/test_number.ambr index 68f01854501..ef4d9a21b86 100644 --- a/tests/components/lg_thinq/snapshots/test_number.ambr +++ b/tests/components/lg_thinq/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lg_thinq/snapshots/test_sensor.ambr b/tests/components/lg_thinq/snapshots/test_sensor.ambr index fe1929944f9..5e6eb98ac42 100644 --- a/tests/components/lg_thinq/snapshots/test_sensor.ambr +++ b/tests/components/lg_thinq/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -157,6 +160,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -257,6 +262,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -305,6 +311,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -353,6 +360,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -392,4 +400,4 @@ 'last_updated': , 'state': '2024-10-10T13:14:00+00:00', }) -# --- \ No newline at end of file +# --- diff --git a/tests/components/linear_garage_door/snapshots/test_cover.ambr b/tests/components/linear_garage_door/snapshots/test_cover.ambr index 96745e1d92a..a09156c53e0 100644 --- a/tests/components/linear_garage_door/snapshots/test_cover.ambr +++ b/tests/components/linear_garage_door/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/linear_garage_door/snapshots/test_diagnostics.ambr b/tests/components/linear_garage_door/snapshots/test_diagnostics.ambr index c689d04949a..db82f41eb73 100644 --- a/tests/components/linear_garage_door/snapshots/test_diagnostics.ambr +++ b/tests/components/linear_garage_door/snapshots/test_diagnostics.ambr @@ -73,6 +73,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'test-site-name', 'unique_id': None, 'version': 1, diff --git a/tests/components/linear_garage_door/snapshots/test_light.ambr b/tests/components/linear_garage_door/snapshots/test_light.ambr index ba64a2b0a04..9e27efc02ec 100644 --- a/tests/components/linear_garage_door/snapshots/test_light.ambr +++ b/tests/components/linear_garage_door/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -178,6 +181,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/lock/conftest.py b/tests/components/lock/conftest.py index fd569b162bc..254a59cae0d 100644 --- a/tests/components/lock/conftest.py +++ b/tests/components/lock/conftest.py @@ -14,7 +14,7 @@ from homeassistant.components.lock import ( from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -120,7 +120,7 @@ async def setup_lock_platform_test_entity( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test lock platform via config entry.""" async_add_entities([entity]) diff --git a/tests/components/madvr/snapshots/test_binary_sensor.ambr b/tests/components/madvr/snapshots/test_binary_sensor.ambr index 7fd54a7c240..7d665210a6f 100644 --- a/tests/components/madvr/snapshots/test_binary_sensor.ambr +++ b/tests/components/madvr/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/madvr/snapshots/test_diagnostics.ambr b/tests/components/madvr/snapshots/test_diagnostics.ambr index 3a281391860..92d0578dba8 100644 --- a/tests/components/madvr/snapshots/test_diagnostics.ambr +++ b/tests/components/madvr/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'envy', 'unique_id': '00:11:22:33:44:55', 'version': 1, diff --git a/tests/components/madvr/snapshots/test_remote.ambr b/tests/components/madvr/snapshots/test_remote.ambr index 1157496a93e..c90270674c8 100644 --- a/tests/components/madvr/snapshots/test_remote.ambr +++ b/tests/components/madvr/snapshots/test_remote.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/madvr/snapshots/test_sensor.ambr b/tests/components/madvr/snapshots/test_sensor.ambr index 7b0dd254f77..115f6a3f5d7 100644 --- a/tests/components/madvr/snapshots/test_sensor.ambr +++ b/tests/components/madvr/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -243,6 +248,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -348,6 +355,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -405,6 +413,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -462,6 +471,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -520,6 +530,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -583,6 +594,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -639,6 +651,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -685,6 +698,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -736,6 +750,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -789,6 +804,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -838,6 +854,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -884,6 +901,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -930,6 +948,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -982,6 +1001,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1039,6 +1059,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1097,6 +1118,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1160,6 +1182,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1216,6 +1239,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1262,6 +1286,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1313,6 +1338,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/mastodon/snapshots/test_init.ambr b/tests/components/mastodon/snapshots/test_init.ambr index 37fa765acea..28157b9e6eb 100644 --- a/tests/components/mastodon/snapshots/test_init.ambr +++ b/tests/components/mastodon/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/mastodon/snapshots/test_sensor.ambr b/tests/components/mastodon/snapshots/test_sensor.ambr index c8df8cdab19..22ac2671c36 100644 --- a/tests/components/mastodon/snapshots/test_sensor.ambr +++ b/tests/components/mastodon/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/mastodon/test_services.py b/tests/components/mastodon/test_services.py index b958bcff74c..4dafa9a8e5b 100644 --- a/tests/components/mastodon/test_services.py +++ b/tests/components/mastodon/test_services.py @@ -9,6 +9,7 @@ from homeassistant.components.mastodon.const import ( ATTR_CONFIG_ENTRY_ID, ATTR_CONTENT_WARNING, ATTR_MEDIA, + ATTR_MEDIA_DESCRIPTION, ATTR_STATUS, ATTR_VISIBILITY, DOMAIN, @@ -75,6 +76,21 @@ from tests.common import MockConfigEntry "sensitive": None, }, ), + ( + { + ATTR_STATUS: "test toot", + ATTR_CONTENT_WARNING: "Spoiler", + ATTR_MEDIA: "/image.jpg", + ATTR_MEDIA_DESCRIPTION: "A test image", + }, + { + "status": "test toot", + "spoiler_text": "Spoiler", + "visibility": None, + "media_ids": "1", + "sensitive": None, + }, + ), ], ) async def test_service_post( @@ -128,6 +144,7 @@ async def test_service_post( "spoiler_text": "Spoiler", "visibility": None, "media_ids": "1", + "media_description": None, "sensitive": None, }, ), diff --git a/tests/components/matter/snapshots/test_binary_sensor.ambr b/tests/components/matter/snapshots/test_binary_sensor.ambr index 82dcc166f13..c8de905d03f 100644 --- a/tests/components/matter/snapshots/test_binary_sensor.ambr +++ b/tests/components/matter/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -382,6 +390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +486,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -523,6 +534,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +581,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -616,6 +629,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_button.ambr b/tests/components/matter/snapshots/test_button.ambr index dbbc984ab2f..448136eeed2 100644 --- a/tests/components/matter/snapshots/test_button.ambr +++ b/tests/components/matter/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +148,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -286,6 +292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +340,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -427,6 +436,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -474,6 +484,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -521,6 +532,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -568,6 +580,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +627,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -660,6 +674,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -706,6 +721,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -752,6 +768,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -799,6 +816,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -846,6 +864,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -893,6 +912,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -940,6 +960,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -987,6 +1008,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1034,6 +1056,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1081,6 +1104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1128,6 +1152,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1175,6 +1200,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1222,6 +1248,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1268,6 +1295,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1314,6 +1342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1360,6 +1389,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1407,6 +1437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1453,6 +1484,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1499,6 +1531,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1545,6 +1578,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1591,6 +1625,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1638,6 +1673,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1685,6 +1721,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1732,6 +1769,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1779,6 +1817,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1826,6 +1865,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_climate.ambr b/tests/components/matter/snapshots/test_climate.ambr index 25f5ca06f62..8aeb1aaafdd 100644 --- a/tests/components/matter/snapshots/test_climate.ambr +++ b/tests/components/matter/snapshots/test_climate.ambr @@ -13,6 +13,7 @@ 'min_temp': 5.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -75,6 +76,7 @@ 'min_temp': 10.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -141,6 +143,7 @@ 'min_temp': 16.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +212,7 @@ 'min_temp': 7, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_cover.ambr b/tests/components/matter/snapshots/test_cover.ambr index 7d036d35983..c83dcf63c6b 100644 --- a/tests/components/matter/snapshots/test_cover.ambr +++ b/tests/components/matter/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -153,6 +156,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -202,6 +206,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_event.ambr b/tests/components/matter/snapshots/test_event.ambr index 031e8e9d24f..b0ddfaed8bf 100644 --- a/tests/components/matter/snapshots/test_event.ambr +++ b/tests/components/matter/snapshots/test_event.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -74,6 +75,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -135,6 +137,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -199,6 +202,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -266,6 +270,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +338,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_fan.ambr b/tests/components/matter/snapshots/test_fan.ambr index 7f1fe7d42db..e4dc14967e5 100644 --- a/tests/components/matter/snapshots/test_fan.ambr +++ b/tests/components/matter/snapshots/test_fan.ambr @@ -15,6 +15,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -84,6 +85,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +152,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -214,6 +217,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_light.ambr b/tests/components/matter/snapshots/test_light.ambr index eff5820d27d..a56f8f891e9 100644 --- a/tests/components/matter/snapshots/test_light.ambr +++ b/tests/components/matter/snapshots/test_light.ambr @@ -14,6 +14,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -89,6 +90,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +147,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -207,6 +210,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -284,6 +288,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -346,6 +351,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -413,6 +419,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -474,6 +481,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -547,6 +555,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +623,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_lock.ambr b/tests/components/matter/snapshots/test_lock.ambr index bf34ac267d7..10ba84dd49b 100644 --- a/tests/components/matter/snapshots/test_lock.ambr +++ b/tests/components/matter/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_number.ambr b/tests/components/matter/snapshots/test_number.ambr index 7e06b6f501d..dc35f6f2a69 100644 --- a/tests/components/matter/snapshots/test_number.ambr +++ b/tests/components/matter/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -177,6 +180,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -233,6 +237,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -289,6 +294,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -344,6 +350,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -400,6 +407,7 @@ 'step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -457,6 +465,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -514,6 +523,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +579,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -625,6 +636,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -680,6 +692,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -735,6 +748,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -791,6 +805,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -847,6 +862,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -903,6 +919,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -958,6 +975,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1014,6 +1032,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1070,6 +1089,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1126,6 +1146,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1181,6 +1202,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1237,6 +1259,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1293,6 +1316,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1349,6 +1373,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1404,6 +1429,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1460,6 +1486,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1516,6 +1543,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1571,6 +1599,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_select.ambr b/tests/components/matter/snapshots/test_select.ambr index d7ddf636ff9..772ee297e13 100644 --- a/tests/components/matter/snapshots/test_select.ambr +++ b/tests/components/matter/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -70,6 +71,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -138,6 +140,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -206,6 +209,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -265,6 +269,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -324,6 +329,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -383,6 +389,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -442,6 +449,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -501,6 +509,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +567,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +624,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -672,6 +683,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -729,6 +741,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -797,6 +810,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -876,6 +890,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -944,6 +959,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1003,6 +1019,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1060,6 +1077,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1115,6 +1133,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1175,6 +1194,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1237,6 +1257,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1296,6 +1317,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1355,6 +1377,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1414,6 +1437,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1473,6 +1497,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1530,6 +1555,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1587,6 +1613,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1645,6 +1672,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1703,6 +1731,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1760,6 +1789,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1818,6 +1848,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1878,6 +1909,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_sensor.ambr b/tests/components/matter/snapshots/test_sensor.ambr index 541f1bc178f..9caa84bbf96 100644 --- a/tests/components/matter/snapshots/test_sensor.ambr +++ b/tests/components/matter/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -173,6 +176,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -224,6 +228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -274,6 +279,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -325,6 +331,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -376,6 +383,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -427,6 +435,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -478,6 +487,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -529,6 +539,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -580,6 +591,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -631,6 +643,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -682,6 +695,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -740,6 +754,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -797,6 +812,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -848,6 +864,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -899,6 +916,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -950,6 +968,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1001,6 +1020,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1052,6 +1072,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1103,6 +1124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1154,6 +1176,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1205,6 +1228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1256,6 +1280,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1310,6 +1335,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1364,6 +1390,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1418,6 +1445,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1472,6 +1500,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1526,6 +1555,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1583,6 +1613,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1640,6 +1671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1697,6 +1729,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1754,6 +1787,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1805,6 +1839,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1854,6 +1889,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1903,6 +1939,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1957,6 +1994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2008,6 +2046,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2059,6 +2098,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2113,6 +2153,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2164,6 +2205,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2218,6 +2260,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2268,6 +2311,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2319,6 +2363,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2375,6 +2420,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2430,6 +2476,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2481,6 +2528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2532,6 +2580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2589,6 +2638,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2652,6 +2702,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2708,6 +2759,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2765,6 +2817,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2822,6 +2875,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2883,6 +2937,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2937,6 +2992,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2999,6 +3055,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3054,6 +3111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3111,6 +3169,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3168,6 +3227,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3217,6 +3277,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3265,6 +3326,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3319,6 +3381,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3370,6 +3433,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3429,6 +3493,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3487,6 +3552,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3541,6 +3607,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3595,6 +3662,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_switch.ambr b/tests/components/matter/snapshots/test_switch.ambr index 8277ee28838..ebf43117846 100644 --- a/tests/components/matter/snapshots/test_switch.ambr +++ b/tests/components/matter/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -287,6 +293,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -334,6 +341,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -381,6 +389,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_vacuum.ambr b/tests/components/matter/snapshots/test_vacuum.ambr index 9e6b52ed572..0703a1af4c7 100644 --- a/tests/components/matter/snapshots/test_vacuum.ambr +++ b/tests/components/matter/snapshots/test_vacuum.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/matter/snapshots/test_valve.ambr b/tests/components/matter/snapshots/test_valve.ambr index 98634635476..99da4c2d0f6 100644 --- a/tests/components/matter/snapshots/test_valve.ambr +++ b/tests/components/matter/snapshots/test_valve.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/mealie/snapshots/test_calendar.ambr b/tests/components/mealie/snapshots/test_calendar.ambr index e5a0a697157..7587a7a55b7 100644 --- a/tests/components/mealie/snapshots/test_calendar.ambr +++ b/tests/components/mealie/snapshots/test_calendar.ambr @@ -170,6 +170,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -222,6 +223,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -274,6 +276,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -326,6 +329,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/mealie/snapshots/test_init.ambr b/tests/components/mealie/snapshots/test_init.ambr index 98ca52dd15e..aada173ffc3 100644 --- a/tests/components/mealie/snapshots/test_init.ambr +++ b/tests/components/mealie/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/mealie/snapshots/test_sensor.ambr b/tests/components/mealie/snapshots/test_sensor.ambr index e645cf4c45f..19219c01c1c 100644 --- a/tests/components/mealie/snapshots/test_sensor.ambr +++ b/tests/components/mealie/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/mealie/snapshots/test_todo.ambr b/tests/components/mealie/snapshots/test_todo.ambr index 4c58a839f57..88c677de581 100644 --- a/tests/components/mealie/snapshots/test_todo.ambr +++ b/tests/components/mealie/snapshots/test_todo.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/melcloud/snapshots/test_diagnostics.ambr b/tests/components/melcloud/snapshots/test_diagnostics.ambr index e6a432de07e..671f5afcc52 100644 --- a/tests/components/melcloud/snapshots/test_diagnostics.ambr +++ b/tests/components/melcloud/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'melcloud', 'unique_id': 'UNIQUE_TEST_ID', 'version': 1, diff --git a/tests/components/meteo_france/snapshots/test_sensor.ambr b/tests/components/meteo_france/snapshots/test_sensor.ambr index 85fdec0fcea..35b6a9d19f7 100644 --- a/tests/components/meteo_france/snapshots/test_sensor.ambr +++ b/tests/components/meteo_france/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -60,6 +61,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +111,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +159,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -205,6 +209,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +261,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -306,6 +312,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -355,6 +362,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -405,6 +413,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -454,6 +463,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -505,6 +515,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -555,6 +566,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -606,6 +618,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -659,6 +672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -709,6 +723,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/meteo_france/snapshots/test_weather.ambr b/tests/components/meteo_france/snapshots/test_weather.ambr index 9e7d7631479..7c64ee86671 100644 --- a/tests/components/meteo_france/snapshots/test_weather.ambr +++ b/tests/components/meteo_france/snapshots/test_weather.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/modern_forms/snapshots/test_diagnostics.ambr b/tests/components/modern_forms/snapshots/test_diagnostics.ambr index f8897a4a47f..1b4090ca5a4 100644 --- a/tests/components/modern_forms/snapshots/test_diagnostics.ambr +++ b/tests/components/modern_forms/snapshots/test_diagnostics.ambr @@ -16,6 +16,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'AA:BB:CC:DD:EE:FF', 'version': 1, diff --git a/tests/components/moehlenhoff_alpha2/snapshots/test_binary_sensor.ambr b/tests/components/moehlenhoff_alpha2/snapshots/test_binary_sensor.ambr index dc6680ff99a..461cb33d776 100644 --- a/tests/components/moehlenhoff_alpha2/snapshots/test_binary_sensor.ambr +++ b/tests/components/moehlenhoff_alpha2/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/moehlenhoff_alpha2/snapshots/test_button.ambr b/tests/components/moehlenhoff_alpha2/snapshots/test_button.ambr index 7dfb9edb2e8..27244d781df 100644 --- a/tests/components/moehlenhoff_alpha2/snapshots/test_button.ambr +++ b/tests/components/moehlenhoff_alpha2/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/moehlenhoff_alpha2/snapshots/test_climate.ambr b/tests/components/moehlenhoff_alpha2/snapshots/test_climate.ambr index c1a63271a33..0708137e1cf 100644 --- a/tests/components/moehlenhoff_alpha2/snapshots/test_climate.ambr +++ b/tests/components/moehlenhoff_alpha2/snapshots/test_climate.ambr @@ -19,6 +19,7 @@ 'target_temp_step': 0.2, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/moehlenhoff_alpha2/snapshots/test_sensor.ambr b/tests/components/moehlenhoff_alpha2/snapshots/test_sensor.ambr index 3fee26a6ed5..4b1c702591d 100644 --- a/tests/components/moehlenhoff_alpha2/snapshots/test_sensor.ambr +++ b/tests/components/moehlenhoff_alpha2/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/monarch_money/snapshots/test_sensor.ambr b/tests/components/monarch_money/snapshots/test_sensor.ambr index cf7e0cb7b2f..b70302188ed 100644 --- a/tests/components/monarch_money/snapshots/test_sensor.ambr +++ b/tests/components/monarch_money/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +163,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -211,6 +215,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -261,6 +266,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -311,6 +317,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +369,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -412,6 +420,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -463,6 +472,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -513,6 +523,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -564,6 +575,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +626,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -665,6 +678,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -715,6 +729,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -766,6 +781,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -816,6 +832,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -867,6 +884,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -915,6 +933,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -965,6 +984,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1018,6 +1038,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1069,6 +1090,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/monzo/snapshots/test_sensor.ambr b/tests/components/monzo/snapshots/test_sensor.ambr index 9be5943d35c..8d3f83ed4f1 100644 --- a/tests/components/monzo/snapshots/test_sensor.ambr +++ b/tests/components/monzo/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +165,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -214,6 +218,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/motionblinds_ble/snapshots/test_diagnostics.ambr b/tests/components/motionblinds_ble/snapshots/test_diagnostics.ambr index 5b4b169c0fe..d042dc02ac3 100644 --- a/tests/components/motionblinds_ble/snapshots/test_diagnostics.ambr +++ b/tests/components/motionblinds_ble/snapshots/test_diagnostics.ambr @@ -28,6 +28,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/music_assistant/snapshots/test_media_player.ambr b/tests/components/music_assistant/snapshots/test_media_player.ambr index 6c5389dbd6a..a07bde4b29d 100644 --- a/tests/components/music_assistant/snapshots/test_media_player.ambr +++ b/tests/components/music_assistant/snapshots/test_media_player.ambr @@ -7,6 +7,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -72,6 +73,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -142,6 +144,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/myuplink/snapshots/test_binary_sensor.ambr b/tests/components/myuplink/snapshots/test_binary_sensor.ambr index 755cae3c623..478c5a55b80 100644 --- a/tests/components/myuplink/snapshots/test_binary_sensor.ambr +++ b/tests/components/myuplink/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -285,6 +291,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/myuplink/snapshots/test_init.ambr b/tests/components/myuplink/snapshots/test_init.ambr index 42ed9c20669..14be11c36ec 100644 --- a/tests/components/myuplink/snapshots/test_init.ambr +++ b/tests/components/myuplink/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/myuplink/snapshots/test_number.ambr b/tests/components/myuplink/snapshots/test_number.ambr index c47d3c60295..f2c89663879 100644 --- a/tests/components/myuplink/snapshots/test_number.ambr +++ b/tests/components/myuplink/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -123,6 +125,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -178,6 +181,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -233,6 +237,7 @@ 'step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +293,7 @@ 'step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -343,6 +349,7 @@ 'step': 10.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -399,6 +406,7 @@ 'step': 10.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/myuplink/snapshots/test_select.ambr b/tests/components/myuplink/snapshots/test_select.ambr index eff06bc7f2d..032fd2ef455 100644 --- a/tests/components/myuplink/snapshots/test_select.ambr +++ b/tests/components/myuplink/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -72,6 +73,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/myuplink/snapshots/test_sensor.ambr b/tests/components/myuplink/snapshots/test_sensor.ambr index 34acbbb8785..f9249651208 100644 --- a/tests/components/myuplink/snapshots/test_sensor.ambr +++ b/tests/components/myuplink/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +372,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -416,6 +424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -467,6 +476,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -518,6 +528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -620,6 +632,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -671,6 +684,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -720,6 +734,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -766,6 +781,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -812,6 +828,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -859,6 +876,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -908,6 +926,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -959,6 +978,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1008,6 +1028,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1055,6 +1076,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1104,6 +1126,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1158,6 +1181,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1210,6 +1234,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1257,6 +1282,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1304,6 +1330,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1351,6 +1378,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1398,6 +1426,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1445,6 +1474,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1494,6 +1524,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1545,6 +1576,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1596,6 +1628,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1647,6 +1680,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1698,6 +1732,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1749,6 +1784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1800,6 +1836,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1851,6 +1888,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1902,6 +1940,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1953,6 +1992,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2002,6 +2042,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2049,6 +2090,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2098,6 +2140,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2149,6 +2192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2200,6 +2244,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2251,6 +2296,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2302,6 +2348,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2353,6 +2400,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2404,6 +2452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2455,6 +2504,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2514,6 +2564,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2580,6 +2631,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2636,6 +2688,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2682,6 +2735,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2730,6 +2784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2781,6 +2836,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2832,6 +2888,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2883,6 +2940,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2934,6 +2992,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2985,6 +3044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3036,6 +3096,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3087,6 +3148,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3138,6 +3200,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3189,6 +3252,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3240,6 +3304,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3291,6 +3356,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3350,6 +3416,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3416,6 +3483,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3472,6 +3540,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3518,6 +3587,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3564,6 +3634,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3611,6 +3682,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3660,6 +3732,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3711,6 +3784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3762,6 +3836,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3813,6 +3888,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3864,6 +3940,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3915,6 +3992,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3966,6 +4044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4017,6 +4096,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4073,6 +4153,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4133,6 +4214,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4186,6 +4268,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4232,6 +4315,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4280,6 +4364,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4331,6 +4416,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4382,6 +4468,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4433,6 +4520,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4484,6 +4572,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4535,6 +4624,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4584,6 +4674,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4631,6 +4722,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4678,6 +4770,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4725,6 +4818,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/myuplink/snapshots/test_switch.ambr b/tests/components/myuplink/snapshots/test_switch.ambr index 5d621e661ee..142d4caa455 100644 --- a/tests/components/myuplink/snapshots/test_switch.ambr +++ b/tests/components/myuplink/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nam/snapshots/test_sensor.ambr b/tests/components/nam/snapshots/test_sensor.ambr index 16129c5d7ce..429d069b741 100644 --- a/tests/components/nam/snapshots/test_sensor.ambr +++ b/tests/components/nam/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -62,6 +63,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -116,6 +118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -170,6 +173,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -224,6 +228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -278,6 +283,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -332,6 +338,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -386,6 +393,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -440,6 +448,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -494,6 +503,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -548,6 +558,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -602,6 +613,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -654,6 +666,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -703,6 +716,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -755,6 +769,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -809,6 +824,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -865,6 +881,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -919,6 +936,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -973,6 +991,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1025,6 +1044,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1079,6 +1099,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1135,6 +1156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1189,6 +1211,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1243,6 +1266,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1297,6 +1321,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1351,6 +1376,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1403,6 +1429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1457,6 +1484,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1513,6 +1541,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1567,6 +1596,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1621,6 +1651,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1675,6 +1706,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nest/test_api.py b/tests/components/nest/test_api.py index 98c3e06cfb8..1a5c4d63dba 100644 --- a/tests/components/nest/test_api.py +++ b/tests/components/nest/test_api.py @@ -89,80 +89,3 @@ async def test_auth( assert creds.client_id == CLIENT_ID assert creds.client_secret == CLIENT_SECRET assert creds.scopes == SDM_SCOPES - - -# This tests needs to be adjusted to remove lingering tasks -@pytest.mark.parametrize("expected_lingering_tasks", [True]) -@pytest.mark.parametrize( - "token_expiration_time", - [time.time() - 7 * 86400], - ids=["expires-in-past"], -) -async def test_auth_expired_token( - hass: HomeAssistant, - aioclient_mock: AiohttpClientMocker, - setup_platform: PlatformSetup, - token_expiration_time: float, -) -> None: - """Verify behavior of an expired token.""" - # Prepare a token refresh response - aioclient_mock.post( - OAUTH2_TOKEN, - json={ - "access_token": FAKE_UPDATED_TOKEN, - "expires_at": time.time() + 86400, - "expires_in": 86400, - }, - ) - # Prepare to capture credentials in API request. Empty payloads just mean - # no devices or structures are loaded. - aioclient_mock.get(f"{API_URL}/enterprises/{PROJECT_ID}/structures", json={}) - aioclient_mock.get(f"{API_URL}/enterprises/{PROJECT_ID}/devices", json={}) - - # Prepare to capture credentials for Subscriber - captured_creds = None - - def async_new_subscriber( - credentials: Credentials, - ) -> Mock: - """Capture credentials for tests.""" - nonlocal captured_creds - captured_creds = credentials - return AsyncMock() - - with patch( - "google_nest_sdm.subscriber_client.pubsub_v1.SubscriberAsyncClient", - side_effect=async_new_subscriber, - ) as new_subscriber_mock: - await setup_platform() - - calls = aioclient_mock.mock_calls - assert len(calls) == 3 - # Verify refresh token call to get an updated token - (method, url, data, headers) = calls[0] - assert data == { - "client_id": CLIENT_ID, - "client_secret": CLIENT_SECRET, - "grant_type": "refresh_token", - "refresh_token": FAKE_REFRESH_TOKEN, - } - # Verify API requests are made with the new token - (method, url, data, headers) = calls[1] - assert headers == {"Authorization": f"Bearer {FAKE_UPDATED_TOKEN}"} - (method, url, data, headers) = calls[2] - assert headers == {"Authorization": f"Bearer {FAKE_UPDATED_TOKEN}"} - - # The subscriber is created with a token that is expired. Verify that the - # credential is expired so the subscriber knows it needs to refresh it. - assert len(new_subscriber_mock.mock_calls) == 1 - assert captured_creds - creds = captured_creds - assert creds.token == FAKE_TOKEN - assert creds.refresh_token == FAKE_REFRESH_TOKEN - assert int(dt_util.as_timestamp(creds.expiry)) == int(token_expiration_time) - assert not creds.valid - assert creds.expired - assert creds.token_uri == OAUTH2_TOKEN - assert creds.client_id == CLIENT_ID - assert creds.client_secret == CLIENT_SECRET - assert creds.scopes == SDM_SCOPES diff --git a/tests/components/netatmo/snapshots/test_binary_sensor.ambr b/tests/components/netatmo/snapshots/test_binary_sensor.ambr index 6a90b4dd77a..3066c999655 100644 --- a/tests/components/netatmo/snapshots/test_binary_sensor.ambr +++ b/tests/components/netatmo/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +159,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -206,6 +210,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +261,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -304,6 +310,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -352,6 +359,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -402,6 +410,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -450,6 +459,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -498,6 +508,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_button.ambr b/tests/components/netatmo/snapshots/test_button.ambr index 6ad1b9e78ba..086403c3b69 100644 --- a/tests/components/netatmo/snapshots/test_button.ambr +++ b/tests/components/netatmo/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_camera.ambr b/tests/components/netatmo/snapshots/test_camera.ambr index 94a5ded5031..9bd10ed9b5f 100644 --- a/tests/components/netatmo/snapshots/test_camera.ambr +++ b/tests/components/netatmo/snapshots/test_camera.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -128,6 +130,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_climate.ambr b/tests/components/netatmo/snapshots/test_climate.ambr index aeae1fd71c7..506e0fb5590 100644 --- a/tests/components/netatmo/snapshots/test_climate.ambr +++ b/tests/components/netatmo/snapshots/test_climate.ambr @@ -20,6 +20,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -95,6 +96,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -176,6 +178,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +259,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -338,6 +342,7 @@ 'target_temp_step': 0.5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_cover.ambr b/tests/components/netatmo/snapshots/test_cover.ambr index 7ea016f5ae8..46aafb32e8e 100644 --- a/tests/components/netatmo/snapshots/test_cover.ambr +++ b/tests/components/netatmo/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_diagnostics.ambr b/tests/components/netatmo/snapshots/test_diagnostics.ambr index 463556ec657..4ea7e30bcf9 100644 --- a/tests/components/netatmo/snapshots/test_diagnostics.ambr +++ b/tests/components/netatmo/snapshots/test_diagnostics.ambr @@ -646,6 +646,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'netatmo', 'version': 1, diff --git a/tests/components/netatmo/snapshots/test_fan.ambr b/tests/components/netatmo/snapshots/test_fan.ambr index ba882d68e50..f850f7ada3b 100644 --- a/tests/components/netatmo/snapshots/test_fan.ambr +++ b/tests/components/netatmo/snapshots/test_fan.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_init.ambr b/tests/components/netatmo/snapshots/test_init.ambr index 60cb22d74f2..35e7f7efc29 100644 --- a/tests/components/netatmo/snapshots/test_init.ambr +++ b/tests/components/netatmo/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/control', 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/control', 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/control', 'connections': set({ }), @@ -99,6 +102,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'corridor', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -131,6 +135,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -163,6 +168,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/control', 'connections': set({ }), @@ -195,6 +201,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -227,6 +234,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -259,6 +267,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -291,6 +300,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -323,6 +333,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -355,6 +366,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -387,6 +399,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -419,6 +432,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -451,6 +465,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -483,6 +498,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -515,6 +531,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/security', 'connections': set({ }), @@ -547,6 +564,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -579,6 +597,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/security', 'connections': set({ }), @@ -611,6 +630,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.netatmo.com/security', 'connections': set({ }), @@ -643,6 +663,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -675,6 +696,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -707,6 +729,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -739,6 +762,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -771,6 +795,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -803,6 +828,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -835,6 +861,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -867,6 +894,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -899,6 +927,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -931,6 +960,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -963,6 +993,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/weather', 'connections': set({ }), @@ -995,6 +1026,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'bureau', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -1027,6 +1059,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'livingroom', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -1059,6 +1092,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'entrada', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -1091,6 +1125,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'cocina', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -1123,6 +1158,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://my.netatmo.com/app/energy', 'connections': set({ }), @@ -1155,6 +1191,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://weathermap.netatmo.com/', 'connections': set({ }), @@ -1187,6 +1224,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://weathermap.netatmo.com/', 'connections': set({ }), @@ -1219,6 +1257,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://weathermap.netatmo.com/', 'connections': set({ }), diff --git a/tests/components/netatmo/snapshots/test_light.ambr b/tests/components/netatmo/snapshots/test_light.ambr index fe5a8aac7d0..cc7da6e8712 100644 --- a/tests/components/netatmo/snapshots/test_light.ambr +++ b/tests/components/netatmo/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -121,6 +123,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_select.ambr b/tests/components/netatmo/snapshots/test_select.ambr index ff68fc71c09..d98d9adb87f 100644 --- a/tests/components/netatmo/snapshots/test_select.ambr +++ b/tests/components/netatmo/snapshots/test_select.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_sensor.ambr b/tests/components/netatmo/snapshots/test_sensor.ambr index ba18c2ca21a..b149e80fa5b 100644 --- a/tests/components/netatmo/snapshots/test_sensor.ambr +++ b/tests/components/netatmo/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -128,6 +130,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -187,6 +190,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +245,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -293,6 +298,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +348,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -393,6 +400,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -448,6 +456,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -497,6 +506,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -548,6 +558,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -606,6 +617,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -664,6 +676,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -721,6 +734,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -773,6 +787,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -823,6 +838,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -870,6 +886,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -921,6 +938,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -974,6 +992,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1021,6 +1040,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1072,6 +1092,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1122,6 +1143,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1169,6 +1191,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1218,6 +1241,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1270,6 +1294,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1320,6 +1345,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1367,6 +1393,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1416,6 +1443,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1476,6 +1504,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1529,6 +1558,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1583,6 +1613,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1637,6 +1668,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1690,6 +1722,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1744,6 +1777,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1801,6 +1835,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1855,6 +1890,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1912,6 +1948,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1966,6 +2003,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2026,6 +2064,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2079,6 +2118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2133,6 +2173,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2187,6 +2228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2240,6 +2282,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2294,6 +2337,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2351,6 +2395,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2405,6 +2450,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2462,6 +2508,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2516,6 +2563,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2576,6 +2624,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2629,6 +2678,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2683,6 +2733,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2737,6 +2788,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2790,6 +2842,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2844,6 +2897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2901,6 +2955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2955,6 +3010,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3012,6 +3068,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3064,6 +3121,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3113,6 +3171,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3173,6 +3232,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3233,6 +3293,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3292,6 +3353,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3346,6 +3408,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3398,6 +3461,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3447,6 +3511,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3498,6 +3563,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3553,6 +3619,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3602,6 +3669,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3651,6 +3719,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3698,6 +3767,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3745,6 +3815,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3792,6 +3863,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3839,6 +3911,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3888,6 +3961,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3948,6 +4022,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4000,6 +4075,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4060,6 +4136,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4119,6 +4196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4173,6 +4251,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4225,6 +4304,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4274,6 +4354,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4325,6 +4406,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4380,6 +4462,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4429,6 +4512,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4480,6 +4564,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4540,6 +4625,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4600,6 +4686,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4659,6 +4746,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4713,6 +4801,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4765,6 +4854,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4814,6 +4904,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4865,6 +4956,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4920,6 +5012,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4969,6 +5062,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5018,6 +5112,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5067,6 +5162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5117,6 +5213,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5166,6 +5263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5218,6 +5316,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5270,6 +5369,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5330,6 +5430,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5382,6 +5483,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5434,6 +5536,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5484,6 +5587,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5531,6 +5635,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5580,6 +5685,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5633,6 +5739,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5682,6 +5789,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5734,6 +5842,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5786,6 +5895,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5836,6 +5946,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5883,6 +5994,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5932,6 +6044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -5985,6 +6098,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6034,6 +6148,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6088,6 +6203,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6140,6 +6256,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6200,6 +6317,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6260,6 +6378,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6310,6 +6429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6357,6 +6477,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6406,6 +6527,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6466,6 +6588,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6526,6 +6649,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6578,6 +6702,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6632,6 +6757,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6686,6 +6812,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6738,6 +6865,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6788,6 +6916,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6835,6 +6964,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6884,6 +7014,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6937,6 +7068,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -6984,6 +7116,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7035,6 +7168,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7087,6 +7221,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7139,6 +7274,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7194,6 +7330,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7244,6 +7381,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7291,6 +7429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7338,6 +7477,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7389,6 +7529,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7444,6 +7585,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -7493,6 +7635,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netatmo/snapshots/test_switch.ambr b/tests/components/netatmo/snapshots/test_switch.ambr index 4244917d86f..f44cbcd22a5 100644 --- a/tests/components/netatmo/snapshots/test_switch.ambr +++ b/tests/components/netatmo/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/netgear_lte/snapshots/test_init.ambr b/tests/components/netgear_lte/snapshots/test_init.ambr index ca65c17cc8e..2a806be8ae1 100644 --- a/tests/components/netgear_lte/snapshots/test_init.ambr +++ b/tests/components/netgear_lte/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.5.1', 'connections': set({ }), diff --git a/tests/components/nextcloud/snapshots/test_binary_sensor.ambr b/tests/components/nextcloud/snapshots/test_binary_sensor.ambr index 1831419af52..578659d411d 100644 --- a/tests/components/nextcloud/snapshots/test_binary_sensor.ambr +++ b/tests/components/nextcloud/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextcloud/snapshots/test_sensor.ambr b/tests/components/nextcloud/snapshots/test_sensor.ambr index c49ba3496da..d01bcc112bf 100644 --- a/tests/components/nextcloud/snapshots/test_sensor.ambr +++ b/tests/components/nextcloud/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -155,6 +158,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -204,6 +208,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -253,6 +258,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -302,6 +308,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -351,6 +358,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -400,6 +408,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -449,6 +458,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -498,6 +508,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -547,6 +558,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -596,6 +608,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -645,6 +658,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -694,6 +708,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -743,6 +758,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -792,6 +808,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -841,6 +858,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -890,6 +908,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -939,6 +958,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -986,6 +1006,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1032,6 +1053,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1088,6 +1110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1137,6 +1160,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1186,6 +1210,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1235,6 +1260,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1284,6 +1310,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1331,6 +1358,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1378,6 +1406,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1424,6 +1453,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1474,6 +1504,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1524,6 +1555,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1574,6 +1606,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1628,6 +1661,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1674,6 +1708,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1720,6 +1755,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1774,6 +1810,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1828,6 +1865,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1882,6 +1920,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1936,6 +1975,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1992,6 +2032,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2039,6 +2080,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2093,6 +2135,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2147,6 +2190,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2201,6 +2245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2247,6 +2292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2293,6 +2339,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2341,6 +2388,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2391,6 +2439,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2440,6 +2489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2489,6 +2539,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2536,6 +2587,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2586,6 +2638,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2642,6 +2695,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2689,6 +2743,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2741,6 +2796,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2788,6 +2844,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2837,6 +2894,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2886,6 +2944,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2935,6 +2994,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2984,6 +3044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3031,6 +3092,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3078,6 +3140,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3132,6 +3195,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3186,6 +3250,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3234,6 +3299,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3288,6 +3354,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3342,6 +3409,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3388,6 +3456,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3444,6 +3513,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3491,6 +3561,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3545,6 +3616,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3591,6 +3663,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3637,6 +3710,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3683,6 +3757,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3729,6 +3804,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3775,6 +3851,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3829,6 +3906,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3885,6 +3963,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3932,6 +4011,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextcloud/snapshots/test_update.ambr b/tests/components/nextcloud/snapshots/test_update.ambr index 484106580b1..a8acd2f5294 100644 --- a/tests/components/nextcloud/snapshots/test_update.ambr +++ b/tests/components/nextcloud/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextdns/snapshots/test_binary_sensor.ambr b/tests/components/nextdns/snapshots/test_binary_sensor.ambr index 814b4c1ac16..65a477f50f3 100644 --- a/tests/components/nextdns/snapshots/test_binary_sensor.ambr +++ b/tests/components/nextdns/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextdns/snapshots/test_button.ambr b/tests/components/nextdns/snapshots/test_button.ambr index 32dc31eea19..3f1f75d1783 100644 --- a/tests/components/nextdns/snapshots/test_button.ambr +++ b/tests/components/nextdns/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextdns/snapshots/test_diagnostics.ambr b/tests/components/nextdns/snapshots/test_diagnostics.ambr index 827d6aeb6e5..23f42fee077 100644 --- a/tests/components/nextdns/snapshots/test_diagnostics.ambr +++ b/tests/components/nextdns/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Fake Profile', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/nextdns/snapshots/test_sensor.ambr b/tests/components/nextdns/snapshots/test_sensor.ambr index 14bebea53f8..48c3b0894db 100644 --- a/tests/components/nextdns/snapshots/test_sensor.ambr +++ b/tests/components/nextdns/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -308,6 +314,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -358,6 +365,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -408,6 +416,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -458,6 +467,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -508,6 +518,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +569,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -608,6 +620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -658,6 +671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -708,6 +722,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -758,6 +773,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -808,6 +824,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -858,6 +875,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -908,6 +926,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -958,6 +977,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1008,6 +1028,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1058,6 +1079,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1108,6 +1130,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1158,6 +1181,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1208,6 +1232,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nextdns/snapshots/test_switch.ambr b/tests/components/nextdns/snapshots/test_switch.ambr index 3328e341a2e..e6d63b7f542 100644 --- a/tests/components/nextdns/snapshots/test_switch.ambr +++ b/tests/components/nextdns/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -374,6 +382,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -420,6 +429,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -466,6 +476,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -512,6 +523,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +570,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -604,6 +617,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -650,6 +664,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -696,6 +711,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -742,6 +758,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -788,6 +805,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -834,6 +852,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -880,6 +899,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -926,6 +946,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -972,6 +993,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1018,6 +1040,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1064,6 +1087,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1110,6 +1134,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1156,6 +1181,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1202,6 +1228,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1248,6 +1275,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1294,6 +1322,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1340,6 +1369,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1386,6 +1416,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1432,6 +1463,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1478,6 +1510,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1524,6 +1557,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1570,6 +1604,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1616,6 +1651,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1662,6 +1698,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1708,6 +1745,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1754,6 +1792,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1800,6 +1839,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1846,6 +1886,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1892,6 +1933,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1938,6 +1980,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1984,6 +2027,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2030,6 +2074,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2076,6 +2121,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2122,6 +2168,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2168,6 +2215,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2214,6 +2262,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2260,6 +2309,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2306,6 +2356,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2352,6 +2403,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2398,6 +2450,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2444,6 +2497,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2490,6 +2544,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2536,6 +2591,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2582,6 +2638,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2628,6 +2685,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2674,6 +2732,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2720,6 +2779,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2766,6 +2826,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2812,6 +2873,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2858,6 +2920,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2904,6 +2967,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2950,6 +3014,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2996,6 +3061,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3042,6 +3108,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3088,6 +3155,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3134,6 +3202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3180,6 +3249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3226,6 +3296,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3272,6 +3343,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3318,6 +3390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nice_go/snapshots/test_cover.ambr b/tests/components/nice_go/snapshots/test_cover.ambr index 49b5267df56..0e1f9013a94 100644 --- a/tests/components/nice_go/snapshots/test_cover.ambr +++ b/tests/components/nice_go/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nice_go/snapshots/test_diagnostics.ambr b/tests/components/nice_go/snapshots/test_diagnostics.ambr index f4ba363a421..b33726d2b72 100644 --- a/tests/components/nice_go/snapshots/test_diagnostics.ambr +++ b/tests/components/nice_go/snapshots/test_diagnostics.ambr @@ -60,6 +60,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/nice_go/snapshots/test_light.ambr b/tests/components/nice_go/snapshots/test_light.ambr index 529df95a570..2b88b7d8d74 100644 --- a/tests/components/nice_go/snapshots/test_light.ambr +++ b/tests/components/nice_go/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/niko_home_control/snapshots/test_cover.ambr b/tests/components/niko_home_control/snapshots/test_cover.ambr index 6f99c1adb8c..5fe89497298 100644 --- a/tests/components/niko_home_control/snapshots/test_cover.ambr +++ b/tests/components/niko_home_control/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/niko_home_control/snapshots/test_light.ambr b/tests/components/niko_home_control/snapshots/test_light.ambr index 702b7326ee2..adb0e743786 100644 --- a/tests/components/niko_home_control/snapshots/test_light.ambr +++ b/tests/components/niko_home_control/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nordpool/snapshots/test_sensor.ambr b/tests/components/nordpool/snapshots/test_sensor.ambr index 9b328c3a71d..86aa49357c5 100644 --- a/tests/components/nordpool/snapshots/test_sensor.ambr +++ b/tests/components/nordpool/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -107,6 +109,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +163,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -207,6 +211,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -259,6 +264,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -306,6 +312,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -358,6 +365,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -410,6 +418,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -463,6 +472,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -516,6 +526,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -567,6 +578,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +626,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -663,6 +676,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -716,6 +730,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -769,6 +784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -820,6 +836,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -867,6 +884,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -916,6 +934,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -969,6 +988,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1022,6 +1042,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1073,6 +1094,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1120,6 +1142,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1167,6 +1190,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1217,6 +1241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1265,6 +1290,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1318,6 +1344,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1371,6 +1398,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1418,6 +1446,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1470,6 +1499,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1517,6 +1547,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1569,6 +1600,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1621,6 +1653,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1674,6 +1707,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1727,6 +1761,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1778,6 +1813,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1825,6 +1861,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1874,6 +1911,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1927,6 +1965,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1980,6 +2019,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2031,6 +2071,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2078,6 +2119,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2127,6 +2169,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2180,6 +2223,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2233,6 +2277,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2284,6 +2329,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2331,6 +2377,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2378,6 +2425,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/notion/test_diagnostics.py b/tests/components/notion/test_diagnostics.py index 890ce2dfc4a..c1d1bd1bb2e 100644 --- a/tests/components/notion/test_diagnostics.py +++ b/tests/components/notion/test_diagnostics.py @@ -37,6 +37,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "data": { "bridges": [ diff --git a/tests/components/nuki/snapshots/test_binary_sensor.ambr b/tests/components/nuki/snapshots/test_binary_sensor.ambr index 55976bcb433..e48cc55bfb3 100644 --- a/tests/components/nuki/snapshots/test_binary_sensor.ambr +++ b/tests/components/nuki/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nuki/snapshots/test_lock.ambr b/tests/components/nuki/snapshots/test_lock.ambr index 24c80e7b487..2d80110a5cc 100644 --- a/tests/components/nuki/snapshots/test_lock.ambr +++ b/tests/components/nuki/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/nuki/snapshots/test_sensor.ambr b/tests/components/nuki/snapshots/test_sensor.ambr index a319104fbc3..5be025727be 100644 --- a/tests/components/nuki/snapshots/test_sensor.ambr +++ b/tests/components/nuki/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/number/test_init.py b/tests/components/number/test_init.py index 31d99dc55d7..7b19879d873 100644 --- a/tests/components/number/test_init.py +++ b/tests/components/number/test_init.py @@ -38,7 +38,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, State from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import STORAGE_KEY as RESTORE_STATE_KEY from homeassistant.setup import async_setup_component from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM @@ -974,7 +974,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test number platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) diff --git a/tests/components/nyt_games/snapshots/test_init.ambr b/tests/components/nyt_games/snapshots/test_init.ambr index 383bed0e106..d9ce6f15a4d 100644 --- a/tests/components/nyt_games/snapshots/test_init.ambr +++ b/tests/components/nyt_games/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/nyt_games/snapshots/test_sensor.ambr b/tests/components/nyt_games/snapshots/test_sensor.ambr index 84b74a26f0d..8201c26739c 100644 --- a/tests/components/nyt_games/snapshots/test_sensor.ambr +++ b/tests/components/nyt_games/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -157,6 +160,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -207,6 +211,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -257,6 +262,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -307,6 +313,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -357,6 +364,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -407,6 +415,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -458,6 +467,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -509,6 +519,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -559,6 +570,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_button.ambr b/tests/components/ohme/snapshots/test_button.ambr index 32de16208f4..b276e8c3c42 100644 --- a/tests/components/ohme/snapshots/test_button.ambr +++ b/tests/components/ohme/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_init.ambr b/tests/components/ohme/snapshots/test_init.ambr index e3ed339b78a..ccf09f546cf 100644 --- a/tests/components/ohme/snapshots/test_init.ambr +++ b/tests/components/ohme/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/ohme/snapshots/test_number.ambr b/tests/components/ohme/snapshots/test_number.ambr index 580082635df..dbcf6134252 100644 --- a/tests/components/ohme/snapshots/test_number.ambr +++ b/tests/components/ohme/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_select.ambr b/tests/components/ohme/snapshots/test_select.ambr index 04770397098..8eec0556889 100644 --- a/tests/components/ohme/snapshots/test_select.ambr +++ b/tests/components/ohme/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_sensor.ambr b/tests/components/ohme/snapshots/test_sensor.ambr index 6415d720419..b5c3c3b96d5 100644 --- a/tests/components/ohme/snapshots/test_sensor.ambr +++ b/tests/components/ohme/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -221,6 +225,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +280,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_switch.ambr b/tests/components/ohme/snapshots/test_switch.ambr index 76066b6e658..49bf5d5709a 100644 --- a/tests/components/ohme/snapshots/test_switch.ambr +++ b/tests/components/ohme/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ohme/snapshots/test_time.ambr b/tests/components/ohme/snapshots/test_time.ambr index 4d9fab20e0b..8c85fc2298e 100644 --- a/tests/components/ohme/snapshots/test_time.ambr +++ b/tests/components/ohme/snapshots/test_time.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ollama/snapshots/test_conversation.ambr b/tests/components/ollama/snapshots/test_conversation.ambr index e4dd7cd00bb..93f3b03d9af 100644 --- a/tests/components/ollama/snapshots/test_conversation.ambr +++ b/tests/components/ollama/snapshots/test_conversation.ambr @@ -1,7 +1,7 @@ # serializer version: 1 # name: test_unknown_hass_api dict({ - 'conversation_id': None, + 'conversation_id': '1234', 'response': IntentResponse( card=dict({ }), @@ -20,7 +20,7 @@ speech=dict({ 'plain': dict({ 'extra_data': None, - 'speech': 'Error preparing LLM API: API non-existing not found', + 'speech': 'Error preparing LLM API', }), }), speech_slots=dict({ diff --git a/tests/components/ollama/test_conversation.py b/tests/components/ollama/test_conversation.py index b8e299f5e77..db641ba703b 100644 --- a/tests/components/ollama/test_conversation.py +++ b/tests/components/ollama/test_conversation.py @@ -1,5 +1,6 @@ """Tests for the Ollama integration.""" +from collections.abc import AsyncGenerator from typing import Any from unittest.mock import AsyncMock, Mock, patch @@ -25,6 +26,14 @@ def mock_ulid_tools(): yield +async def stream_generator(response: dict | list[dict]) -> AsyncGenerator[dict]: + """Generate a response from the assistant.""" + if not isinstance(response, list): + response = [response] + for msg in response: + yield msg + + @pytest.mark.parametrize("agent_id", [None, "conversation.mock_title"]) async def test_chat( hass: HomeAssistant, @@ -42,7 +51,9 @@ async def test_chat( with patch( "ollama.AsyncClient.chat", - return_value={"message": {"role": "assistant", "content": "test response"}}, + return_value=stream_generator( + {"message": {"role": "assistant", "content": "test response"}} + ), ) as mock_chat: result = await conversation.async_converse( hass, @@ -81,6 +92,53 @@ async def test_chat( assert "Current time is" in detail_event["data"]["messages"][0]["content"] +async def test_chat_stream( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_init_component, +) -> None: + """Test chat messages are assembled across streamed responses.""" + + entry = MockConfigEntry() + entry.add_to_hass(hass) + + with patch( + "ollama.AsyncClient.chat", + return_value=stream_generator( + [ + {"message": {"role": "assistant", "content": "test "}}, + { + "message": {"role": "assistant", "content": "response"}, + "done": True, + "done_reason": "stop", + }, + ], + ), + ) as mock_chat: + result = await conversation.async_converse( + hass, + "test message", + None, + Context(), + agent_id=mock_config_entry.entry_id, + ) + + assert mock_chat.call_count == 1 + args = mock_chat.call_args.kwargs + prompt = args["messages"][0]["content"] + + assert args["model"] == "test model" + assert args["messages"] == [ + Message(role="system", content=prompt), + Message(role="user", content="test message"), + ] + + assert result.response.response_type == intent.IntentResponseType.ACTION_DONE, ( + result + ) + assert result.response.speech["plain"]["speech"] == "test response" + + async def test_template_variables( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: @@ -103,7 +161,9 @@ async def test_template_variables( patch("ollama.AsyncClient.list"), patch( "ollama.AsyncClient.chat", - return_value={"message": {"role": "assistant", "content": "test response"}}, + return_value=stream_generator( + {"message": {"role": "assistant", "content": "test response"}} + ), ) as mock_chat, patch("homeassistant.auth.AuthManager.async_get_user", return_value=mock_user), ): @@ -170,26 +230,30 @@ async def test_function_call( def completion_result(*args, messages, **kwargs): for message in messages: if message["role"] == "tool": - return { - "message": { - "role": "assistant", - "content": "I have successfully called the function", - } - } - - return { - "message": { - "role": "assistant", - "tool_calls": [ + return stream_generator( { - "function": { - "name": "test_tool", - "arguments": tool_args, + "message": { + "role": "assistant", + "content": "I have successfully called the function", } } - ], + ) + + return stream_generator( + { + "message": { + "role": "assistant", + "tool_calls": [ + { + "function": { + "name": "test_tool", + "arguments": tool_args, + } + } + ], + } } - } + ) with patch( "ollama.AsyncClient.chat", @@ -251,26 +315,30 @@ async def test_function_exception( def completion_result(*args, messages, **kwargs): for message in messages: if message["role"] == "tool": - return { - "message": { - "role": "assistant", - "content": "There was an error calling the function", - } - } - - return { - "message": { - "role": "assistant", - "tool_calls": [ + return stream_generator( { - "function": { - "name": "test_tool", - "arguments": {"param1": "test_value"}, + "message": { + "role": "assistant", + "content": "There was an error calling the function", } } - ], + ) + + return stream_generator( + { + "message": { + "role": "assistant", + "tool_calls": [ + { + "function": { + "name": "test_tool", + "arguments": {"param1": "test_value"}, + } + } + ], + } } - } + ) with patch( "ollama.AsyncClient.chat", @@ -325,7 +393,11 @@ async def test_unknown_hass_api( await hass.async_block_till_done() result = await conversation.async_converse( - hass, "hello", None, Context(), agent_id=mock_config_entry.entry_id + hass, + "hello", + "1234", + Context(), + agent_id=mock_config_entry.entry_id, ) assert result == snapshot @@ -340,7 +412,9 @@ async def test_message_history_trimming( def response(*args, **kwargs) -> dict: nonlocal response_idx response_idx += 1 - return {"message": {"role": "assistant", "content": f"response {response_idx}"}} + return stream_generator( + {"message": {"role": "assistant", "content": f"response {response_idx}"}} + ) with patch( "ollama.AsyncClient.chat", @@ -428,70 +502,19 @@ async def test_message_history_trimming( assert args[4].kwargs["messages"][5]["content"] == "message 5" -async def test_message_history_pruning( - hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_init_component -) -> None: - """Test that old message histories are pruned.""" - with patch( - "ollama.AsyncClient.chat", - return_value={"message": {"role": "assistant", "content": "test response"}}, - ): - # Create 3 different message histories - conversation_ids: list[str] = [] - for i in range(3): - result = await conversation.async_converse( - hass, - f"message {i + 1}", - conversation_id=None, - context=Context(), - agent_id=mock_config_entry.entry_id, - ) - assert ( - result.response.response_type == intent.IntentResponseType.ACTION_DONE - ), result - assert isinstance(result.conversation_id, str) - conversation_ids.append(result.conversation_id) - - agent = conversation.get_agent_manager(hass).async_get_agent( - mock_config_entry.entry_id - ) - assert len(agent._history) == 3 - assert agent._history.keys() == set(conversation_ids) - - # Modify the timestamps of the first 2 histories so they will be pruned - # on the next cycle. - for conversation_id in conversation_ids[:2]: - # Move back 2 hours - agent._history[conversation_id].timestamp -= 2 * 60 * 60 - - # Next cycle - result = await conversation.async_converse( - hass, - "test message", - conversation_id=None, - context=Context(), - agent_id=mock_config_entry.entry_id, - ) - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE, ( - result - ) - - # Only the most recent histories should remain - assert len(agent._history) == 2 - assert conversation_ids[-1] in agent._history - assert result.conversation_id in agent._history - - async def test_message_history_unlimited( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_init_component ) -> None: """Test that message history is not trimmed when max_history = 0.""" conversation_id = "1234" + + def stream(*args, **kwargs) -> AsyncGenerator[dict]: + return stream_generator( + {"message": {"role": "assistant", "content": "test response"}} + ) + with ( - patch( - "ollama.AsyncClient.chat", - return_value={"message": {"role": "assistant", "content": "test response"}}, - ), + patch("ollama.AsyncClient.chat", side_effect=stream) as mock_chat, ): hass.config_entries.async_update_entry( mock_config_entry, options={ollama.CONF_MAX_HISTORY: 0} @@ -508,13 +531,13 @@ async def test_message_history_unlimited( result.response.response_type == intent.IntentResponseType.ACTION_DONE ), result - agent = conversation.get_agent_manager(hass).async_get_agent( - mock_config_entry.entry_id + args = mock_chat.call_args_list + assert len(args) == 100 + recorded_messages = args[-1].kwargs["messages"] + message_count = sum( + (message["role"] == "user") for message in recorded_messages ) - - assert len(agent._history) == 1 - assert conversation_id in agent._history - assert agent._history[conversation_id].num_user_messages == 100 + assert message_count == 100 async def test_error_handling( @@ -608,7 +631,9 @@ async def test_options( """Test that options are passed correctly to ollama client.""" with patch( "ollama.AsyncClient.chat", - return_value={"message": {"role": "assistant", "content": "test response"}}, + return_value=stream_generator( + {"message": {"role": "assistant", "content": "test response"}} + ), ) as mock_chat: await conversation.async_converse( hass, diff --git a/tests/components/omnilogic/snapshots/test_sensor.ambr b/tests/components/omnilogic/snapshots/test_sensor.ambr index a4ea7f02a03..b6eb07dbe26 100644 --- a/tests/components/omnilogic/snapshots/test_sensor.ambr +++ b/tests/components/omnilogic/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/omnilogic/snapshots/test_switch.ambr b/tests/components/omnilogic/snapshots/test_switch.ambr index a5d77f1adcf..cc1a2e226fc 100644 --- a/tests/components/omnilogic/snapshots/test_switch.ambr +++ b/tests/components/omnilogic/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/onboarding/test_views.py b/tests/components/onboarding/test_views.py index 98f6426609e..99623cb6efe 100644 --- a/tests/components/onboarding/test_views.py +++ b/tests/components/onboarding/test_views.py @@ -14,6 +14,7 @@ from syrupy import SnapshotAssertion from homeassistant.components import backup, onboarding from homeassistant.components.onboarding import const, views from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import area_registry as ar from homeassistant.setup import async_setup_component @@ -777,7 +778,7 @@ async def test_onboarding_backup_view_without_backup( resp = await client.request(method, f"/api/onboarding/{view}", **kwargs) assert resp.status == 500 - assert await resp.json() == {"error": "backup_disabled"} + assert await resp.json() == {"code": "backup_disabled"} async def test_onboarding_backup_info( @@ -920,14 +921,16 @@ async def test_onboarding_backup_restore( @pytest.mark.parametrize( - ("params", "restore_error", "expected_status", "expected_message", "restore_calls"), + ("params", "restore_error", "expected_status", "expected_json", "restore_calls"), [ # Missing agent_id ( {"backup_id": "abc123"}, None, 400, - "Message format incorrect: required key not provided @ data['agent_id']", + { + "message": "Message format incorrect: required key not provided @ data['agent_id']" + }, 0, ), # Missing backup_id @@ -935,7 +938,9 @@ async def test_onboarding_backup_restore( {"agent_id": "backup.local"}, None, 400, - "Message format incorrect: required key not provided @ data['backup_id']", + { + "message": "Message format incorrect: required key not provided @ data['backup_id']" + }, 0, ), # Invalid restore_database @@ -947,7 +952,9 @@ async def test_onboarding_backup_restore( }, None, 400, - "Message format incorrect: expected bool for dictionary value @ data['restore_database']", + { + "message": "Message format incorrect: expected bool for dictionary value @ data['restore_database']" + }, 0, ), # Invalid folder @@ -959,7 +966,9 @@ async def test_onboarding_backup_restore( }, None, 400, - "Message format incorrect: expected Folder or one of 'share', 'addons/local', 'ssl', 'media' @ data['restore_folders'][0]", + { + "message": "Message format incorrect: expected Folder or one of 'share', 'addons/local', 'ssl', 'media' @ data['restore_folders'][0]" + }, 0, ), # Wrong password @@ -967,12 +976,63 @@ async def test_onboarding_backup_restore( {"backup_id": "abc123", "agent_id": "backup.local"}, backup.IncorrectPasswordError, 400, - "incorrect_password", + {"code": "incorrect_password"}, + 1, + ), + # Home Assistant error + ( + {"backup_id": "abc123", "agent_id": "backup.local"}, + HomeAssistantError("Boom!"), + 400, + {"code": "restore_failed", "message": "Boom!"}, 1, ), ], ) async def test_onboarding_backup_restore_error( + hass: HomeAssistant, + hass_storage: dict[str, Any], + hass_client: ClientSessionGenerator, + params: dict[str, Any], + restore_error: Exception | None, + expected_status: int, + expected_json: str, + restore_calls: int, +) -> None: + """Test returning installation type during onboarding.""" + mock_storage(hass_storage, {"done": []}) + + assert await async_setup_component(hass, "onboarding", {}) + assert await async_setup_component(hass, "backup", {}) + await hass.async_block_till_done() + + client = await hass_client() + + with patch( + "homeassistant.components.backup.manager.BackupManager.async_restore_backup", + side_effect=restore_error, + ) as mock_restore: + resp = await client.post("/api/onboarding/backup/restore", json=params) + + assert resp.status == expected_status + assert await resp.json() == expected_json + assert len(mock_restore.mock_calls) == restore_calls + + +@pytest.mark.parametrize( + ("params", "restore_error", "expected_status", "expected_message", "restore_calls"), + [ + # Unexpected error + ( + {"backup_id": "abc123", "agent_id": "backup.local"}, + Exception("Boom!"), + 500, + "500 Internal Server Error", + 1, + ), + ], +) +async def test_onboarding_backup_restore_unexpected_error( hass: HomeAssistant, hass_storage: dict[str, Any], hass_client: ClientSessionGenerator, @@ -998,7 +1058,7 @@ async def test_onboarding_backup_restore_error( resp = await client.post("/api/onboarding/backup/restore", json=params) assert resp.status == expected_status - assert await resp.json() == {"message": expected_message} + assert (await resp.content.read()).decode().startswith(expected_message) assert len(mock_restore.mock_calls) == restore_calls diff --git a/tests/components/ondilo_ico/fixtures/pool2.json b/tests/components/ondilo_ico/fixtures/pool2.json index da0cb62d484..24e72b469f0 100644 --- a/tests/components/ondilo_ico/fixtures/pool2.json +++ b/tests/components/ondilo_ico/fixtures/pool2.json @@ -15,5 +15,5 @@ "latitude": 48.861783, "longitude": 2.337421 }, - "updated_at": "2024-01-01T01:00:00+0000" + "updated_at": "2024-01-01T01:05:00+0000" } diff --git a/tests/components/ondilo_ico/snapshots/test_init.ambr b/tests/components/ondilo_ico/snapshots/test_init.ambr index 44008ac907e..07e56a78fae 100644 --- a/tests/components/ondilo_ico/snapshots/test_init.ambr +++ b/tests/components/ondilo_ico/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/ondilo_ico/snapshots/test_sensor.ambr b/tests/components/ondilo_ico/snapshots/test_sensor.ambr index 56e30cd904a..84a2d3da4cb 100644 --- a/tests/components/ondilo_ico/snapshots/test_sensor.ambr +++ b/tests/components/ondilo_ico/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -259,6 +264,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -309,6 +315,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -360,6 +367,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -411,6 +419,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -461,6 +470,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -511,6 +521,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -561,6 +572,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -611,6 +623,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -661,6 +674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ondilo_ico/test_init.py b/tests/components/ondilo_ico/test_init.py index 67f68f27b3e..58b1e27987d 100644 --- a/tests/components/ondilo_ico/test_init.py +++ b/tests/components/ondilo_ico/test_init.py @@ -1,8 +1,10 @@ """Test Ondilo ICO initialization.""" +from datetime import datetime, timedelta from typing import Any from unittest.mock import MagicMock +from freezegun.api import FrozenDateTimeFactory from ondilo import OndiloError import pytest from syrupy import SnapshotAssertion @@ -13,7 +15,7 @@ from homeassistant.helpers import device_registry as dr from . import setup_integration -from tests.common import MockConfigEntry +from tests.common import MockConfigEntry, async_fire_time_changed async def test_devices( @@ -63,6 +65,7 @@ async def test_get_pools_error( async def test_init_with_no_ico_attached( hass: HomeAssistant, mock_ondilo_client: MagicMock, + device_registry: dr.DeviceRegistry, config_entry: MockConfigEntry, pool1: dict[str, Any], ) -> None: @@ -73,14 +76,104 @@ async def test_init_with_no_ico_attached( mock_ondilo_client.get_ICO_details.return_value = None await setup_integration(hass, config_entry, mock_ondilo_client) + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + # No devices should be created + assert len(device_entries) == 0 # No sensor should be created assert len(hass.states.async_all()) == 0 # We should not have tried to retrieve pool measures mock_ondilo_client.get_last_pool_measures.assert_not_called() - assert config_entry.state is ConfigEntryState.SETUP_RETRY + assert config_entry.state is ConfigEntryState.LOADED -@pytest.mark.parametrize("api", ["get_ICO_details", "get_last_pool_measures"]) +async def test_adding_pool_after_setup( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_ondilo_client: MagicMock, + device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, + pool1: dict[str, Any], + two_pools: list[dict[str, Any]], + ico_details1: dict[str, Any], + ico_details2: dict[str, Any], +) -> None: + """Test adding one pool after integration setup.""" + mock_ondilo_client.get_pools.return_value = pool1 + mock_ondilo_client.get_ICO_details.return_value = ico_details1 + + await setup_integration(hass, config_entry, mock_ondilo_client) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + # One pool is created with 7 entities. + assert len(device_entries) == 1 + assert len(hass.states.async_all()) == 7 + + mock_ondilo_client.get_pools.return_value = two_pools + mock_ondilo_client.get_ICO_details.return_value = ico_details2 + + # Trigger a refresh of the pools coordinator. + freezer.tick(timedelta(minutes=20)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + # Two pool have been created with 7 entities each. + assert len(device_entries) == 2 + assert len(hass.states.async_all()) == 14 + + +async def test_removing_pool_after_setup( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_ondilo_client: MagicMock, + device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, + pool1: dict[str, Any], + ico_details1: dict[str, Any], +) -> None: + """Test removing one pool after integration setup.""" + await setup_integration(hass, config_entry, mock_ondilo_client) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + # Two pools are created with 7 entities each. + assert len(device_entries) == 2 + assert len(hass.states.async_all()) == 14 + + mock_ondilo_client.get_pools.return_value = pool1 + mock_ondilo_client.get_ICO_details.return_value = ico_details1 + + # Trigger a refresh of the pools coordinator. + freezer.tick(timedelta(minutes=20)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + # One pool is left with 7 entities. + assert len(device_entries) == 1 + assert len(hass.states.async_all()) == 7 + + +@pytest.mark.parametrize( + ("api", "devices", "config_entry_state"), + [ + ("get_ICO_details", 0, ConfigEntryState.SETUP_RETRY), + ("get_last_pool_measures", 1, ConfigEntryState.LOADED), + ], +) async def test_details_error_all_pools( hass: HomeAssistant, mock_ondilo_client: MagicMock, @@ -88,6 +181,8 @@ async def test_details_error_all_pools( config_entry: MockConfigEntry, pool1: dict[str, Any], api: str, + devices: int, + config_entry_state: ConfigEntryState, ) -> None: """Test details and measures error for all pools.""" mock_ondilo_client.get_pools.return_value = pool1 @@ -100,8 +195,8 @@ async def test_details_error_all_pools( device_registry, config_entry.entry_id ) - assert not device_entries - assert config_entry.state is ConfigEntryState.SETUP_RETRY + assert len(device_entries) == devices + assert config_entry.state is config_entry_state async def test_details_error_one_pool( @@ -131,12 +226,15 @@ async def test_details_error_one_pool( async def test_measures_error_one_pool( hass: HomeAssistant, + freezer: FrozenDateTimeFactory, mock_ondilo_client: MagicMock, device_registry: dr.DeviceRegistry, config_entry: MockConfigEntry, last_measures: list[dict[str, Any]], ) -> None: """Test measures error for one pool and success for the other.""" + entity_id_1 = "sensor.pool_1_temperature" + entity_id_2 = "sensor.pool_2_temperature" mock_ondilo_client.get_last_pool_measures.side_effect = [ OndiloError( 404, @@ -151,4 +249,170 @@ async def test_measures_error_one_pool( device_registry, config_entry.entry_id ) - assert len(device_entries) == 1 + assert len(device_entries) == 2 + # One pool returned an error, the other is ok. + # 7 entities are created for the second pool. + assert len(hass.states.async_all()) == 7 + assert hass.states.get(entity_id_1) is None + assert hass.states.get(entity_id_2) is not None + + # All pools now return measures. + mock_ondilo_client.get_last_pool_measures.side_effect = None + + # Move time to next pools coordinator refresh. + freezer.tick(timedelta(minutes=20)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + assert len(device_entries) == 2 + # 14 entities in total, 7 entities per pool. + assert len(hass.states.async_all()) == 14 + assert hass.states.get(entity_id_1) is not None + assert hass.states.get(entity_id_2) is not None + + +async def test_measures_scheduling( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_ondilo_client: MagicMock, + device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, +) -> None: + """Test refresh scheduling of measures coordinator.""" + # Move time to 10 min after pool 1 was updated and 5 min after pool 2 was updated. + freezer.move_to("2024-01-01T01:10:00+00:00") + entity_id_1 = "sensor.pool_1_temperature" + entity_id_2 = "sensor.pool_2_temperature" + await setup_integration(hass, config_entry, mock_ondilo_client) + + device_entries = dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id + ) + + # Two pools are created with 7 entities each. + assert len(device_entries) == 2 + assert len(hass.states.async_all()) == 14 + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T01:10:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T01:10:00+00:00") + + # Tick time by 20 min. + # The measures coordinators for both pools should not have been refreshed again. + freezer.tick(timedelta(minutes=20)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T01:10:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T01:10:00+00:00") + + # Move time to 65 min after pool 1 was last updated. + # This is 5 min after we expect pool 1 to be updated again. + # The measures coordinator for pool 1 should refresh at this time. + # The measures coordinator for pool 2 should not have been refreshed again. + # The pools coordinator has updated the last update time + # of the pools to a stale time that is already passed. + freezer.move_to("2024-01-01T02:05:00+00:00") + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T02:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T01:10:00+00:00") + + # Tick time by 5 min. + # The measures coordinator for pool 1 should not have been refreshed again. + # The measures coordinator for pool 2 should refresh at this time. + # The pools coordinator has updated the last update time + # of the pools to a stale time that is already passed. + freezer.tick(timedelta(minutes=5)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T02:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T02:10:00+00:00") + + # Tick time by 55 min. + # The measures coordinator for pool 1 should refresh at this time. + # This is 1 hour after the last refresh of the measures coordinator for pool 1. + freezer.tick(timedelta(minutes=55)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T03:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T02:10:00+00:00") + + # Tick time by 5 min. + # The measures coordinator for pool 2 should refresh at this time. + # This is 1 hour after the last refresh of the measures coordinator for pool 2. + freezer.tick(timedelta(minutes=5)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T03:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T03:10:00+00:00") + + # Set an error on the pools coordinator endpoint. + # This will cause the pools coordinator to not update the next refresh. + # This should cause the measures coordinators to keep the 1 hour cadence. + mock_ondilo_client.get_pools.side_effect = OndiloError( + 502, + ( + " 502 Bad Gateway " + "

502 Bad Gateway

" + ), + ) + + # Tick time by 55 min. + # The measures coordinator for pool 1 should refresh at this time. + # This is 1 hour after the last refresh of the measures coordinator for pool 1. + freezer.tick(timedelta(minutes=55)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T04:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T03:10:00+00:00") + + # Tick time by 5 min. + # The measures coordinator for pool 2 should refresh at this time. + # This is 1 hour after the last refresh of the measures coordinator for pool 2. + freezer.tick(timedelta(minutes=5)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + state = hass.states.get(entity_id_1) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T04:05:00+00:00") + state = hass.states.get(entity_id_2) + assert state is not None + assert state.last_reported == datetime.fromisoformat("2024-01-01T04:10:00+00:00") diff --git a/tests/components/onedrive/const.py b/tests/components/onedrive/const.py index 3739369887d..3ba54dc40d7 100644 --- a/tests/components/onedrive/const.py +++ b/tests/components/onedrive/const.py @@ -5,10 +5,10 @@ from json import dumps from onedrive_personal_sdk.models.items import ( AppRoot, - Contributor, File, Folder, Hashes, + IdentitySet, ItemParentReference, User, ) @@ -31,7 +31,7 @@ BACKUP_METADATA = { "size": 34519040, } -CONTRIBUTOR = Contributor( +IDENTITY_SET = IdentitySet( user=User( display_name="John Doe", id="id", @@ -47,7 +47,7 @@ MOCK_APPROOT = AppRoot( parent_reference=ItemParentReference( drive_id="mock_drive_id", id="id", path="path" ), - created_by=CONTRIBUTOR, + created_by=IDENTITY_SET, ) MOCK_BACKUP_FOLDER = Folder( @@ -58,7 +58,7 @@ MOCK_BACKUP_FOLDER = Folder( parent_reference=ItemParentReference( drive_id="mock_drive_id", id="id", path="path" ), - created_by=CONTRIBUTOR, + created_by=IDENTITY_SET, ) MOCK_BACKUP_FILE = File( @@ -73,7 +73,7 @@ MOCK_BACKUP_FILE = File( ), mime_type="application/x-tar", description="", - created_by=CONTRIBUTOR, + created_by=IDENTITY_SET, ) MOCK_METADATA_FILE = File( @@ -96,5 +96,5 @@ MOCK_METADATA_FILE = File( } ) ), - created_by=CONTRIBUTOR, + created_by=IDENTITY_SET, ) diff --git a/tests/components/onewire/snapshots/test_binary_sensor.ambr b/tests/components/onewire/snapshots/test_binary_sensor.ambr index d94eda5b7c3..10122ba8685 100644 --- a/tests/components/onewire/snapshots/test_binary_sensor.ambr +++ b/tests/components/onewire/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -390,6 +398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -438,6 +447,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -486,6 +496,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +545,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -582,6 +594,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -631,6 +644,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -680,6 +694,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -729,6 +744,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/onewire/snapshots/test_init.ambr b/tests/components/onewire/snapshots/test_init.ambr index 5666dab6383..9b2a0e00a62 100644 --- a/tests/components/onewire/snapshots/test_init.ambr +++ b/tests/components/onewire/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -99,6 +102,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -131,6 +135,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -163,6 +168,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -195,6 +201,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -227,6 +234,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -259,6 +267,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -291,6 +300,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -323,6 +333,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -355,6 +366,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -387,6 +399,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -419,6 +432,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -451,6 +465,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -483,6 +498,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -515,6 +531,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -547,6 +564,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -579,6 +597,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -611,6 +630,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -643,6 +663,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -675,6 +696,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/onewire/snapshots/test_select.ambr b/tests/components/onewire/snapshots/test_select.ambr index 7c4027cd046..a896d946841 100644 --- a/tests/components/onewire/snapshots/test_select.ambr +++ b/tests/components/onewire/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/onewire/snapshots/test_sensor.ambr b/tests/components/onewire/snapshots/test_sensor.ambr index b963e29d160..eca459b4c57 100644 --- a/tests/components/onewire/snapshots/test_sensor.ambr +++ b/tests/components/onewire/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -61,6 +62,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -114,6 +116,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -167,6 +170,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +222,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -269,6 +274,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -322,6 +328,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -375,6 +382,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +436,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -481,6 +490,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +544,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -587,6 +598,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -640,6 +652,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -693,6 +706,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -746,6 +760,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -799,6 +814,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -852,6 +868,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -905,6 +922,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -958,6 +976,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1011,6 +1030,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1064,6 +1084,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1117,6 +1138,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1170,6 +1192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1223,6 +1246,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1276,6 +1300,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1329,6 +1354,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1382,6 +1408,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1435,6 +1462,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1488,6 +1516,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1541,6 +1570,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1594,6 +1624,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1647,6 +1678,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1700,6 +1732,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1753,6 +1786,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1806,6 +1840,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1859,6 +1894,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1912,6 +1948,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1965,6 +2002,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2018,6 +2056,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2071,6 +2110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2124,6 +2164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2177,6 +2218,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2230,6 +2272,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2283,6 +2326,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2336,6 +2380,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2389,6 +2434,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2442,6 +2488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2495,6 +2542,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2548,6 +2596,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2601,6 +2650,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2654,6 +2704,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2707,6 +2758,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2760,6 +2812,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2813,6 +2866,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2866,6 +2920,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2919,6 +2974,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2972,6 +3028,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3025,6 +3082,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/onewire/snapshots/test_switch.ambr b/tests/components/onewire/snapshots/test_switch.ambr index cb752982bec..8be414c7c1e 100644 --- a/tests/components/onewire/snapshots/test_switch.ambr +++ b/tests/components/onewire/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -390,6 +398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -438,6 +447,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -486,6 +496,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +545,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -582,6 +594,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -630,6 +643,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -678,6 +692,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -726,6 +741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -774,6 +790,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -822,6 +839,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -870,6 +888,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -918,6 +937,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -966,6 +986,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1014,6 +1035,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1062,6 +1084,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1110,6 +1133,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1158,6 +1182,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1206,6 +1231,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1254,6 +1280,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1302,6 +1329,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1350,6 +1378,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1398,6 +1427,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1446,6 +1476,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1494,6 +1525,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1542,6 +1574,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1590,6 +1623,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1638,6 +1672,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1686,6 +1721,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1734,6 +1770,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/onvif/snapshots/test_diagnostics.ambr b/tests/components/onvif/snapshots/test_diagnostics.ambr index c8a9ff75d62..c3938efcbb6 100644 --- a/tests/components/onvif/snapshots/test_diagnostics.ambr +++ b/tests/components/onvif/snapshots/test_diagnostics.ambr @@ -24,6 +24,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'aa:bb:cc:dd:ee:ff', 'version': 1, diff --git a/tests/components/openai_conversation/snapshots/test_conversation.ambr b/tests/components/openai_conversation/snapshots/test_conversation.ambr index 4ef8b8655ee..77c28de2773 100644 --- a/tests/components/openai_conversation/snapshots/test_conversation.ambr +++ b/tests/components/openai_conversation/snapshots/test_conversation.ambr @@ -1,34 +1,50 @@ # serializer version: 1 -# name: test_unknown_hass_api - dict({ - 'conversation_id': 'my-conversation-id', - 'response': IntentResponse( - card=dict({ - }), - error_code=, - failed_results=list([ - ]), - intent=None, - intent_targets=list([ - ]), - language='en', - matched_states=list([ - ]), - reprompt=dict({ - }), - response_type=, - speech=dict({ - 'plain': dict({ - 'extra_data': None, - 'speech': 'Error preparing LLM API', +# name: test_function_call + list([ + dict({ + 'content': 'Please call the test function', + 'role': 'user', + }), + dict({ + 'agent_id': 'conversation.openai', + 'content': None, + 'role': 'assistant', + 'tool_calls': list([ + dict({ + 'id': 'call_call_1', + 'tool_args': dict({ + 'param1': 'call1', + }), + 'tool_name': 'test_tool', + }), + dict({ + 'id': 'call_call_2', + 'tool_args': dict({ + 'param1': 'call2', + }), + 'tool_name': 'test_tool', }), - }), - speech_slots=dict({ - }), - success_results=list([ ]), - unmatched_states=list([ - ]), - ), - }) + }), + dict({ + 'agent_id': 'conversation.openai', + 'role': 'tool_result', + 'tool_call_id': 'call_call_1', + 'tool_name': 'test_tool', + 'tool_result': 'value1', + }), + dict({ + 'agent_id': 'conversation.openai', + 'role': 'tool_result', + 'tool_call_id': 'call_call_2', + 'tool_name': 'test_tool', + 'tool_result': 'value2', + }), + dict({ + 'agent_id': 'conversation.openai', + 'content': 'Cool', + 'role': 'assistant', + 'tool_calls': None, + }), + ]) # --- diff --git a/tests/components/openai_conversation/test_conversation.py b/tests/components/openai_conversation/test_conversation.py index 39ca1b53e28..2c956b7e63f 100644 --- a/tests/components/openai_conversation/test_conversation.py +++ b/tests/components/openai_conversation/test_conversation.py @@ -1,28 +1,70 @@ """Tests for the OpenAI integration.""" +from collections.abc import Generator from unittest.mock import AsyncMock, patch -from freezegun import freeze_time from httpx import Response from openai import RateLimitError -from openai.types.chat.chat_completion import ChatCompletion, Choice -from openai.types.chat.chat_completion_message import ChatCompletionMessage -from openai.types.chat.chat_completion_message_tool_call import ( - ChatCompletionMessageToolCall, - Function, +from openai.types.chat.chat_completion_chunk import ( + ChatCompletionChunk, + Choice, + ChoiceDelta, + ChoiceDeltaToolCall, + ChoiceDeltaToolCallFunction, ) -from openai.types.completion_usage import CompletionUsage -import voluptuous as vol +import pytest +from syrupy.assertion import SnapshotAssertion from homeassistant.components import conversation -from homeassistant.components.conversation import trace +from homeassistant.components.homeassistant.exposed_entities import async_expose_entity from homeassistant.const import CONF_LLM_HASS_API from homeassistant.core import Context, HomeAssistant -from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import intent, llm +from homeassistant.helpers import intent from homeassistant.setup import async_setup_component from tests.common import MockConfigEntry +from tests.components.conversation import ( + MockChatLog, + mock_chat_log, # noqa: F401 +) + +ASSIST_RESPONSE_FINISH = ( + # Assistant message + ChatCompletionChunk( + id="chatcmpl-B", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[Choice(index=0, delta=ChoiceDelta(content="Cool"))], + ), + # Finish stream + ChatCompletionChunk( + id="chatcmpl-B", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[Choice(index=0, finish_reason="stop", delta=ChoiceDelta())], + ), +) + + +@pytest.fixture +def mock_create_stream() -> Generator[AsyncMock]: + """Mock stream response.""" + + async def mock_generator(stream): + for value in stream: + yield value + + with patch( + "openai.resources.chat.completions.AsyncCompletions.create", + AsyncMock(), + ) as mock_create: + mock_create.side_effect = lambda **kwargs: mock_generator( + mock_create.return_value.pop(0) + ) + + yield mock_create async def test_entity( @@ -83,348 +125,299 @@ async def test_conversation_agent( assert agent.supported_languages == "*" -@patch( - "homeassistant.components.openai_conversation.conversation.llm.AssistAPI._async_get_tools" -) async def test_function_call( - mock_get_tools, hass: HomeAssistant, mock_config_entry_with_assist: MockConfigEntry, mock_init_component, + mock_create_stream: AsyncMock, + mock_chat_log: MockChatLog, # noqa: F811 + snapshot: SnapshotAssertion, ) -> None: """Test function call from the assistant.""" - agent_id = mock_config_entry_with_assist.entry_id - context = Context() - - mock_tool = AsyncMock() - mock_tool.name = "test_tool" - mock_tool.description = "Test function" - mock_tool.parameters = vol.Schema( - {vol.Optional("param1", description="Test parameters"): str} - ) - mock_tool.async_call.return_value = "Test response" - - mock_get_tools.return_value = [mock_tool] - - def completion_result(*args, messages, **kwargs): - for message in messages: - role = message["role"] if isinstance(message, dict) else message.role - if role == "tool": - return ChatCompletion( - id="chatcmpl-1234567890ZYXWVUTSRQPONMLKJIH", - choices=[ - Choice( - finish_reason="stop", - index=0, - message=ChatCompletionMessage( - content="I have successfully called the function", - role="assistant", - function_call=None, - tool_calls=None, - ), - ) - ], - created=1700000000, - model="gpt-4-1106-preview", - object="chat.completion", - system_fingerprint=None, - usage=CompletionUsage( - completion_tokens=9, prompt_tokens=8, total_tokens=17 - ), - ) - - return ChatCompletion( - id="chatcmpl-1234567890ABCDEFGHIJKLMNOPQRS", - choices=[ - Choice( - finish_reason="tool_calls", - index=0, - message=ChatCompletionMessage( - content=None, - role="assistant", - function_call=None, - tool_calls=[ - ChatCompletionMessageToolCall( - id="call_AbCdEfGhIjKlMnOpQrStUvWx", - function=Function( - arguments='{"param1":"test_value"}', - name="test_tool", - ), - type="function", - ) - ], - ), - ) - ], - created=1700000000, - model="gpt-4-1106-preview", - object="chat.completion", - system_fingerprint=None, - usage=CompletionUsage( - completion_tokens=9, prompt_tokens=8, total_tokens=17 + mock_create_stream.return_value = [ + # Initial conversation + ( + # First tool call + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + id="call_call_1", + index=0, + function=ChoiceDeltaToolCallFunction( + name="test_tool", + arguments=None, + ), + ) + ] + ), + ) + ], ), - ) + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction( + name=None, + arguments='{"para', + ), + ) + ] + ), + ) + ], + ), + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction( + name=None, + arguments='m1":"call1"}', + ), + ) + ] + ), + ) + ], + ), + # Second tool call + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + id="call_call_2", + index=1, + function=ChoiceDeltaToolCallFunction( + name="test_tool", + arguments='{"param1":"call2"}', + ), + ) + ] + ), + ) + ], + ), + # Finish stream + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice(index=0, finish_reason="tool_calls", delta=ChoiceDelta()) + ], + ), + ), + # Response after tool responses + ASSIST_RESPONSE_FINISH, + ] + mock_chat_log.mock_tool_results( + { + "call_call_1": "value1", + "call_call_2": "value2", + } + ) - with ( - patch( - "openai.resources.chat.completions.AsyncCompletions.create", - new_callable=AsyncMock, - side_effect=completion_result, - ) as mock_create, - freeze_time("2024-06-03 23:00:00"), - ): - result = await conversation.async_converse( - hass, - "Please call the test function", - None, - context, - agent_id=agent_id, - ) - - assert ( - "Today's date is 2024-06-03." - in mock_create.mock_calls[1][2]["messages"][0]["content"] + result = await conversation.async_converse( + hass, + "Please call the test function", + mock_chat_log.conversation_id, + Context(), + agent_id="conversation.openai", ) assert result.response.response_type == intent.IntentResponseType.ACTION_DONE - assert mock_create.mock_calls[1][2]["messages"][3] == { - "role": "tool", - "tool_call_id": "call_AbCdEfGhIjKlMnOpQrStUvWx", - "content": '"Test response"', - } - mock_tool.async_call.assert_awaited_once_with( - hass, - llm.ToolInput( - id="call_AbCdEfGhIjKlMnOpQrStUvWx", - tool_name="test_tool", - tool_args={"param1": "test_value"}, + # Don't test the prompt, as it's not deterministic + assert mock_chat_log.content[1:] == snapshot + + +@pytest.mark.parametrize( + ("description", "messages"), + [ + ( + "Test function call started with missing arguments", + ( + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + id="call_call_1", + index=0, + function=ChoiceDeltaToolCallFunction( + name="test_tool", + arguments=None, + ), + ) + ] + ), + ) + ], + ), + ChatCompletionChunk( + id="chatcmpl-B", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[Choice(index=0, delta=ChoiceDelta(content="Cool"))], + ), + ), ), - llm.LLMContext( - platform="openai_conversation", - context=context, - user_prompt="Please call the test function", - language="en", - assistant="conversation", - device_id=None, + ( + "Test invalid JSON", + ( + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + id="call_call_1", + index=0, + function=ChoiceDeltaToolCallFunction( + name="test_tool", + arguments=None, + ), + ) + ] + ), + ) + ], + ), + ChatCompletionChunk( + id="chatcmpl-A", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta( + tool_calls=[ + ChoiceDeltaToolCall( + index=0, + function=ChoiceDeltaToolCallFunction( + name=None, + arguments='{"para', + ), + ) + ] + ), + ) + ], + ), + ChatCompletionChunk( + id="chatcmpl-B", + created=1700000000, + model="gpt-4-1106-preview", + object="chat.completion.chunk", + choices=[ + Choice( + index=0, + delta=ChoiceDelta(content="Cool"), + finish_reason="tool_calls", + ) + ], + ), + ), ), - ) - - # Test Conversation tracing - traces = trace.async_get_traces() - assert traces - last_trace = traces[-1].as_dict() - trace_events = last_trace.get("events", []) - assert [event["event_type"] for event in trace_events] == [ - trace.ConversationTraceEventType.ASYNC_PROCESS, - trace.ConversationTraceEventType.AGENT_DETAIL, - trace.ConversationTraceEventType.TOOL_CALL, - ] - # AGENT_DETAIL event contains the raw prompt passed to the model - detail_event = trace_events[1] - assert "Answer in plain text" in detail_event["data"]["messages"][0]["content"] - assert ( - "Today's date is 2024-06-03." - in trace_events[1]["data"]["messages"][0]["content"] - ) - assert [t.name for t in detail_event["data"]["tools"]] == ["test_tool"] - - # Call it again, make sure we have updated prompt - with ( - patch( - "openai.resources.chat.completions.AsyncCompletions.create", - new_callable=AsyncMock, - side_effect=completion_result, - ) as mock_create, - freeze_time("2024-06-04 23:00:00"), - ): - result = await conversation.async_converse( - hass, - "Please call the test function", - None, - context, - agent_id=agent_id, - ) - - assert ( - "Today's date is 2024-06-04." - in mock_create.mock_calls[1][2]["messages"][0]["content"] - ) - # Test old assert message not updated - assert ( - "Today's date is 2024-06-03." - in trace_events[1]["data"]["messages"][0]["content"] - ) - - -@patch( - "homeassistant.components.openai_conversation.conversation.llm.AssistAPI._async_get_tools" + ], ) -async def test_function_exception( - mock_get_tools, +async def test_function_call_invalid( hass: HomeAssistant, mock_config_entry_with_assist: MockConfigEntry, mock_init_component, + mock_create_stream: AsyncMock, + mock_chat_log: MockChatLog, # noqa: F811 + description: str, + messages: tuple[ChatCompletionChunk], ) -> None: - """Test function call with exception.""" - agent_id = mock_config_entry_with_assist.entry_id - context = Context() + """Test function call containing invalid data.""" + mock_create_stream.return_value = [messages] - mock_tool = AsyncMock() - mock_tool.name = "test_tool" - mock_tool.description = "Test function" - mock_tool.parameters = vol.Schema( - {vol.Optional("param1", description="Test parameters"): str} - ) - mock_tool.async_call.side_effect = HomeAssistantError("Test tool exception") - - mock_get_tools.return_value = [mock_tool] - - def completion_result(*args, messages, **kwargs): - for message in messages: - role = message["role"] if isinstance(message, dict) else message.role - if role == "tool": - return ChatCompletion( - id="chatcmpl-1234567890ZYXWVUTSRQPONMLKJIH", - choices=[ - Choice( - finish_reason="stop", - index=0, - message=ChatCompletionMessage( - content="There was an error calling the function", - role="assistant", - function_call=None, - tool_calls=None, - ), - ) - ], - created=1700000000, - model="gpt-4-1106-preview", - object="chat.completion", - system_fingerprint=None, - usage=CompletionUsage( - completion_tokens=9, prompt_tokens=8, total_tokens=17 - ), - ) - - return ChatCompletion( - id="chatcmpl-1234567890ABCDEFGHIJKLMNOPQRS", - choices=[ - Choice( - finish_reason="tool_calls", - index=0, - message=ChatCompletionMessage( - content=None, - role="assistant", - function_call=None, - tool_calls=[ - ChatCompletionMessageToolCall( - id="call_AbCdEfGhIjKlMnOpQrStUvWx", - function=Function( - arguments='{"param1":"test_value"}', - name="test_tool", - ), - type="function", - ) - ], - ), - ) - ], - created=1700000000, - model="gpt-4-1106-preview", - object="chat.completion", - system_fingerprint=None, - usage=CompletionUsage( - completion_tokens=9, prompt_tokens=8, total_tokens=17 - ), - ) - - with patch( - "openai.resources.chat.completions.AsyncCompletions.create", - new_callable=AsyncMock, - side_effect=completion_result, - ) as mock_create: - result = await conversation.async_converse( + with pytest.raises(ValueError): + await conversation.async_converse( hass, "Please call the test function", - None, - context, - agent_id=agent_id, + "mock-conversation-id", + Context(), + agent_id="conversation.openai", ) - assert result.response.response_type == intent.IntentResponseType.ACTION_DONE - assert mock_create.mock_calls[1][2]["messages"][3] == { - "role": "tool", - "tool_call_id": "call_AbCdEfGhIjKlMnOpQrStUvWx", - "content": '{"error": "HomeAssistantError", "error_text": "Test tool exception"}', - } - mock_tool.async_call.assert_awaited_once_with( - hass, - llm.ToolInput( - id="call_AbCdEfGhIjKlMnOpQrStUvWx", - tool_name="test_tool", - tool_args={"param1": "test_value"}, - ), - llm.LLMContext( - platform="openai_conversation", - context=context, - user_prompt="Please call the test function", - language="en", - assistant="conversation", - device_id=None, - ), - ) - async def test_assist_api_tools_conversion( hass: HomeAssistant, mock_config_entry_with_assist: MockConfigEntry, mock_init_component, + mock_create_stream, ) -> None: """Test that we are able to convert actual tools from Assist API.""" for component in ( - "intent", - "todo", - "light", - "shopping_list", - "humidifier", + "calendar", "climate", - "media_player", - "vacuum", "cover", + "humidifier", + "intent", + "light", + "media_player", + "script", + "shopping_list", + "todo", + "vacuum", "weather", ): assert await async_setup_component(hass, component, {}) + hass.states.async_set(f"{component}.test", "on") + async_expose_entity(hass, "conversation", f"{component}.test", True) - agent_id = mock_config_entry_with_assist.entry_id - with patch( - "openai.resources.chat.completions.AsyncCompletions.create", - new_callable=AsyncMock, - return_value=ChatCompletion( - id="chatcmpl-1234567890ABCDEFGHIJKLMNOPQRS", - choices=[ - Choice( - finish_reason="stop", - index=0, - message=ChatCompletionMessage( - content="Hello, how can I help you?", - role="assistant", - function_call=None, - tool_calls=None, - ), - ) - ], - created=1700000000, - model="gpt-3.5-turbo-0613", - object="chat.completion", - system_fingerprint=None, - usage=CompletionUsage( - completion_tokens=9, prompt_tokens=8, total_tokens=17 - ), - ), - ) as mock_create: - await conversation.async_converse( - hass, "hello", None, Context(), agent_id=agent_id - ) + mock_create_stream.return_value = [ASSIST_RESPONSE_FINISH] - tools = mock_create.mock_calls[0][2]["tools"] + await conversation.async_converse( + hass, "hello", None, Context(), agent_id="conversation.openai" + ) + + tools = mock_create_stream.mock_calls[0][2]["tools"] assert tools diff --git a/tests/components/openuv/test_diagnostics.py b/tests/components/openuv/test_diagnostics.py index 61b68b5ad90..03b392b3e7b 100644 --- a/tests/components/openuv/test_diagnostics.py +++ b/tests/components/openuv/test_diagnostics.py @@ -39,6 +39,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "data": { "protection_window": { diff --git a/tests/components/osoenergy/snapshots/test_water_heater.ambr b/tests/components/osoenergy/snapshots/test_water_heater.ambr index 5ebac405144..92b3a7aa099 100644 --- a/tests/components/osoenergy/snapshots/test_water_heater.ambr +++ b/tests/components/osoenergy/snapshots/test_water_heater.ambr @@ -9,6 +9,7 @@ 'min_temp': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/overseerr/snapshots/test_event.ambr b/tests/components/overseerr/snapshots/test_event.ambr index 1002bc4cdad..8a7be6c463d 100644 --- a/tests/components/overseerr/snapshots/test_event.ambr +++ b/tests/components/overseerr/snapshots/test_event.ambr @@ -15,6 +15,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/overseerr/snapshots/test_init.ambr b/tests/components/overseerr/snapshots/test_init.ambr index 21b4b215ac5..2709f532ef6 100644 --- a/tests/components/overseerr/snapshots/test_init.ambr +++ b/tests/components/overseerr/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://overseerr.test', 'connections': set({ }), diff --git a/tests/components/overseerr/snapshots/test_sensor.ambr b/tests/components/overseerr/snapshots/test_sensor.ambr index 53a9b3dd82a..bbee260b782 100644 --- a/tests/components/overseerr/snapshots/test_sensor.ambr +++ b/tests/components/overseerr/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -258,6 +263,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -308,6 +314,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/p1_monitor/snapshots/test_init.ambr b/tests/components/p1_monitor/snapshots/test_init.ambr index d0a676fce1b..83684e153c9 100644 --- a/tests/components/p1_monitor/snapshots/test_init.ambr +++ b/tests/components/p1_monitor/snapshots/test_init.ambr @@ -16,6 +16,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'unique_thingy', 'version': 2, @@ -38,6 +40,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'unique_thingy', 'version': 2, diff --git a/tests/components/palazzetti/snapshots/test_button.ambr b/tests/components/palazzetti/snapshots/test_button.ambr index 6827c9a1f22..8130f0a0ec7 100644 --- a/tests/components/palazzetti/snapshots/test_button.ambr +++ b/tests/components/palazzetti/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/palazzetti/snapshots/test_climate.ambr b/tests/components/palazzetti/snapshots/test_climate.ambr index aa637039df9..cf23cb87ccb 100644 --- a/tests/components/palazzetti/snapshots/test_climate.ambr +++ b/tests/components/palazzetti/snapshots/test_climate.ambr @@ -23,6 +23,7 @@ 'target_temp_step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/palazzetti/snapshots/test_init.ambr b/tests/components/palazzetti/snapshots/test_init.ambr index abdee6b7f6f..fc96cab4fad 100644 --- a/tests/components/palazzetti/snapshots/test_init.ambr +++ b/tests/components/palazzetti/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/palazzetti/snapshots/test_number.ambr b/tests/components/palazzetti/snapshots/test_number.ambr index 7ace1149e0a..1d40e9e4b6b 100644 --- a/tests/components/palazzetti/snapshots/test_number.ambr +++ b/tests/components/palazzetti/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -123,6 +125,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/palazzetti/snapshots/test_sensor.ambr b/tests/components/palazzetti/snapshots/test_sensor.ambr index aa98f3a4f59..6bf4f68c1fa 100644 --- a/tests/components/palazzetti/snapshots/test_sensor.ambr +++ b/tests/components/palazzetti/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +368,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -460,6 +467,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -511,6 +519,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_binary_sensor.ambr b/tests/components/peblar/snapshots/test_binary_sensor.ambr index 72c3ac78a12..9ad9c877ed2 100644 --- a/tests/components/peblar/snapshots/test_binary_sensor.ambr +++ b/tests/components/peblar/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_button.ambr b/tests/components/peblar/snapshots/test_button.ambr index 96aab5c93ef..6d31da0ae52 100644 --- a/tests/components/peblar/snapshots/test_button.ambr +++ b/tests/components/peblar/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_init.ambr b/tests/components/peblar/snapshots/test_init.ambr index ba79093b3ec..8a7cefc523d 100644 --- a/tests/components/peblar/snapshots/test_init.ambr +++ b/tests/components/peblar/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.127', 'connections': set({ tuple( diff --git a/tests/components/peblar/snapshots/test_number.ambr b/tests/components/peblar/snapshots/test_number.ambr index d78067849f3..d8e9c756c50 100644 --- a/tests/components/peblar/snapshots/test_number.ambr +++ b/tests/components/peblar/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_select.ambr b/tests/components/peblar/snapshots/test_select.ambr index 62e09325601..3a600653a84 100644 --- a/tests/components/peblar/snapshots/test_select.ambr +++ b/tests/components/peblar/snapshots/test_select.ambr @@ -14,6 +14,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_sensor.ambr b/tests/components/peblar/snapshots/test_sensor.ambr index bb1a3eb34d6..5a1d1663ba2 100644 --- a/tests/components/peblar/snapshots/test_sensor.ambr +++ b/tests/components/peblar/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +240,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -311,6 +316,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -379,6 +385,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -430,6 +437,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -481,6 +489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -532,6 +541,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -583,6 +593,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -648,6 +659,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -704,6 +716,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -753,6 +766,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -804,6 +818,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -855,6 +870,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_switch.ambr b/tests/components/peblar/snapshots/test_switch.ambr index 426b48b6838..46051974339 100644 --- a/tests/components/peblar/snapshots/test_switch.ambr +++ b/tests/components/peblar/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/peblar/snapshots/test_update.ambr b/tests/components/peblar/snapshots/test_update.ambr index de8bb63150d..0a6b2bf069f 100644 --- a/tests/components/peblar/snapshots/test_update.ambr +++ b/tests/components/peblar/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/pegel_online/snapshots/test_diagnostics.ambr b/tests/components/pegel_online/snapshots/test_diagnostics.ambr index 1e55805f867..d0fdc81acb4 100644 --- a/tests/components/pegel_online/snapshots/test_diagnostics.ambr +++ b/tests/components/pegel_online/snapshots/test_diagnostics.ambr @@ -31,6 +31,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '70272185-xxxx-xxxx-xxxx-43bea330dcae', 'version': 1, diff --git a/tests/components/pglab/__init__.py b/tests/components/pglab/__init__.py new file mode 100644 index 00000000000..0ee9b203524 --- /dev/null +++ b/tests/components/pglab/__init__.py @@ -0,0 +1 @@ +"""Tests for the PG LAB Electronics integration.""" diff --git a/tests/components/pglab/conftest.py b/tests/components/pglab/conftest.py new file mode 100644 index 00000000000..b148cb08a15 --- /dev/null +++ b/tests/components/pglab/conftest.py @@ -0,0 +1,41 @@ +"""Common fixtures for the PG LAB Electronics tests.""" + +import pytest + +from homeassistant.components.pglab.const import DISCOVERY_TOPIC, DOMAIN +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry, mock_device_registry, mock_registry + +CONF_DISCOVERY_PREFIX = "discovery_prefix" + + +@pytest.fixture +def device_reg(hass: HomeAssistant): + """Return an empty, loaded, registry.""" + return mock_device_registry(hass) + + +@pytest.fixture +def entity_reg(hass: HomeAssistant): + """Return an empty, loaded, registry.""" + return mock_registry(hass) + + +@pytest.fixture +async def setup_pglab(hass: HomeAssistant): + """Set up PG LAB Electronics.""" + hass.config.components.add("pglab") + + entry = MockConfigEntry( + data={CONF_DISCOVERY_PREFIX: DISCOVERY_TOPIC}, + domain=DOMAIN, + title="PG LAB Electronics", + ) + + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert "pglab" in hass.config.components diff --git a/tests/components/pglab/test_config_flow.py b/tests/components/pglab/test_config_flow.py new file mode 100644 index 00000000000..81ed010920e --- /dev/null +++ b/tests/components/pglab/test_config_flow.py @@ -0,0 +1,133 @@ +"""Test the PG LAB Electronics config flow.""" + +from homeassistant.components.mqtt import MQTT_CONNECTION_STATE +from homeassistant.components.pglab.const import DOMAIN +from homeassistant.config_entries import SOURCE_MQTT, SOURCE_USER +from homeassistant.core import HomeAssistant +from homeassistant.data_entry_flow import FlowResultType +from homeassistant.helpers.dispatcher import async_dispatcher_send +from homeassistant.helpers.service_info.mqtt import MqttServiceInfo + +from tests.common import MockConfigEntry +from tests.typing import MqttMockHAClient + + +async def test_mqtt_config_single_instance( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient +) -> None: + """Test MQTT flow aborts when an entry already exist.""" + + MockConfigEntry(domain=DOMAIN).add_to_hass(hass) + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_MQTT} + ) + + # Be sure that result is abort. Only single instance is allowed. + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "single_instance_allowed" + + +async def test_mqtt_setup(hass: HomeAssistant, mqtt_mock: MqttMockHAClient) -> None: + """Test we can finish a config flow through MQTT with custom prefix.""" + discovery_info = MqttServiceInfo( + topic="pglab/discovery/E-Board-DD53AC85/config", + payload=( + '{"ip":"192.168.1.16", "mac":"80:34:28:1B:18:5A", "name":"e-board-office",' + '"hw":"255.255.255", "fw":"255.255.255", "type":"E-Board", "id":"E-Board-DD53AC85",' + '"manufacturer":"PG LAB Electronics", "params":{"shutters":0, "boards":"10000000" } }' + ), + qos=0, + retain=False, + subscribed_topic="pglab/discovery/#", + timestamp=None, + ) + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_MQTT}, data=discovery_info + ) + assert result["type"] is FlowResultType.FORM + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] == FlowResultType.CREATE_ENTRY + assert result["result"].data == {"discovery_prefix": "pglab/discovery"} + + +async def test_mqtt_abort_invalid_topic( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient +) -> None: + """Check MQTT flow aborts if discovery topic is invalid.""" + discovery_info = MqttServiceInfo( + topic="pglab/discovery/E-Board-DD53AC85/wrong_topic", + payload=( + '{"ip":"192.168.1.16", "mac":"80:34:28:1B:18:5A", "name":"e-board-office",' + '"hw":"255.255.255", "fw":"255.255.255", "type":"E-Board", "id":"E-Board-DD53AC85",' + '"manufacturer":"PG LAB Electronics", "params":{"shutters":0, "boards":"10000000" } }' + ), + qos=0, + retain=False, + subscribed_topic="pglab/discovery/#", + timestamp=None, + ) + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_MQTT}, data=discovery_info + ) + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "invalid_discovery_info" + + discovery_info = MqttServiceInfo( + topic="pglab/discovery/E-Board-DD53AC85/config", + payload="", + qos=0, + retain=False, + subscribed_topic="pglab/discovery/#", + timestamp=None, + ) + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_MQTT}, data=discovery_info + ) + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "invalid_discovery_info" + + +async def test_user_setup(hass: HomeAssistant, mqtt_mock: MqttMockHAClient) -> None: + """Test if the user can finish a config flow.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["result"].data == { + "discovery_prefix": "pglab/discovery", + } + + +async def test_user_setup_mqtt_not_connected( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient +) -> None: + """Test that the user setup is aborted when MQTT is not connected.""" + + mqtt_mock.connected = False + async_dispatcher_send(hass, MQTT_CONNECTION_STATE, False) + await hass.async_block_till_done() + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "mqtt_not_connected" + + +async def test_user_setup_mqtt_not_configured(hass: HomeAssistant) -> None: + """Test that the user setup is aborted when MQTT is not configured.""" + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "mqtt_not_configured" diff --git a/tests/components/pglab/test_discovery.py b/tests/components/pglab/test_discovery.py new file mode 100644 index 00000000000..65716236277 --- /dev/null +++ b/tests/components/pglab/test_discovery.py @@ -0,0 +1,154 @@ +"""The tests for the PG LAB Electronics discovery device.""" + +import json + +from syrupy.assertion import SnapshotAssertion + +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr + +from tests.common import async_fire_mqtt_message +from tests.typing import MqttMockHAClient + + +async def test_device_discover( + hass: HomeAssistant, + mqtt_mock: MqttMockHAClient, + device_reg, + entity_reg, + setup_pglab, +) -> None: + """Test setting up a device.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "11000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Verify device and registry entries are created + device_entry = device_reg.async_get_device( + connections={(dr.CONNECTION_NETWORK_MAC, payload["mac"])} + ) + assert device_entry is not None + assert device_entry.configuration_url == f"http://{payload['ip']}/" + assert device_entry.manufacturer == "PG LAB Electronics" + assert device_entry.model == payload["type"] + assert device_entry.name == payload["name"] + assert device_entry.sw_version == payload["fw"] + + +async def test_device_update( + hass: HomeAssistant, + mqtt_mock: MqttMockHAClient, + device_reg, + entity_reg, + setup_pglab, + snapshot: SnapshotAssertion, +) -> None: + """Test update a device.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "11000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Verify device is created + device_entry = device_reg.async_get_device( + connections={(dr.CONNECTION_NETWORK_MAC, payload["mac"])} + ) + assert device_entry is not None + + # update device + payload["fw"] = "1.0.1" + payload["hw"] = "1.0.8" + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Verify device is created + device_entry = device_reg.async_get_device( + connections={(dr.CONNECTION_NETWORK_MAC, payload["mac"])} + ) + assert device_entry is not None + assert device_entry.sw_version == "1.0.1" + assert device_entry.hw_version == "1.0.8" + + +async def test_device_remove( + hass: HomeAssistant, + mqtt_mock: MqttMockHAClient, + device_reg, + entity_reg, + setup_pglab, +) -> None: + """Test remove a device.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "11000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Verify device is created + device_entry = device_reg.async_get_device( + connections={(dr.CONNECTION_NETWORK_MAC, payload["mac"])} + ) + assert device_entry is not None + + async_fire_mqtt_message( + hass, + topic, + "", + ) + await hass.async_block_till_done() + + # Verify device entry is removed + device_entry = device_reg.async_get_device( + connections={(dr.CONNECTION_NETWORK_MAC, payload["mac"])} + ) + assert device_entry is None diff --git a/tests/components/pglab/test_init.py b/tests/components/pglab/test_init.py new file mode 100644 index 00000000000..a6353054e8c --- /dev/null +++ b/tests/components/pglab/test_init.py @@ -0,0 +1 @@ +"""Test the PG LAB Electronics integration.""" diff --git a/tests/components/pglab/test_switch.py b/tests/components/pglab/test_switch.py new file mode 100644 index 00000000000..fef445f80f3 --- /dev/null +++ b/tests/components/pglab/test_switch.py @@ -0,0 +1,318 @@ +"""The tests for the PG LAB Electronics switch.""" + +from datetime import timedelta +import json + +from homeassistant import config_entries +from homeassistant.components.switch import ( + DOMAIN as SWITCH_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ( + ATTR_ASSUMED_STATE, + ATTR_ENTITY_ID, + STATE_OFF, + STATE_ON, + STATE_UNKNOWN, +) +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er +from homeassistant.util import dt as dt_util + +from tests.common import async_fire_mqtt_message, async_fire_time_changed +from tests.typing import MqttMockHAClient + + +async def call_service(hass: HomeAssistant, entity_id, service, **kwargs): + """Call a service.""" + await hass.services.async_call( + SWITCH_DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id, **kwargs}, + blocking=True, + ) + + +async def test_available_relay( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab +) -> None: + """Check if relay are properly created when two E-Relay boards are connected.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "11000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + for i in range(16): + state = hass.states.get(f"switch.test_relay_{i}") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + +async def test_change_state_via_mqtt( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab +) -> None: + """Test state update via MQTT.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "10000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Simulate response from the device + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + # Turn relay OFF + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "OFF") + await hass.async_block_till_done() + state = hass.states.get("switch.test_relay_0") + assert not state.attributes.get(ATTR_ASSUMED_STATE) + assert state.state == STATE_OFF + + # Turn relay ON + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON") + await hass.async_block_till_done() + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_ON + + # Turn relay OFF + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "OFF") + await hass.async_block_till_done() + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_OFF + + # Turn relay ON + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON") + await hass.async_block_till_done() + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_ON + + +async def test_mqtt_state_by_calling_service( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab +) -> None: + """Calling service to turn ON/OFF relay and check mqtt state.""" + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "10000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Turn relay ON + await call_service(hass, "switch.test_relay_0", SERVICE_TURN_ON) + mqtt_mock.async_publish.assert_called_once_with( + "pglab/test/relay/0/set", "ON", 0, False + ) + mqtt_mock.async_publish.reset_mock() + + # Turn relay OFF + await call_service(hass, "switch.test_relay_0", SERVICE_TURN_OFF) + mqtt_mock.async_publish.assert_called_once_with( + "pglab/test/relay/0/set", "OFF", 0, False + ) + mqtt_mock.async_publish.reset_mock() + + # Turn relay ON + await call_service(hass, "switch.test_relay_3", SERVICE_TURN_ON) + mqtt_mock.async_publish.assert_called_once_with( + "pglab/test/relay/3/set", "ON", 0, False + ) + mqtt_mock.async_publish.reset_mock() + + # Turn relay OFF + await call_service(hass, "switch.test_relay_3", SERVICE_TURN_OFF) + mqtt_mock.async_publish.assert_called_once_with( + "pglab/test/relay/3/set", "OFF", 0, False + ) + mqtt_mock.async_publish.reset_mock() + + +async def test_discovery_update( + hass: HomeAssistant, mqtt_mock: MqttMockHAClient, setup_pglab +) -> None: + """Update discovery message and check if relay are property updated.""" + + # publish the first discovery message + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "first_test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "10000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # test the available relay in the first configuration + for i in range(8): + state = hass.states.get(f"switch.first_test_relay_{i}") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + # prepare a new message ... the same device but renamed + # and with different relay configuration + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "second_test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "11000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # be sure that old relay are been removed + for i in range(8): + assert not hass.states.get(f"switch.first_test_relay_{i}") + + # check new relay + for i in range(16): + state = hass.states.get(f"switch.second_test_relay_{i}") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + +async def test_disable_entity_state_change_via_mqtt( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mqtt_mock: MqttMockHAClient, + setup_pglab, +) -> None: + """Test state update via MQTT of disable entity.""" + + topic = "pglab/discovery/E-Board-DD53AC85/config" + payload = { + "ip": "192.168.1.16", + "mac": "80:34:28:1B:18:5A", + "name": "test", + "hw": "1.0.7", + "fw": "1.0.0", + "type": "E-Board", + "id": "E-Board-DD53AC85", + "manufacturer": "PG LAB Electronics", + "params": {"shutters": 0, "boards": "10000000"}, + } + + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Be sure that the entity relay_0 is available + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_UNKNOWN + assert not state.attributes.get(ATTR_ASSUMED_STATE) + + # Disable entity relay_0 + new_status = entity_registry.async_update_entity( + "switch.test_relay_0", disabled_by=er.RegistryEntryDisabler.USER + ) + + # Be sure that the entity is disabled + assert new_status.disabled is True + + # Try to change the state of the disabled relay_0 + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON") + await hass.async_block_till_done() + + # Enable entity relay_0 + new_status = entity_registry.async_update_entity( + "switch.test_relay_0", disabled_by=None + ) + + # Be sure that the entity is enabled + assert new_status.disabled is False + + async_fire_time_changed( + hass, + dt_util.utcnow() + + timedelta(seconds=config_entries.RELOAD_AFTER_UPDATE_DELAY + 1), + ) + await hass.async_block_till_done() + + # Re-send the discovery message + async_fire_mqtt_message( + hass, + topic, + json.dumps(payload), + ) + await hass.async_block_till_done() + + # Be sure that the state is not changed + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_UNKNOWN + + # Try again to change the state of the disabled relay_0 + async_fire_mqtt_message(hass, "pglab/test/relay/0/state", "ON") + await hass.async_block_till_done() + + # Be sure that the state is been updated + state = hass.states.get("switch.test_relay_0") + assert state.state == STATE_ON diff --git a/tests/components/philips_js/snapshots/test_diagnostics.ambr b/tests/components/philips_js/snapshots/test_diagnostics.ambr index 4f7a6176634..53db95f0534 100644 --- a/tests/components/philips_js/snapshots/test_diagnostics.ambr +++ b/tests/components/philips_js/snapshots/test_diagnostics.ambr @@ -94,6 +94,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/philips_js/test_config_flow.py b/tests/components/philips_js/test_config_flow.py index 80d05961813..4b8048a8ebe 100644 --- a/tests/components/philips_js/test_config_flow.py +++ b/tests/components/philips_js/test_config_flow.py @@ -155,6 +155,7 @@ async def test_pairing(hass: HomeAssistant, mock_tv_pairable, mock_setup_entry) "version": 1, "options": {}, "minor_version": 1, + "subentries": (), } await hass.async_block_till_done() diff --git a/tests/components/pi_hole/snapshots/test_diagnostics.ambr b/tests/components/pi_hole/snapshots/test_diagnostics.ambr index 3094fcef24b..2d6f6687d04 100644 --- a/tests/components/pi_hole/snapshots/test_diagnostics.ambr +++ b/tests/components/pi_hole/snapshots/test_diagnostics.ambr @@ -33,6 +33,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/ping/snapshots/test_binary_sensor.ambr b/tests/components/ping/snapshots/test_binary_sensor.ambr index 0196c2cbbfb..bb28432841f 100644 --- a/tests/components/ping/snapshots/test_binary_sensor.ambr +++ b/tests/components/ping/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ping/snapshots/test_sensor.ambr b/tests/components/ping/snapshots/test_sensor.ambr index d1548f7559c..bb811af6a34 100644 --- a/tests/components/ping/snapshots/test_sensor.ambr +++ b/tests/components/ping/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -114,6 +116,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/plaato/snapshots/test_binary_sensor.ambr b/tests/components/plaato/snapshots/test_binary_sensor.ambr index e8db3bf32d8..76c0a299c5e 100644 --- a/tests/components/plaato/snapshots/test_binary_sensor.ambr +++ b/tests/components/plaato/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/plaato/snapshots/test_sensor.ambr b/tests/components/plaato/snapshots/test_sensor.ambr index 110ffb04ba9..24ba62e28ca 100644 --- a/tests/components/plaato/snapshots/test_sensor.ambr +++ b/tests/components/plaato/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -286,6 +292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -333,6 +340,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -379,6 +387,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -478,6 +488,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -528,6 +539,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/poolsense/snapshots/test_binary_sensor.ambr b/tests/components/poolsense/snapshots/test_binary_sensor.ambr index 8a6d39332d4..b3d99b95308 100644 --- a/tests/components/poolsense/snapshots/test_binary_sensor.ambr +++ b/tests/components/poolsense/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/poolsense/snapshots/test_sensor.ambr b/tests/components/poolsense/snapshots/test_sensor.ambr index 9029f1f24aa..c0066ba9396 100644 --- a/tests/components/poolsense/snapshots/test_sensor.ambr +++ b/tests/components/poolsense/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -151,6 +154,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -199,6 +203,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -247,6 +252,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -295,6 +301,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -389,6 +397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/powerfox/snapshots/test_sensor.ambr b/tests/components/powerfox/snapshots/test_sensor.ambr index a2aa8a9c72c..bae306ccabc 100644 --- a/tests/components/powerfox/snapshots/test_sensor.ambr +++ b/tests/components/powerfox/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -107,6 +109,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -209,6 +213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -260,6 +265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -311,6 +317,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +369,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -413,6 +421,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -464,6 +473,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -515,6 +525,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/proximity/snapshots/test_diagnostics.ambr b/tests/components/proximity/snapshots/test_diagnostics.ambr index 3d9673ffd90..42ec74710f9 100644 --- a/tests/components/proximity/snapshots/test_diagnostics.ambr +++ b/tests/components/proximity/snapshots/test_diagnostics.ambr @@ -102,6 +102,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'home', 'unique_id': 'proximity_home', 'version': 1, diff --git a/tests/components/ps4/test_init.py b/tests/components/ps4/test_init.py index ede6b3b5147..4cde723a28f 100644 --- a/tests/components/ps4/test_init.py +++ b/tests/components/ps4/test_init.py @@ -52,6 +52,7 @@ MOCK_FLOW_RESULT = { "title": "test_ps4", "data": MOCK_DATA, "options": {}, + "subentries": (), } MOCK_ENTRY_ID = "SomeID" diff --git a/tests/components/purpleair/test_diagnostics.py b/tests/components/purpleair/test_diagnostics.py index ae4b28567be..6271a63d652 100644 --- a/tests/components/purpleair/test_diagnostics.py +++ b/tests/components/purpleair/test_diagnostics.py @@ -38,6 +38,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "data": { "fields": [ diff --git a/tests/components/pyload/snapshots/test_button.ambr b/tests/components/pyload/snapshots/test_button.ambr index bf1e1f59c98..57a0358da42 100644 --- a/tests/components/pyload/snapshots/test_button.ambr +++ b/tests/components/pyload/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/pyload/snapshots/test_sensor.ambr b/tests/components/pyload/snapshots/test_sensor.ambr index 69d0387fc8f..25abe62017d 100644 --- a/tests/components/pyload/snapshots/test_sensor.ambr +++ b/tests/components/pyload/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +163,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -216,6 +220,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -266,6 +271,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -316,6 +322,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -364,6 +371,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -418,6 +426,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -474,6 +483,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -524,6 +534,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -574,6 +585,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -622,6 +634,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -676,6 +689,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -732,6 +746,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -782,6 +797,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -832,6 +848,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -880,6 +897,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -934,6 +952,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -990,6 +1009,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/pyload/snapshots/test_switch.ambr b/tests/components/pyload/snapshots/test_switch.ambr index 0fcc45f8586..479013b09e4 100644 --- a/tests/components/pyload/snapshots/test_switch.ambr +++ b/tests/components/pyload/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainforest_raven/snapshots/test_diagnostics.ambr b/tests/components/rainforest_raven/snapshots/test_diagnostics.ambr index e131bf3d952..abf8e380916 100644 --- a/tests/components/rainforest_raven/snapshots/test_diagnostics.ambr +++ b/tests/components/rainforest_raven/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, @@ -84,6 +86,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/rainforest_raven/snapshots/test_init.ambr b/tests/components/rainforest_raven/snapshots/test_init.ambr index 768bbc729d4..8a143f9963f 100644 --- a/tests/components/rainforest_raven/snapshots/test_init.ambr +++ b/tests/components/rainforest_raven/snapshots/test_init.ambr @@ -8,6 +8,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/rainforest_raven/snapshots/test_sensor.ambr b/tests/components/rainforest_raven/snapshots/test_sensor.ambr index 34a5e031885..618766c1613 100644 --- a/tests/components/rainforest_raven/snapshots/test_sensor.ambr +++ b/tests/components/rainforest_raven/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +165,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -213,6 +217,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainmachine/snapshots/test_binary_sensor.ambr b/tests/components/rainmachine/snapshots/test_binary_sensor.ambr index 9c930736fe3..c4d6f2eeae1 100644 --- a/tests/components/rainmachine/snapshots/test_binary_sensor.ambr +++ b/tests/components/rainmachine/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainmachine/snapshots/test_button.ambr b/tests/components/rainmachine/snapshots/test_button.ambr index 609079bb0d8..68f83d9286a 100644 --- a/tests/components/rainmachine/snapshots/test_button.ambr +++ b/tests/components/rainmachine/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainmachine/snapshots/test_diagnostics.ambr b/tests/components/rainmachine/snapshots/test_diagnostics.ambr index acd5fd165b4..681805996f1 100644 --- a/tests/components/rainmachine/snapshots/test_diagnostics.ambr +++ b/tests/components/rainmachine/snapshots/test_diagnostics.ambr @@ -1144,6 +1144,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 2, @@ -2275,6 +2277,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 2, diff --git a/tests/components/rainmachine/snapshots/test_select.ambr b/tests/components/rainmachine/snapshots/test_select.ambr index 651a709d2fa..d150f8c31b5 100644 --- a/tests/components/rainmachine/snapshots/test_select.ambr +++ b/tests/components/rainmachine/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainmachine/snapshots/test_sensor.ambr b/tests/components/rainmachine/snapshots/test_sensor.ambr index e93d0645030..2475abecb51 100644 --- a/tests/components/rainmachine/snapshots/test_sensor.ambr +++ b/tests/components/rainmachine/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -242,6 +247,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -289,6 +295,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -336,6 +343,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -383,6 +391,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -430,6 +439,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -477,6 +487,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -524,6 +535,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -571,6 +583,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -618,6 +631,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -665,6 +679,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/rainmachine/snapshots/test_switch.ambr b/tests/components/rainmachine/snapshots/test_switch.ambr index b803ff994d4..d40913a7eb0 100644 --- a/tests/components/rainmachine/snapshots/test_switch.ambr +++ b/tests/components/rainmachine/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -78,6 +79,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -126,6 +128,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -173,6 +176,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -234,6 +238,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +287,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -329,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -390,6 +397,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -438,6 +446,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -510,6 +519,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +568,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -619,6 +630,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -667,6 +679,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -728,6 +741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -776,6 +790,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -837,6 +852,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -885,6 +901,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -946,6 +963,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -994,6 +1012,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1055,6 +1074,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1103,6 +1123,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1164,6 +1185,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1212,6 +1234,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1273,6 +1296,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1321,6 +1345,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1382,6 +1407,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1430,6 +1456,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1491,6 +1518,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1539,6 +1567,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1600,6 +1629,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/recollect_waste/test_diagnostics.py b/tests/components/recollect_waste/test_diagnostics.py index 24c690bcb37..a57e289ec04 100644 --- a/tests/components/recollect_waste/test_diagnostics.py +++ b/tests/components/recollect_waste/test_diagnostics.py @@ -34,6 +34,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "data": [ { diff --git a/tests/components/renault/snapshots/test_binary_sensor.ambr b/tests/components/renault/snapshots/test_binary_sensor.ambr index 7142608b977..b62cfb4d1b1 100644 --- a/tests/components/renault/snapshots/test_binary_sensor.ambr +++ b/tests/components/renault/snapshots/test_binary_sensor.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -41,6 +42,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -72,6 +74,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -134,6 +138,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -165,6 +170,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -196,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -304,6 +311,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -341,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -372,6 +381,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -403,6 +413,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -434,6 +445,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -465,6 +477,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -496,6 +509,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -527,6 +541,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -558,6 +573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -690,6 +706,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -727,6 +744,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -758,6 +776,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -789,6 +808,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -860,6 +880,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -897,6 +918,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -928,6 +950,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -959,6 +982,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -990,6 +1014,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1021,6 +1046,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1052,6 +1078,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1083,6 +1110,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1114,6 +1142,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1145,6 +1174,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1288,6 +1318,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1325,6 +1356,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1356,6 +1388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1387,6 +1420,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1418,6 +1452,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1449,6 +1484,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1480,6 +1516,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1588,6 +1625,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1625,6 +1663,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1656,6 +1695,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1687,6 +1727,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1718,6 +1759,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1749,6 +1791,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1780,6 +1823,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1811,6 +1855,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1842,6 +1887,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1974,6 +2020,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -2011,6 +2058,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2042,6 +2090,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2073,6 +2122,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2144,6 +2194,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -2181,6 +2232,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2212,6 +2264,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2243,6 +2296,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2274,6 +2328,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2305,6 +2360,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2336,6 +2392,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2367,6 +2424,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2398,6 +2456,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2429,6 +2488,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/renault/snapshots/test_button.ambr b/tests/components/renault/snapshots/test_button.ambr index e61255372c1..58789c7aa47 100644 --- a/tests/components/renault/snapshots/test_button.ambr +++ b/tests/components/renault/snapshots/test_button.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -41,6 +42,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -88,6 +90,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -125,6 +128,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +160,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -187,6 +192,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +262,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -293,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -324,6 +332,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -355,6 +364,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -424,6 +434,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -461,6 +472,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -492,6 +504,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -523,6 +536,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -592,6 +606,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -629,6 +644,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -676,6 +692,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -713,6 +730,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -744,6 +762,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -775,6 +794,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -844,6 +864,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -881,6 +902,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -912,6 +934,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -943,6 +966,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1012,6 +1036,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1049,6 +1074,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1080,6 +1106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1111,6 +1138,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/renault/snapshots/test_device_tracker.ambr b/tests/components/renault/snapshots/test_device_tracker.ambr index f90cb92cc63..119defca4ac 100644 --- a/tests/components/renault/snapshots/test_device_tracker.ambr +++ b/tests/components/renault/snapshots/test_device_tracker.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -41,6 +42,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -89,6 +91,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -126,6 +129,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -174,6 +178,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -216,6 +221,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -253,6 +259,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -301,6 +308,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -338,6 +346,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -389,6 +398,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -426,6 +436,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -477,6 +488,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -519,6 +531,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -556,6 +569,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/renault/snapshots/test_select.ambr b/tests/components/renault/snapshots/test_select.ambr index 9974e21be75..526c8af5bc4 100644 --- a/tests/components/renault/snapshots/test_select.ambr +++ b/tests/components/renault/snapshots/test_select.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -46,6 +47,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -90,6 +92,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -143,6 +146,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -187,6 +191,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +245,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -284,6 +290,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -337,6 +344,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -379,6 +387,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -423,6 +432,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +486,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -520,6 +531,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -573,6 +585,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -617,6 +630,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/renault/snapshots/test_sensor.ambr b/tests/components/renault/snapshots/test_sensor.ambr index b092222c9f3..175ad2422ed 100644 --- a/tests/components/renault/snapshots/test_sensor.ambr +++ b/tests/components/renault/snapshots/test_sensor.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -43,6 +44,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -76,6 +78,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -140,6 +144,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -171,6 +176,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -202,6 +208,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +321,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -353,6 +361,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -395,6 +404,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +438,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -461,6 +472,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -500,6 +512,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -533,6 +546,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -566,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -599,6 +614,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -630,6 +646,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -663,6 +680,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -696,6 +714,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -729,6 +748,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -760,6 +780,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -791,6 +812,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -822,6 +844,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1071,6 +1094,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1110,6 +1134,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1152,6 +1177,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1185,6 +1211,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1218,6 +1245,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1257,6 +1285,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1290,6 +1319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1323,6 +1353,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1356,6 +1387,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1387,6 +1419,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1420,6 +1453,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1453,6 +1487,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1484,6 +1519,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1515,6 +1551,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1546,6 +1583,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1577,6 +1615,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1824,6 +1863,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1863,6 +1903,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1905,6 +1946,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1938,6 +1980,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1971,6 +2014,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2010,6 +2054,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2043,6 +2088,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2076,6 +2122,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2109,6 +2156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2140,6 +2188,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2173,6 +2222,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2206,6 +2256,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2237,6 +2288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2268,6 +2320,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2299,6 +2352,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2330,6 +2384,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2361,6 +2416,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2620,6 +2676,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -2659,6 +2716,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2692,6 +2750,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2725,6 +2784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2756,6 +2816,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -2787,6 +2848,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2818,6 +2880,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -2930,6 +2993,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -2969,6 +3033,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3011,6 +3076,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3044,6 +3110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3077,6 +3144,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3116,6 +3184,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3149,6 +3218,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3182,6 +3252,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3215,6 +3286,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3246,6 +3318,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -3279,6 +3352,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3312,6 +3386,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3345,6 +3420,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3376,6 +3452,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -3407,6 +3484,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3438,6 +3516,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -3687,6 +3766,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -3726,6 +3806,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3768,6 +3849,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3801,6 +3883,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3834,6 +3917,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3873,6 +3957,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3906,6 +3991,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3939,6 +4025,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3972,6 +4059,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4003,6 +4091,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4036,6 +4125,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4069,6 +4159,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4100,6 +4191,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4131,6 +4223,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4162,6 +4255,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4193,6 +4287,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4440,6 +4535,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -4479,6 +4575,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4521,6 +4618,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4554,6 +4652,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4587,6 +4686,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4626,6 +4726,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4659,6 +4760,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4692,6 +4794,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4725,6 +4828,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4756,6 +4860,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4789,6 +4894,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4822,6 +4928,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4853,6 +4960,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4884,6 +4992,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4915,6 +5024,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -4946,6 +5056,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4977,6 +5088,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , diff --git a/tests/components/ridwell/snapshots/test_diagnostics.ambr b/tests/components/ridwell/snapshots/test_diagnostics.ambr index b03d87c7a89..4b4dda7227d 100644 --- a/tests/components/ridwell/snapshots/test_diagnostics.ambr +++ b/tests/components/ridwell/snapshots/test_diagnostics.ambr @@ -44,6 +44,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 2, diff --git a/tests/components/ring/snapshots/test_binary_sensor.ambr b/tests/components/ring/snapshots/test_binary_sensor.ambr index 84c727e6340..09dab9b0ecc 100644 --- a/tests/components/ring/snapshots/test_binary_sensor.ambr +++ b/tests/components/ring/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_button.ambr b/tests/components/ring/snapshots/test_button.ambr index 01f6525450b..7da11d66194 100644 --- a/tests/components/ring/snapshots/test_button.ambr +++ b/tests/components/ring/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_camera.ambr b/tests/components/ring/snapshots/test_camera.ambr index ec285b438b3..8c3b8a083b0 100644 --- a/tests/components/ring/snapshots/test_camera.ambr +++ b/tests/components/ring/snapshots/test_camera.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -112,6 +114,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -164,6 +167,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -217,6 +221,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -270,6 +275,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_event.ambr b/tests/components/ring/snapshots/test_event.ambr index e97a01516bb..9c0fee906a0 100644 --- a/tests/components/ring/snapshots/test_event.ambr +++ b/tests/components/ring/snapshots/test_event.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -178,6 +181,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -234,6 +238,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +295,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_light.ambr b/tests/components/ring/snapshots/test_light.ambr index 73874fda259..6c6effb93c1 100644 --- a/tests/components/ring/snapshots/test_light.ambr +++ b/tests/components/ring/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_number.ambr b/tests/components/ring/snapshots/test_number.ambr index 0873319b837..abc63051f6a 100644 --- a/tests/components/ring/snapshots/test_number.ambr +++ b/tests/components/ring/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -123,6 +125,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -235,6 +239,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -291,6 +296,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -347,6 +353,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_sensor.ambr b/tests/components/ring/snapshots/test_sensor.ambr index a90bb3fe5f6..615bd1df018 100644 --- a/tests/components/ring/snapshots/test_sensor.ambr +++ b/tests/components/ring/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -151,6 +154,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -203,6 +207,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -253,6 +258,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -301,6 +307,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +356,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -397,6 +405,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -444,6 +453,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -491,6 +501,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -540,6 +551,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -588,6 +600,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -636,6 +649,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -684,6 +698,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -731,6 +746,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -782,6 +798,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -832,6 +849,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -879,6 +897,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -927,6 +946,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -974,6 +994,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1021,6 +1042,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1068,6 +1090,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1119,6 +1142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1169,6 +1193,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1217,6 +1242,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1265,6 +1291,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1313,6 +1340,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1360,6 +1388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_siren.ambr b/tests/components/ring/snapshots/test_siren.ambr index c49ab2cb30f..8ef08815a1e 100644 --- a/tests/components/ring/snapshots/test_siren.ambr +++ b/tests/components/ring/snapshots/test_siren.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -63,6 +64,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/ring/snapshots/test_switch.ambr b/tests/components/ring/snapshots/test_switch.ambr index 57c27cfedfa..8c7c55d5169 100644 --- a/tests/components/ring/snapshots/test_switch.ambr +++ b/tests/components/ring/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/roborock/conftest.py b/tests/components/roborock/conftest.py index 43e5148c9a8..9b3a6633c62 100644 --- a/tests/components/roborock/conftest.py +++ b/tests/components/roborock/conftest.py @@ -30,6 +30,7 @@ from .mock_data import ( MULTI_MAP_LIST, NETWORK_INFO, PROP, + SCENES, USER_DATA, USER_EMAIL, ) @@ -67,8 +68,24 @@ class A01Mock(RoborockMqttClientA01): return {prot: self.protocol_responses[prot] for prot in dyad_data_protocols} +@pytest.fixture(name="bypass_api_client_fixture") +def bypass_api_client_fixture() -> None: + """Skip calls to the API client.""" + with ( + patch( + "homeassistant.components.roborock.RoborockApiClient.get_home_data_v2", + return_value=HOME_DATA, + ), + patch( + "homeassistant.components.roborock.RoborockApiClient.get_scenes", + return_value=SCENES, + ), + ): + yield + + @pytest.fixture(name="bypass_api_fixture") -def bypass_api_fixture() -> None: +def bypass_api_fixture(bypass_api_client_fixture: Any) -> None: """Skip calls to the API.""" with ( patch("homeassistant.components.roborock.RoborockMqttClientV1.async_connect"), @@ -76,10 +93,6 @@ def bypass_api_fixture() -> None: patch( "homeassistant.components.roborock.coordinator.RoborockMqttClientV1._send_command" ), - patch( - "homeassistant.components.roborock.RoborockApiClient.get_home_data_v2", - return_value=HOME_DATA, - ), patch( "homeassistant.components.roborock.RoborockMqttClientV1.get_networking", return_value=NETWORK_INFO, diff --git a/tests/components/roborock/mock_data.py b/tests/components/roborock/mock_data.py index 6e3fb229aa9..59c54892687 100644 --- a/tests/components/roborock/mock_data.py +++ b/tests/components/roborock/mock_data.py @@ -9,6 +9,7 @@ from roborock.containers import ( Consumable, DnDTimer, HomeData, + HomeDataScene, MultiMapsList, NetworkInfo, S7Status, @@ -1150,3 +1151,19 @@ MAP_DATA = MapData(0, 0) MAP_DATA.image = ImageData( 100, 10, 10, 10, 10, ImageConfig(), Image.new("RGB", (1, 1)), lambda p: p ) + + +SCENES = [ + HomeDataScene.from_dict( + { + "name": "sc1", + "id": 12, + }, + ), + HomeDataScene.from_dict( + { + "name": "sc2", + "id": 24, + }, + ), +] diff --git a/tests/components/roborock/test_scene.py b/tests/components/roborock/test_scene.py new file mode 100644 index 00000000000..15707784feb --- /dev/null +++ b/tests/components/roborock/test_scene.py @@ -0,0 +1,112 @@ +"""Test Roborock Scene platform.""" + +from unittest.mock import ANY, patch + +import pytest +from roborock import RoborockException + +from homeassistant.const import SERVICE_TURN_ON, Platform +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError + +from tests.common import MockConfigEntry + + +@pytest.fixture +def bypass_api_client_get_scenes_fixture(bypass_api_fixture) -> None: + """Fixture to raise when getting scenes.""" + with ( + patch( + "homeassistant.components.roborock.RoborockApiClient.get_scenes", + side_effect=RoborockException(), + ), + ): + yield + + +@pytest.mark.parametrize( + ("entity_id"), + [ + ("scene.roborock_s7_maxv_sc1"), + ("scene.roborock_s7_maxv_sc2"), + ], +) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_get_scenes_failure( + hass: HomeAssistant, + bypass_api_client_get_scenes_fixture, + setup_entry: MockConfigEntry, + entity_id: str, +) -> None: + """Test that if scene retrieval fails, no entity is being created.""" + # Ensure that the entity does not exist + assert hass.states.get(entity_id) is None + + +@pytest.fixture +def platforms() -> list[Platform]: + """Fixture to set platforms used in the test.""" + return [Platform.SCENE] + + +@pytest.mark.parametrize( + ("entity_id", "scene_id"), + [ + ("scene.roborock_s7_maxv_sc1", 12), + ("scene.roborock_s7_maxv_sc2", 24), + ], +) +@pytest.mark.freeze_time("2023-10-30 08:50:00") +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_execute_success( + hass: HomeAssistant, + bypass_api_fixture, + setup_entry: MockConfigEntry, + entity_id: str, + scene_id: int, +) -> None: + """Test activating the scene entities.""" + with patch( + "homeassistant.components.roborock.RoborockApiClient.execute_scene" + ) as mock_execute_scene: + await hass.services.async_call( + "scene", + SERVICE_TURN_ON, + blocking=True, + target={"entity_id": entity_id}, + ) + mock_execute_scene.assert_called_once_with(ANY, scene_id) + assert hass.states.get(entity_id).state == "2023-10-30T08:50:00+00:00" + + +@pytest.mark.parametrize( + ("entity_id", "scene_id"), + [ + ("scene.roborock_s7_maxv_sc1", 12), + ], +) +@pytest.mark.freeze_time("2023-10-30 08:50:00") +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_execute_failure( + hass: HomeAssistant, + bypass_api_fixture, + setup_entry: MockConfigEntry, + entity_id: str, + scene_id: int, +) -> None: + """Test failure while activating the scene entity.""" + with ( + patch( + "homeassistant.components.roborock.RoborockApiClient.execute_scene", + side_effect=RoborockException, + ) as mock_execute_scene, + pytest.raises(HomeAssistantError, match="Error while calling execute_scene"), + ): + await hass.services.async_call( + "scene", + SERVICE_TURN_ON, + blocking=True, + target={"entity_id": entity_id}, + ) + mock_execute_scene.assert_called_once_with(ANY, scene_id) + assert hass.states.get(entity_id).state == "2023-10-30T08:50:00+00:00" diff --git a/tests/components/rova/snapshots/test_init.ambr b/tests/components/rova/snapshots/test_init.ambr index 5e607e6a8df..8eb77006061 100644 --- a/tests/components/rova/snapshots/test_init.ambr +++ b/tests/components/rova/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/rova/snapshots/test_sensor.ambr b/tests/components/rova/snapshots/test_sensor.ambr index 866f1c735c1..90cf29a1b89 100644 --- a/tests/components/rova/snapshots/test_sensor.ambr +++ b/tests/components/rova/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/russound_rio/snapshots/test_init.ambr b/tests/components/russound_rio/snapshots/test_init.ambr index c92f06c4bc0..e3185a06b24 100644 --- a/tests/components/russound_rio/snapshots/test_init.ambr +++ b/tests/components/russound_rio/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.20.75', 'connections': set({ tuple( diff --git a/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr b/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr index 9f3087df3d1..1feaece1c3e 100644 --- a/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr +++ b/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sabnzbd/snapshots/test_button.ambr b/tests/components/sabnzbd/snapshots/test_button.ambr index 9b965e10518..f09bb44e8e4 100644 --- a/tests/components/sabnzbd/snapshots/test_button.ambr +++ b/tests/components/sabnzbd/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sabnzbd/snapshots/test_number.ambr b/tests/components/sabnzbd/snapshots/test_number.ambr index 6a370797264..623002470b7 100644 --- a/tests/components/sabnzbd/snapshots/test_number.ambr +++ b/tests/components/sabnzbd/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sabnzbd/snapshots/test_sensor.ambr b/tests/components/sabnzbd/snapshots/test_sensor.ambr index 8b977e69aa6..893d270a569 100644 --- a/tests/components/sabnzbd/snapshots/test_sensor.ambr +++ b/tests/components/sabnzbd/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -62,6 +63,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -164,6 +167,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +222,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -272,6 +277,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -323,6 +329,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -375,6 +382,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -430,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -478,6 +487,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -529,6 +539,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/samsungtv/snapshots/test_init.ambr b/tests/components/samsungtv/snapshots/test_init.ambr index 017a2bc3e60..ad01b5454ff 100644 --- a/tests/components/samsungtv/snapshots/test_init.ambr +++ b/tests/components/samsungtv/snapshots/test_init.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -46,6 +47,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -115,6 +117,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/samsungtv/test_diagnostics.py b/tests/components/samsungtv/test_diagnostics.py index 0319d5dd8dd..e8e0b699a7e 100644 --- a/tests/components/samsungtv/test_diagnostics.py +++ b/tests/components/samsungtv/test_diagnostics.py @@ -51,6 +51,7 @@ async def test_entry_diagnostics( "pref_disable_new_entities": False, "pref_disable_polling": False, "source": "user", + "subentries": [], "title": "Mock Title", "unique_id": "any", "version": 2, @@ -91,6 +92,7 @@ async def test_entry_diagnostics_encrypted( "pref_disable_new_entities": False, "pref_disable_polling": False, "source": "user", + "subentries": [], "title": "Mock Title", "unique_id": "any", "version": 2, @@ -130,6 +132,7 @@ async def test_entry_diagnostics_encrypte_offline( "pref_disable_new_entities": False, "pref_disable_polling": False, "source": "user", + "subentries": [], "title": "Mock Title", "unique_id": "any", "version": 2, diff --git a/tests/components/sanix/snapshots/test_sensor.ambr b/tests/components/sanix/snapshots/test_sensor.ambr index 84c97ce68b1..6cf0254b66b 100644 --- a/tests/components/sanix/snapshots/test_sensor.ambr +++ b/tests/components/sanix/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -105,6 +107,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +159,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -204,6 +208,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -251,6 +256,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/schlage/snapshots/test_init.ambr b/tests/components/schlage/snapshots/test_init.ambr index c7049443ab7..a7f94b80038 100644 --- a/tests/components/schlage/snapshots/test_init.ambr +++ b/tests/components/schlage/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/screenlogic/snapshots/test_diagnostics.ambr b/tests/components/screenlogic/snapshots/test_diagnostics.ambr index 237d3eab257..c7db7a33959 100644 --- a/tests/components/screenlogic/snapshots/test_diagnostics.ambr +++ b/tests/components/screenlogic/snapshots/test_diagnostics.ambr @@ -18,6 +18,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Pentair: DD-EE-FF', 'unique_id': 'aa:bb:cc:dd:ee:ff', 'version': 1, diff --git a/tests/components/sense/snapshots/test_binary_sensor.ambr b/tests/components/sense/snapshots/test_binary_sensor.ambr index 339830b16d3..7221a0bc518 100644 --- a/tests/components/sense/snapshots/test_binary_sensor.ambr +++ b/tests/components/sense/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sense/snapshots/test_sensor.ambr b/tests/components/sense/snapshots/test_sensor.ambr index 4a3507880a1..0a68553cf04 100644 --- a/tests/components/sense/snapshots/test_sensor.ambr +++ b/tests/components/sense/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -120,6 +122,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -176,6 +179,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -229,6 +233,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -285,6 +290,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -341,6 +347,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -397,6 +404,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -453,6 +461,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -509,6 +518,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -562,6 +572,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -618,6 +629,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -674,6 +686,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -727,6 +740,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -780,6 +794,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -831,6 +846,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -881,6 +897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -932,6 +949,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -982,6 +1000,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1035,6 +1054,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1088,6 +1108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1141,6 +1162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1192,6 +1214,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1242,6 +1265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1293,6 +1317,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1343,6 +1368,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1396,6 +1422,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1448,6 +1475,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1500,6 +1528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1552,6 +1581,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1605,6 +1635,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1658,6 +1689,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1709,6 +1741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1759,6 +1792,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1810,6 +1844,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1860,6 +1895,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1913,6 +1949,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1965,6 +2002,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2018,6 +2056,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2071,6 +2110,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2122,6 +2162,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2172,6 +2213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2223,6 +2265,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2273,6 +2316,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2326,6 +2370,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2379,6 +2424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2432,6 +2478,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2483,6 +2530,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2533,6 +2581,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2584,6 +2633,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2634,6 +2684,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_binary_sensor.ambr b/tests/components/sensibo/snapshots/test_binary_sensor.ambr index 110a6ae8174..2e62c73acb4 100644 --- a/tests/components/sensibo/snapshots/test_binary_sensor.ambr +++ b/tests/components/sensibo/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -381,6 +389,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -475,6 +485,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -522,6 +533,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +581,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -616,6 +629,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -663,6 +677,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_button.ambr b/tests/components/sensibo/snapshots/test_button.ambr index 7ef6d56c714..6bfc4a5a44f 100644 --- a/tests/components/sensibo/snapshots/test_button.ambr +++ b/tests/components/sensibo/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_climate.ambr b/tests/components/sensibo/snapshots/test_climate.ambr index 5bcfae0917e..e3bd456ad23 100644 --- a/tests/components/sensibo/snapshots/test_climate.ambr +++ b/tests/components/sensibo/snapshots/test_climate.ambr @@ -13,6 +13,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -94,6 +95,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -185,6 +187,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_entity.ambr b/tests/components/sensibo/snapshots/test_entity.ambr index 23ead2f6d96..80ee847cb55 100644 --- a/tests/components/sensibo/snapshots/test_entity.ambr +++ b/tests/components/sensibo/snapshots/test_entity.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'hallway', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.sensibo.com/', 'connections': set({ tuple( @@ -38,6 +39,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'kitchen', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.sensibo.com/', 'connections': set({ tuple( @@ -72,6 +74,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'bedroom', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.sensibo.com/', 'connections': set({ tuple( @@ -106,6 +109,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://home.sensibo.com/', 'connections': set({ }), diff --git a/tests/components/sensibo/snapshots/test_number.ambr b/tests/components/sensibo/snapshots/test_number.ambr index b632b95f1be..458c7ca7183 100644 --- a/tests/components/sensibo/snapshots/test_number.ambr +++ b/tests/components/sensibo/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -125,6 +127,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -182,6 +185,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +243,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +301,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_select.ambr b/tests/components/sensibo/snapshots/test_select.ambr index 7438fb70140..05582a1ea16 100644 --- a/tests/components/sensibo/snapshots/test_select.ambr +++ b/tests/components/sensibo/snapshots/test_select.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_sensor.ambr b/tests/components/sensibo/snapshots/test_sensor.ambr index 31e579d9929..bfd5f2d3e9a 100644 --- a/tests/components/sensibo/snapshots/test_sensor.ambr +++ b/tests/components/sensibo/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +222,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +280,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -321,6 +327,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -370,6 +377,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -421,6 +429,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -472,6 +481,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -523,6 +533,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -574,6 +585,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -623,6 +635,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -672,6 +685,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -725,6 +739,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -777,6 +792,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_switch.ambr b/tests/components/sensibo/snapshots/test_switch.ambr index 13cb73cef7a..e0ea140eb37 100644 --- a/tests/components/sensibo/snapshots/test_switch.ambr +++ b/tests/components/sensibo/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensibo/snapshots/test_update.ambr b/tests/components/sensibo/snapshots/test_update.ambr index 3eb69c9a812..c113d5615b1 100644 --- a/tests/components/sensibo/snapshots/test_update.ambr +++ b/tests/components/sensibo/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +126,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sensor/test_init.py b/tests/components/sensor/test_init.py index 604cd91770e..b162200f95e 100644 --- a/tests/components/sensor/test_init.py +++ b/tests/components/sensor/test_init.py @@ -45,7 +45,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, State from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.restore_state import STORAGE_KEY as RESTORE_STATE_KEY from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -2584,7 +2584,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test sensor platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) diff --git a/tests/components/sfr_box/snapshots/test_binary_sensor.ambr b/tests/components/sfr_box/snapshots/test_binary_sensor.ambr index 15308fad91f..4718abc02b5 100644 --- a/tests/components/sfr_box/snapshots/test_binary_sensor.ambr +++ b/tests/components/sfr_box/snapshots/test_binary_sensor.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.0.1', 'connections': set({ }), @@ -41,6 +42,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -72,6 +74,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -132,6 +135,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.0.1', 'connections': set({ }), @@ -169,6 +173,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -200,6 +205,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sfr_box/snapshots/test_button.ambr b/tests/components/sfr_box/snapshots/test_button.ambr index 67b2198fd2b..68a1e7f7227 100644 --- a/tests/components/sfr_box/snapshots/test_button.ambr +++ b/tests/components/sfr_box/snapshots/test_button.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.0.1', 'connections': set({ }), @@ -41,6 +42,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sfr_box/snapshots/test_sensor.ambr b/tests/components/sfr_box/snapshots/test_sensor.ambr index 7645a4ad8bf..6376ef24ce2 100644 --- a/tests/components/sfr_box/snapshots/test_sensor.ambr +++ b/tests/components/sfr_box/snapshots/test_sensor.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.0.1', 'connections': set({ }), @@ -48,6 +49,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -79,6 +81,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -110,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -149,6 +153,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -180,6 +185,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -211,6 +217,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -242,6 +249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -275,6 +283,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -308,6 +317,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -341,6 +351,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -374,6 +385,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -407,6 +419,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -440,6 +453,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -480,6 +494,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -524,6 +539,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , diff --git a/tests/components/shelly/snapshots/test_binary_sensor.ambr b/tests/components/shelly/snapshots/test_binary_sensor.ambr index 942bcaad8ab..fcc6377837e 100644 --- a/tests/components/shelly/snapshots/test_binary_sensor.ambr +++ b/tests/components/shelly/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/shelly/snapshots/test_event.ambr b/tests/components/shelly/snapshots/test_event.ambr index 51129b7e249..ae719774aee 100644 --- a/tests/components/shelly/snapshots/test_event.ambr +++ b/tests/components/shelly/snapshots/test_event.ambr @@ -11,6 +11,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/shelly/snapshots/test_number.ambr b/tests/components/shelly/snapshots/test_number.ambr index 811101abe21..07fda999556 100644 --- a/tests/components/shelly/snapshots/test_number.ambr +++ b/tests/components/shelly/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/shelly/snapshots/test_sensor.ambr b/tests/components/shelly/snapshots/test_sensor.ambr index 8ab767ca889..cb39b148c8a 100644 --- a/tests/components/shelly/snapshots/test_sensor.ambr +++ b/tests/components/shelly/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/simplefin/snapshots/test_binary_sensor.ambr b/tests/components/simplefin/snapshots/test_binary_sensor.ambr index 44fe2a10b78..3123100205e 100644 --- a/tests/components/simplefin/snapshots/test_binary_sensor.ambr +++ b/tests/components/simplefin/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/simplefin/snapshots/test_sensor.ambr b/tests/components/simplefin/snapshots/test_sensor.ambr index c7dced9300e..dd305f7528f 100644 --- a/tests/components/simplefin/snapshots/test_sensor.ambr +++ b/tests/components/simplefin/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -160,6 +163,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -210,6 +214,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -261,6 +266,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -311,6 +317,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -362,6 +369,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -412,6 +420,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -463,6 +472,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -513,6 +523,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -564,6 +575,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -614,6 +626,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -665,6 +678,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -715,6 +729,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -766,6 +781,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/simplisafe/test_diagnostics.py b/tests/components/simplisafe/test_diagnostics.py index d5479f00b06..13c1e28aa36 100644 --- a/tests/components/simplisafe/test_diagnostics.py +++ b/tests/components/simplisafe/test_diagnostics.py @@ -32,6 +32,7 @@ async def test_entry_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, "subscription_data": { "12345": { diff --git a/tests/components/slide_local/snapshots/test_button.ambr b/tests/components/slide_local/snapshots/test_button.ambr index 549538f1361..7b363f4d9ba 100644 --- a/tests/components/slide_local/snapshots/test_button.ambr +++ b/tests/components/slide_local/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/slide_local/snapshots/test_cover.ambr b/tests/components/slide_local/snapshots/test_cover.ambr index d9283618a47..172f5411a94 100644 --- a/tests/components/slide_local/snapshots/test_cover.ambr +++ b/tests/components/slide_local/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/slide_local/snapshots/test_diagnostics.ambr b/tests/components/slide_local/snapshots/test_diagnostics.ambr index 63dab3f5a66..7606c2a399b 100644 --- a/tests/components/slide_local/snapshots/test_diagnostics.ambr +++ b/tests/components/slide_local/snapshots/test_diagnostics.ambr @@ -19,6 +19,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'slide', 'unique_id': '12:34:56:78:90:ab', 'version': 1, diff --git a/tests/components/slide_local/snapshots/test_init.ambr b/tests/components/slide_local/snapshots/test_init.ambr index d90f72e4b05..5b1a9f5ce2f 100644 --- a/tests/components/slide_local/snapshots/test_init.ambr +++ b/tests/components/slide_local/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.2', 'connections': set({ tuple( diff --git a/tests/components/slide_local/snapshots/test_switch.ambr b/tests/components/slide_local/snapshots/test_switch.ambr index e19467c283e..9b1a7969539 100644 --- a/tests/components/slide_local/snapshots/test_switch.ambr +++ b/tests/components/slide_local/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sma/snapshots/test_diagnostics.ambr b/tests/components/sma/snapshots/test_diagnostics.ambr index c7de3851b5f..14b0d120190 100644 --- a/tests/components/sma/snapshots/test_diagnostics.ambr +++ b/tests/components/sma/snapshots/test_diagnostics.ambr @@ -21,6 +21,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'import', + 'subentries': list([ + ]), 'title': 'SMA Device Name', 'unique_id': '123456789', 'version': 1, diff --git a/tests/components/smartthings/test_sensor.py b/tests/components/smartthings/test_sensor.py index 7e6768e4d7d..a6a48202f1d 100644 --- a/tests/components/smartthings/test_sensor.py +++ b/tests/components/smartthings/test_sensor.py @@ -4,14 +4,9 @@ The only mocking required is of the underlying SmartThings API object so real HTTP calls are not initiated during testing. """ -from pysmartthings import ATTRIBUTES, CAPABILITIES, Attribute, Capability +from pysmartthings import Attribute, Capability -from homeassistant.components.sensor import ( - DEVICE_CLASSES, - DOMAIN as SENSOR_DOMAIN, - STATE_CLASSES, -) -from homeassistant.components.smartthings import sensor +from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.components.smartthings.const import DOMAIN, SIGNAL_SMARTTHINGS_UPDATE from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ( @@ -29,20 +24,6 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from .conftest import setup_platform -async def test_mapping_integrity() -> None: - """Test ensures the map dicts have proper integrity.""" - for capability, maps in sensor.CAPABILITY_TO_SENSORS.items(): - assert capability in CAPABILITIES, capability - for sensor_map in maps: - assert sensor_map.attribute in ATTRIBUTES, sensor_map.attribute - if sensor_map.device_class: - assert sensor_map.device_class in DEVICE_CLASSES, ( - sensor_map.device_class - ) - if sensor_map.state_class: - assert sensor_map.state_class in STATE_CLASSES, sensor_map.state_class - - async def test_entity_state(hass: HomeAssistant, device_factory) -> None: """Tests the state attributes properly match the sensor types.""" device = device_factory("Sensor 1", [Capability.battery], {Attribute.battery: 100}) @@ -75,7 +56,9 @@ async def test_entity_three_axis_invalid_state( ) -> None: """Tests the state attributes properly match the three axis types.""" device = device_factory( - "Three Axis", [Capability.three_axis], {Attribute.three_axis: []} + "Three Axis", + [Capability.three_axis], + {Attribute.three_axis: [None, None, None]}, ) await setup_platform(hass, SENSOR_DOMAIN, devices=[device]) state = hass.states.get("sensor.three_axis_x_coordinate") diff --git a/tests/components/smarty/snapshots/test_binary_sensor.ambr b/tests/components/smarty/snapshots/test_binary_sensor.ambr index 2f943a25012..ad4b61f5070 100644 --- a/tests/components/smarty/snapshots/test_binary_sensor.ambr +++ b/tests/components/smarty/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smarty/snapshots/test_button.ambr b/tests/components/smarty/snapshots/test_button.ambr index 38849bd2b2e..b5b86c80beb 100644 --- a/tests/components/smarty/snapshots/test_button.ambr +++ b/tests/components/smarty/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smarty/snapshots/test_fan.ambr b/tests/components/smarty/snapshots/test_fan.ambr index 8ca95beeb86..2502bd6f09f 100644 --- a/tests/components/smarty/snapshots/test_fan.ambr +++ b/tests/components/smarty/snapshots/test_fan.ambr @@ -8,6 +8,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smarty/snapshots/test_init.ambr b/tests/components/smarty/snapshots/test_init.ambr index b25cdb9dc3a..a292cc97f47 100644 --- a/tests/components/smarty/snapshots/test_init.ambr +++ b/tests/components/smarty/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/smarty/snapshots/test_sensor.ambr b/tests/components/smarty/snapshots/test_sensor.ambr index 2f713db7f83..c32740fa38c 100644 --- a/tests/components/smarty/snapshots/test_sensor.ambr +++ b/tests/components/smarty/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -148,6 +151,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -196,6 +200,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -244,6 +249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smarty/snapshots/test_switch.ambr b/tests/components/smarty/snapshots/test_switch.ambr index be1da7c6961..33c829adf31 100644 --- a/tests/components/smarty/snapshots/test_switch.ambr +++ b/tests/components/smarty/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smlight/snapshots/test_binary_sensor.ambr b/tests/components/smlight/snapshots/test_binary_sensor.ambr index 8becf5b2567..edb2a914a5d 100644 --- a/tests/components/smlight/snapshots/test_binary_sensor.ambr +++ b/tests/components/smlight/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smlight/snapshots/test_init.ambr b/tests/components/smlight/snapshots/test_init.ambr index 457a529065c..ba374199254 100644 --- a/tests/components/smlight/snapshots/test_init.ambr +++ b/tests/components/smlight/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.1.161', 'connections': set({ tuple( diff --git a/tests/components/smlight/snapshots/test_sensor.ambr b/tests/components/smlight/snapshots/test_sensor.ambr index 262ecfe1544..542338e4dbf 100644 --- a/tests/components/smlight/snapshots/test_sensor.ambr +++ b/tests/components/smlight/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -118,6 +120,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -165,6 +168,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -218,6 +222,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -269,6 +274,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -319,6 +325,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -377,6 +384,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smlight/snapshots/test_switch.ambr b/tests/components/smlight/snapshots/test_switch.ambr index 733d002be0f..b748202a557 100644 --- a/tests/components/smlight/snapshots/test_switch.ambr +++ b/tests/components/smlight/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/smlight/snapshots/test_update.ambr b/tests/components/smlight/snapshots/test_update.ambr index 8c6757d5b91..dc6b8f46ca5 100644 --- a/tests/components/smlight/snapshots/test_update.ambr +++ b/tests/components/smlight/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/solarlog/snapshots/test_diagnostics.ambr b/tests/components/solarlog/snapshots/test_diagnostics.ambr index e0f1bc2623c..6aef72ebbd5 100644 --- a/tests/components/solarlog/snapshots/test_diagnostics.ambr +++ b/tests/components/solarlog/snapshots/test_diagnostics.ambr @@ -18,6 +18,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'solarlog', 'unique_id': None, 'version': 1, diff --git a/tests/components/solarlog/snapshots/test_sensor.ambr b/tests/components/solarlog/snapshots/test_sensor.ambr index 06bc01f9d39..c51f7627efc 100644 --- a/tests/components/solarlog/snapshots/test_sensor.ambr +++ b/tests/components/solarlog/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -116,6 +118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -173,6 +176,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -224,6 +228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +280,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -329,6 +335,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +387,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -437,6 +445,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -494,6 +503,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -551,6 +561,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -606,6 +617,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -662,6 +674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -716,6 +729,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -765,6 +779,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -814,6 +829,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -865,6 +881,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -916,6 +933,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -967,6 +985,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1018,6 +1037,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1072,6 +1092,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1123,6 +1144,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1174,6 +1196,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1231,6 +1254,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1288,6 +1312,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1345,6 +1370,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1397,6 +1423,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/sonos/snapshots/test_media_player.ambr b/tests/components/sonos/snapshots/test_media_player.ambr index 8ef298de3db..7f4681d8915 100644 --- a/tests/components/sonos/snapshots/test_media_player.ambr +++ b/tests/components/sonos/snapshots/test_media_player.ambr @@ -7,6 +7,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/spotify/snapshots/test_media_player.ambr b/tests/components/spotify/snapshots/test_media_player.ambr index 9692d59cfd1..74dbcb50f92 100644 --- a/tests/components/spotify/snapshots/test_media_player.ambr +++ b/tests/components/spotify/snapshots/test_media_player.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -79,6 +80,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/squeezebox/snapshots/test_media_player.ambr b/tests/components/squeezebox/snapshots/test_media_player.ambr index ddd5b9868a1..fd663c5eb63 100644 --- a/tests/components/squeezebox/snapshots/test_media_player.ambr +++ b/tests/components/squeezebox/snapshots/test_media_player.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -43,6 +44,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/stookwijzer/snapshots/test_sensor.ambr b/tests/components/stookwijzer/snapshots/test_sensor.ambr index f6751a84f22..ff1f6a12b8a 100644 --- a/tests/components/stookwijzer/snapshots/test_sensor.ambr +++ b/tests/components/stookwijzer/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -67,6 +68,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -118,6 +120,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/streamlabswater/snapshots/test_binary_sensor.ambr b/tests/components/streamlabswater/snapshots/test_binary_sensor.ambr index c74df76e71b..d13a19bc656 100644 --- a/tests/components/streamlabswater/snapshots/test_binary_sensor.ambr +++ b/tests/components/streamlabswater/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/streamlabswater/snapshots/test_sensor.ambr b/tests/components/streamlabswater/snapshots/test_sensor.ambr index d54cdcafb93..c1248f2c0a0 100644 --- a/tests/components/streamlabswater/snapshots/test_sensor.ambr +++ b/tests/components/streamlabswater/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -108,6 +110,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/stt/test_init.py b/tests/components/stt/test_init.py index 3d5daab2bec..e36ece52f57 100644 --- a/tests/components/stt/test_init.py +++ b/tests/components/stt/test_init.py @@ -16,7 +16,7 @@ from homeassistant.components.stt import ( ) from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_setup_component from .common import ( @@ -145,7 +145,7 @@ async def mock_config_entry_setup( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test stt platform via config entry.""" async_add_entities([mock_provider_entity]) diff --git a/tests/components/subaru/test_config_flow.py b/tests/components/subaru/test_config_flow.py index 6abc544c92a..0b45546902b 100644 --- a/tests/components/subaru/test_config_flow.py +++ b/tests/components/subaru/test_config_flow.py @@ -136,6 +136,7 @@ async def test_user_form_pin_not_required( "data": deepcopy(TEST_CONFIG), "options": {}, "minor_version": 1, + "subentries": (), } expected["data"][CONF_PIN] = None @@ -341,6 +342,7 @@ async def test_pin_form_success(hass: HomeAssistant, pin_form) -> None: "data": TEST_CONFIG, "options": {}, "minor_version": 1, + "subentries": (), } result["data"][CONF_DEVICE_ID] = TEST_DEVICE_ID assert result == expected diff --git a/tests/components/suez_water/snapshots/test_sensor.ambr b/tests/components/suez_water/snapshots/test_sensor.ambr index da0ed3df7dd..536e79df606 100644 --- a/tests/components/suez_water/snapshots/test_sensor.ambr +++ b/tests/components/suez_water/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/swiss_public_transport/snapshots/test_sensor.ambr b/tests/components/swiss_public_transport/snapshots/test_sensor.ambr index b8ad82c7b79..5ba65b2bd70 100644 --- a/tests/components/swiss_public_transport/snapshots/test_sensor.ambr +++ b/tests/components/swiss_public_transport/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -151,6 +154,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -199,6 +203,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -293,6 +299,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -340,6 +347,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/switchbot_cloud/snapshots/test_sensor.ambr b/tests/components/switchbot_cloud/snapshots/test_sensor.ambr index a9b6fb20bfb..2446add959b 100644 --- a/tests/components/switchbot_cloud/snapshots/test_sensor.ambr +++ b/tests/components/switchbot_cloud/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/switcher_kis/test_diagnostics.py b/tests/components/switcher_kis/test_diagnostics.py index 53572085f9b..f59958420c4 100644 --- a/tests/components/switcher_kis/test_diagnostics.py +++ b/tests/components/switcher_kis/test_diagnostics.py @@ -69,5 +69,6 @@ async def test_diagnostics( "created_at": ANY, "modified_at": ANY, "discovery_keys": {}, + "subentries": [], }, } diff --git a/tests/components/systemmonitor/snapshots/test_diagnostics.ambr b/tests/components/systemmonitor/snapshots/test_diagnostics.ambr index 75d942fc601..afa508cc004 100644 --- a/tests/components/systemmonitor/snapshots/test_diagnostics.ambr +++ b/tests/components/systemmonitor/snapshots/test_diagnostics.ambr @@ -56,6 +56,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'System Monitor', 'unique_id': None, 'version': 1, @@ -111,6 +113,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'System Monitor', 'unique_id': None, 'version': 1, diff --git a/tests/components/tailwind/snapshots/test_binary_sensor.ambr b/tests/components/tailwind/snapshots/test_binary_sensor.ambr index 064b391c43a..d04f2e726b5 100644 --- a/tests/components/tailwind/snapshots/test_binary_sensor.ambr +++ b/tests/components/tailwind/snapshots/test_binary_sensor.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -129,6 +132,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/tailwind/snapshots/test_button.ambr b/tests/components/tailwind/snapshots/test_button.ambr index 17b656ec5fd..7d3d10aa609 100644 --- a/tests/components/tailwind/snapshots/test_button.ambr +++ b/tests/components/tailwind/snapshots/test_button.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tailwind/snapshots/test_cover.ambr b/tests/components/tailwind/snapshots/test_cover.ambr index b69bd9e6410..1a26a6c98a7 100644 --- a/tests/components/tailwind/snapshots/test_cover.ambr +++ b/tests/components/tailwind/snapshots/test_cover.ambr @@ -21,6 +21,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -51,6 +52,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -101,6 +103,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -131,6 +134,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/tailwind/snapshots/test_number.ambr b/tests/components/tailwind/snapshots/test_number.ambr index 3e2e0577ad5..7b906ef1976 100644 --- a/tests/components/tailwind/snapshots/test_number.ambr +++ b/tests/components/tailwind/snapshots/test_number.ambr @@ -29,6 +29,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tankerkoenig/snapshots/test_diagnostics.ambr b/tests/components/tankerkoenig/snapshots/test_diagnostics.ambr index 3180c7c0b1d..b5b33d7c246 100644 --- a/tests/components/tankerkoenig/snapshots/test_diagnostics.ambr +++ b/tests/components/tankerkoenig/snapshots/test_diagnostics.ambr @@ -37,6 +37,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/tasmota/snapshots/test_sensor.ambr b/tests/components/tasmota/snapshots/test_sensor.ambr index be011e595b9..8a5a78cd366 100644 --- a/tests/components/tasmota/snapshots/test_sensor.ambr +++ b/tests/components/tasmota/snapshots/test_sensor.ambr @@ -24,6 +24,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -103,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -149,6 +151,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -254,6 +257,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -401,6 +405,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -452,6 +457,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -503,6 +509,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -586,6 +593,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -632,6 +640,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -741,6 +750,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -824,6 +834,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -875,6 +886,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -990,6 +1002,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1041,6 +1054,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1156,6 +1170,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1239,6 +1254,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1290,6 +1306,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1405,6 +1422,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1552,6 +1570,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1603,6 +1622,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1654,6 +1674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1732,6 +1753,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1860,6 +1882,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1909,6 +1932,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1958,6 +1982,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/technove/snapshots/test_binary_sensor.ambr b/tests/components/technove/snapshots/test_binary_sensor.ambr index f08dd6970fe..5d9bcd2175a 100644 --- a/tests/components/technove/snapshots/test_binary_sensor.ambr +++ b/tests/components/technove/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/technove/snapshots/test_number.ambr b/tests/components/technove/snapshots/test_number.ambr index 622c04d542a..eea4b0cb64c 100644 --- a/tests/components/technove/snapshots/test_number.ambr +++ b/tests/components/technove/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/technove/snapshots/test_sensor.ambr b/tests/components/technove/snapshots/test_sensor.ambr index 149155519d4..dec671b0f34 100644 --- a/tests/components/technove/snapshots/test_sensor.ambr +++ b/tests/components/technove/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -320,6 +326,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -376,6 +383,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -425,6 +433,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/technove/snapshots/test_switch.ambr b/tests/components/technove/snapshots/test_switch.ambr index 6febc8c768c..a5f8411747b 100644 --- a/tests/components/technove/snapshots/test_switch.ambr +++ b/tests/components/technove/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tedee/snapshots/test_binary_sensor.ambr b/tests/components/tedee/snapshots/test_binary_sensor.ambr index e3238dacda1..c2210a7ca5d 100644 --- a/tests/components/tedee/snapshots/test_binary_sensor.ambr +++ b/tests/components/tedee/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -286,6 +292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -332,6 +339,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tedee/snapshots/test_init.ambr b/tests/components/tedee/snapshots/test_init.ambr index af559f561b2..28b5ef7a7ed 100644 --- a/tests/components/tedee/snapshots/test_init.ambr +++ b/tests/components/tedee/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/tedee/snapshots/test_lock.ambr b/tests/components/tedee/snapshots/test_lock.ambr index cca988663d2..432c3ebd19f 100644 --- a/tests/components/tedee/snapshots/test_lock.ambr +++ b/tests/components/tedee/snapshots/test_lock.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -85,6 +87,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -132,6 +135,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tedee/snapshots/test_sensor.ambr b/tests/components/tedee/snapshots/test_sensor.ambr index 297fe9b0d37..22679c4153a 100644 --- a/tests/components/tedee/snapshots/test_sensor.ambr +++ b/tests/components/tedee/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/template/test_sensor.py b/tests/components/template/test_sensor.py index 3bf91549114..6f0e6be8a2a 100644 --- a/tests/components/template/test_sensor.py +++ b/tests/components/template/test_sensor.py @@ -24,7 +24,7 @@ from homeassistant.const import ( from homeassistant.core import Context, CoreState, HomeAssistant, State, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.entity_component import async_update_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import ATTR_COMPONENT, async_setup_component @@ -393,7 +393,7 @@ async def test_creating_sensor_loads_group(hass: HomeAssistant) -> None: async def async_setup_template( hass: HomeAssistant, config: ConfigType, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> bool: order.append("sensor.template") diff --git a/tests/components/tesla_fleet/snapshots/test_binary_sensor.ambr b/tests/components/tesla_fleet/snapshots/test_binary_sensor.ambr index 479d647e1c7..4e34f586280 100644 --- a/tests/components/tesla_fleet/snapshots/test_binary_sensor.ambr +++ b/tests/components/tesla_fleet/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -237,6 +242,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -284,6 +290,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -331,6 +338,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -377,6 +385,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -424,6 +433,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -471,6 +481,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -518,6 +529,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -565,6 +577,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -612,6 +625,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -658,6 +672,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -704,6 +719,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -751,6 +767,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -798,6 +815,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -845,6 +863,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -892,6 +911,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -938,6 +958,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -985,6 +1006,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1032,6 +1054,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1079,6 +1102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1126,6 +1150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1173,6 +1198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1219,6 +1245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_button.ambr b/tests/components/tesla_fleet/snapshots/test_button.ambr index 8b5270d4852..145b10112b3 100644 --- a/tests/components/tesla_fleet/snapshots/test_button.ambr +++ b/tests/components/tesla_fleet/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_climate.ambr b/tests/components/tesla_fleet/snapshots/test_climate.ambr index 696f8c37f08..f3b36730c3f 100644 --- a/tests/components/tesla_fleet/snapshots/test_climate.ambr +++ b/tests/components/tesla_fleet/snapshots/test_climate.ambr @@ -15,6 +15,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -85,6 +86,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +158,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -225,6 +228,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -296,6 +300,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +370,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_cover.ambr b/tests/components/tesla_fleet/snapshots/test_cover.ambr index dbdb003d802..ed6969262f1 100644 --- a/tests/components/tesla_fleet/snapshots/test_cover.ambr +++ b/tests/components/tesla_fleet/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -390,6 +398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -438,6 +447,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -486,6 +496,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +545,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -582,6 +594,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -630,6 +643,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -678,6 +692,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_device_tracker.ambr b/tests/components/tesla_fleet/snapshots/test_device_tracker.ambr index 02ad4b01002..dc142c4ffeb 100644 --- a/tests/components/tesla_fleet/snapshots/test_device_tracker.ambr +++ b/tests/components/tesla_fleet/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_init.ambr b/tests/components/tesla_fleet/snapshots/test_init.ambr index e9828db9f1b..c482d33de86 100644 --- a/tests/components/tesla_fleet/snapshots/test_init.ambr +++ b/tests/components/tesla_fleet/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -99,6 +102,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/tesla_fleet/snapshots/test_lock.ambr b/tests/components/tesla_fleet/snapshots/test_lock.ambr index 3384bb0eb97..e98ad09caad 100644 --- a/tests/components/tesla_fleet/snapshots/test_lock.ambr +++ b/tests/components/tesla_fleet/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_media_player.ambr b/tests/components/tesla_fleet/snapshots/test_media_player.ambr index cc3018364a5..77c46faedd7 100644 --- a/tests/components/tesla_fleet/snapshots/test_media_player.ambr +++ b/tests/components/tesla_fleet/snapshots/test_media_player.ambr @@ -7,6 +7,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -85,6 +86,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_number.ambr b/tests/components/tesla_fleet/snapshots/test_number.ambr index 00dd67015fe..1981544a024 100644 --- a/tests/components/tesla_fleet/snapshots/test_number.ambr +++ b/tests/components/tesla_fleet/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -184,6 +187,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_select.ambr b/tests/components/tesla_fleet/snapshots/test_select.ambr index f29ce841113..171b52decf1 100644 --- a/tests/components/tesla_fleet/snapshots/test_select.ambr +++ b/tests/components/tesla_fleet/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -186,6 +189,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -245,6 +249,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -304,6 +309,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -363,6 +369,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +429,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -481,6 +489,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -539,6 +548,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_sensor.ambr b/tests/components/tesla_fleet/snapshots/test_sensor.ambr index d6b646d7794..f7349c9e2d8 100644 --- a/tests/components/tesla_fleet/snapshots/test_sensor.ambr +++ b/tests/components/tesla_fleet/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -81,6 +82,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -154,6 +156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -227,6 +230,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -300,6 +304,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -373,6 +378,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -446,6 +452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -519,6 +526,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -592,6 +600,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -665,6 +674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -738,6 +748,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -811,6 +822,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -884,6 +896,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -957,6 +970,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1030,6 +1044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1103,6 +1118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1176,6 +1192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1249,6 +1266,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1322,6 +1340,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1395,6 +1414,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1468,6 +1488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1541,6 +1562,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1614,6 +1636,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1693,6 +1716,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1770,6 +1794,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1843,6 +1868,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1916,6 +1942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1986,6 +2013,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2059,6 +2087,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2132,6 +2161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2205,6 +2235,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2276,6 +2307,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2335,6 +2367,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2400,6 +2433,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2467,6 +2501,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2538,6 +2573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2599,6 +2635,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2669,6 +2706,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2739,6 +2777,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2806,6 +2845,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2873,6 +2913,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2947,6 +2988,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3026,6 +3068,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3096,6 +3139,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3166,6 +3210,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3237,6 +3282,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3298,6 +3344,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3371,6 +3418,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3441,6 +3489,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3514,6 +3563,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3584,6 +3634,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3654,6 +3705,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3726,6 +3778,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3801,6 +3854,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3871,6 +3925,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3936,6 +3991,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3997,6 +4053,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4060,6 +4117,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4133,6 +4191,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4206,6 +4265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4279,6 +4339,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4352,6 +4413,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4419,6 +4481,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4484,6 +4547,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4543,6 +4607,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4604,6 +4669,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4677,6 +4743,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4748,6 +4815,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4807,6 +4875,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4866,6 +4935,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4925,6 +4995,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tesla_fleet/snapshots/test_switch.ambr b/tests/components/tesla_fleet/snapshots/test_switch.ambr index 43d59a9da85..2ea3bcc5ee5 100644 --- a/tests/components/tesla_fleet/snapshots/test_switch.ambr +++ b/tests/components/tesla_fleet/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_binary_sensor.ambr b/tests/components/teslemetry/snapshots/test_binary_sensor.ambr index e90cc9ced55..6a6e9826dc2 100644 --- a/tests/components/teslemetry/snapshots/test_binary_sensor.ambr +++ b/tests/components/teslemetry/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -329,6 +336,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -375,6 +383,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -421,6 +430,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -467,6 +477,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -514,6 +525,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -561,6 +573,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -607,6 +620,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -653,6 +667,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -700,6 +715,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -746,6 +762,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -792,6 +809,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -838,6 +856,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -884,6 +903,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -930,6 +950,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -976,6 +997,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1022,6 +1044,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1069,6 +1092,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1116,6 +1140,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1163,6 +1188,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1210,6 +1236,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1257,6 +1284,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1303,6 +1331,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1349,6 +1378,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1395,6 +1425,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1441,6 +1472,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1487,6 +1519,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1533,6 +1566,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1579,6 +1613,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1625,6 +1660,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1672,6 +1708,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1719,6 +1756,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1766,6 +1804,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1813,6 +1852,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1859,6 +1899,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1905,6 +1946,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1951,6 +1993,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1998,6 +2041,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2044,6 +2088,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2091,6 +2136,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2138,6 +2184,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2185,6 +2232,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2232,6 +2280,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2278,6 +2327,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2325,6 +2375,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_button.ambr b/tests/components/teslemetry/snapshots/test_button.ambr index 6d3016186ae..e4e20215020 100644 --- a/tests/components/teslemetry/snapshots/test_button.ambr +++ b/tests/components/teslemetry/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_climate.ambr b/tests/components/teslemetry/snapshots/test_climate.ambr index 7064309e98b..4c265c00cb8 100644 --- a/tests/components/teslemetry/snapshots/test_climate.ambr +++ b/tests/components/teslemetry/snapshots/test_climate.ambr @@ -21,6 +21,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -91,6 +92,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +164,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -231,6 +234,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -300,6 +304,7 @@ 'target_temp_step': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -339,6 +344,7 @@ 'min_temp': 15.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_cover.ambr b/tests/components/teslemetry/snapshots/test_cover.ambr index 8364f2a6a6e..9548a911cf9 100644 --- a/tests/components/teslemetry/snapshots/test_cover.ambr +++ b/tests/components/teslemetry/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +300,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -342,6 +349,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -390,6 +398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -438,6 +447,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -486,6 +496,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -534,6 +545,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -582,6 +594,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -630,6 +643,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_device_tracker.ambr b/tests/components/teslemetry/snapshots/test_device_tracker.ambr index 0bc371b2d2d..b9e381ee42d 100644 --- a/tests/components/teslemetry/snapshots/test_device_tracker.ambr +++ b/tests/components/teslemetry/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_init.ambr b/tests/components/teslemetry/snapshots/test_init.ambr index 7d60ed82859..f1011034d63 100644 --- a/tests/components/teslemetry/snapshots/test_init.ambr +++ b/tests/components/teslemetry/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://teslemetry.com/console', 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://teslemetry.com/console', 'connections': set({ }), @@ -67,6 +69,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://teslemetry.com/console', 'connections': set({ }), @@ -99,6 +102,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://teslemetry.com/console', 'connections': set({ }), diff --git a/tests/components/teslemetry/snapshots/test_lock.ambr b/tests/components/teslemetry/snapshots/test_lock.ambr index bb5693fe3ab..d6b29f0d7d4 100644 --- a/tests/components/teslemetry/snapshots/test_lock.ambr +++ b/tests/components/teslemetry/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_media_player.ambr b/tests/components/teslemetry/snapshots/test_media_player.ambr index a9d2569c637..663e91a502c 100644 --- a/tests/components/teslemetry/snapshots/test_media_player.ambr +++ b/tests/components/teslemetry/snapshots/test_media_player.ambr @@ -7,6 +7,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -84,6 +85,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_number.ambr b/tests/components/teslemetry/snapshots/test_number.ambr index 8e8f10397d0..5ca9feb22f2 100644 --- a/tests/components/teslemetry/snapshots/test_number.ambr +++ b/tests/components/teslemetry/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -184,6 +187,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_select.ambr b/tests/components/teslemetry/snapshots/test_select.ambr index 90af1259273..755a1a82c41 100644 --- a/tests/components/teslemetry/snapshots/test_select.ambr +++ b/tests/components/teslemetry/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -186,6 +189,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -245,6 +249,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -304,6 +309,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -363,6 +369,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -421,6 +428,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_sensor.ambr b/tests/components/teslemetry/snapshots/test_sensor.ambr index 6439e74eecc..c5d98abc95c 100644 --- a/tests/components/teslemetry/snapshots/test_sensor.ambr +++ b/tests/components/teslemetry/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -81,6 +82,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -154,6 +156,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -227,6 +230,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -300,6 +304,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -373,6 +378,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -446,6 +452,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -519,6 +526,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -592,6 +600,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -665,6 +674,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -738,6 +748,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -811,6 +822,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -884,6 +896,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -957,6 +970,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1030,6 +1044,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1103,6 +1118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1176,6 +1192,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1249,6 +1266,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1322,6 +1340,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1395,6 +1414,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1468,6 +1488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1541,6 +1562,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1614,6 +1636,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1687,6 +1710,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1766,6 +1790,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1843,6 +1868,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1916,6 +1942,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1986,6 +2013,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2059,6 +2087,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2132,6 +2161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2205,6 +2235,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2276,6 +2307,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2335,6 +2367,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2400,6 +2433,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2470,6 +2504,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2541,6 +2576,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2602,6 +2638,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2672,6 +2709,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2742,6 +2780,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2809,6 +2848,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2876,6 +2916,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2950,6 +2991,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3029,6 +3071,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3099,6 +3142,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3169,6 +3213,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3240,6 +3285,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3301,6 +3347,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3374,6 +3421,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3444,6 +3492,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3517,6 +3566,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3587,6 +3637,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3657,6 +3708,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3729,6 +3781,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3804,6 +3857,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3874,6 +3928,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3939,6 +3994,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4000,6 +4056,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4063,6 +4120,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4136,6 +4194,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4209,6 +4268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4282,6 +4342,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4355,6 +4416,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4422,6 +4484,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4487,6 +4550,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4546,6 +4610,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4607,6 +4672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4680,6 +4746,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4751,6 +4818,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4810,6 +4878,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4869,6 +4938,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -4928,6 +4998,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_switch.ambr b/tests/components/teslemetry/snapshots/test_switch.ambr index b34d9c65393..f9997133044 100644 --- a/tests/components/teslemetry/snapshots/test_switch.ambr +++ b/tests/components/teslemetry/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/teslemetry/snapshots/test_update.ambr b/tests/components/teslemetry/snapshots/test_update.ambr index 2411d047135..1c7d525af86 100644 --- a/tests/components/teslemetry/snapshots/test_update.ambr +++ b/tests/components/teslemetry/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_binary_sensor.ambr b/tests/components/tessie/snapshots/test_binary_sensor.ambr index 6c0da044df2..2fe97b88811 100644 --- a/tests/components/tessie/snapshots/test_binary_sensor.ambr +++ b/tests/components/tessie/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +288,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -328,6 +335,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -375,6 +383,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +431,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -469,6 +479,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -516,6 +527,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -563,6 +575,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -610,6 +623,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -657,6 +671,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -704,6 +719,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -751,6 +767,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -798,6 +815,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -844,6 +862,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -891,6 +910,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -938,6 +958,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -985,6 +1006,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1032,6 +1054,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1078,6 +1101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1125,6 +1149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1172,6 +1197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1219,6 +1245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1266,6 +1293,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1313,6 +1341,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1359,6 +1388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_button.ambr b/tests/components/tessie/snapshots/test_button.ambr index 7757d1f2fea..96ece94a1c9 100644 --- a/tests/components/tessie/snapshots/test_button.ambr +++ b/tests/components/tessie/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_climate.ambr b/tests/components/tessie/snapshots/test_climate.ambr index 959b42cea53..415988e783e 100644 --- a/tests/components/tessie/snapshots/test_climate.ambr +++ b/tests/components/tessie/snapshots/test_climate.ambr @@ -19,6 +19,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_cover.ambr b/tests/components/tessie/snapshots/test_cover.ambr index 6338758afb7..fdf2a967048 100644 --- a/tests/components/tessie/snapshots/test_cover.ambr +++ b/tests/components/tessie/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_device_tracker.ambr b/tests/components/tessie/snapshots/test_device_tracker.ambr index 61f89db8637..92502340aa2 100644 --- a/tests/components/tessie/snapshots/test_device_tracker.ambr +++ b/tests/components/tessie/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_lock.ambr b/tests/components/tessie/snapshots/test_lock.ambr index cea2bebbddb..f819281d79b 100644 --- a/tests/components/tessie/snapshots/test_lock.ambr +++ b/tests/components/tessie/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_media_player.ambr b/tests/components/tessie/snapshots/test_media_player.ambr index 6c355c8ddca..911598004a6 100644 --- a/tests/components/tessie/snapshots/test_media_player.ambr +++ b/tests/components/tessie/snapshots/test_media_player.ambr @@ -7,6 +7,7 @@ 'capabilities': dict({ }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_number.ambr b/tests/components/tessie/snapshots/test_number.ambr index 6e641bdf5b7..0e43695ca78 100644 --- a/tests/components/tessie/snapshots/test_number.ambr +++ b/tests/components/tessie/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -184,6 +187,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +245,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_select.ambr b/tests/components/tessie/snapshots/test_select.ambr index acc1946aab5..f118633aded 100644 --- a/tests/components/tessie/snapshots/test_select.ambr +++ b/tests/components/tessie/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -127,6 +129,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -186,6 +189,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -245,6 +249,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -304,6 +309,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -363,6 +369,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -422,6 +429,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -481,6 +489,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_sensor.ambr b/tests/components/tessie/snapshots/test_sensor.ambr index 0a5ff4603aa..5465f89d808 100644 --- a/tests/components/tessie/snapshots/test_sensor.ambr +++ b/tests/components/tessie/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -122,6 +124,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +240,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -293,6 +298,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -350,6 +356,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -404,6 +411,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -461,6 +469,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -516,6 +525,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -566,6 +576,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -617,6 +628,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -674,6 +686,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -731,6 +744,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -788,6 +802,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -842,6 +857,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -896,6 +912,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -947,6 +964,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -998,6 +1016,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1056,6 +1075,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1111,6 +1131,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1159,6 +1180,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1213,6 +1235,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1267,6 +1290,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1321,6 +1345,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1378,6 +1403,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1432,6 +1458,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1486,6 +1513,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1542,6 +1570,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1597,6 +1626,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1651,6 +1681,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1700,6 +1731,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1747,6 +1779,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1796,6 +1829,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1853,6 +1887,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1910,6 +1945,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1967,6 +2003,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2024,6 +2061,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2075,6 +2113,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2132,6 +2171,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2200,6 +2240,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2272,6 +2313,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2331,6 +2373,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2377,6 +2420,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_switch.ambr b/tests/components/tessie/snapshots/test_switch.ambr index 35e36010830..371ef822122 100644 --- a/tests/components/tessie/snapshots/test_switch.ambr +++ b/tests/components/tessie/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -145,6 +148,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -192,6 +196,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +244,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -286,6 +292,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tessie/snapshots/test_update.ambr b/tests/components/tessie/snapshots/test_update.ambr index 1728c13b0ad..e4c25e2230f 100644 --- a/tests/components/tessie/snapshots/test_update.ambr +++ b/tests/components/tessie/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tibber/test_statistics.py b/tests/components/tibber/test_statistics.py index d817c9612aa..845df86a88c 100644 --- a/tests/components/tibber/test_statistics.py +++ b/tests/components/tibber/test_statistics.py @@ -10,10 +10,13 @@ from homeassistant.util import dt as dt_util from .test_common import CONSUMPTION_DATA_1, PRODUCTION_DATA_1, mock_get_homes +from tests.common import MockConfigEntry from tests.components.recorder.common import async_wait_recording_done -async def test_async_setup_entry(recorder_mock: Recorder, hass: HomeAssistant) -> None: +async def test_async_setup_entry( + recorder_mock: Recorder, hass: HomeAssistant, config_entry: MockConfigEntry +) -> None: """Test setup Tibber.""" tibber_connection = AsyncMock() tibber_connection.name = "tibber" @@ -21,7 +24,7 @@ async def test_async_setup_entry(recorder_mock: Recorder, hass: HomeAssistant) - tibber_connection.fetch_production_data_active_homes.return_value = None tibber_connection.get_homes = mock_get_homes - coordinator = TibberDataCoordinator(hass, tibber_connection) + coordinator = TibberDataCoordinator(hass, config_entry, tibber_connection) await coordinator._async_update_data() await async_wait_recording_done(hass) diff --git a/tests/components/tile/snapshots/test_binary_sensor.ambr b/tests/components/tile/snapshots/test_binary_sensor.ambr index 5f72f53fa1e..6de356ebf51 100644 --- a/tests/components/tile/snapshots/test_binary_sensor.ambr +++ b/tests/components/tile/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tile/snapshots/test_device_tracker.ambr b/tests/components/tile/snapshots/test_device_tracker.ambr index 15108331e66..f5de1511c99 100644 --- a/tests/components/tile/snapshots/test_device_tracker.ambr +++ b/tests/components/tile/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tile/snapshots/test_init.ambr b/tests/components/tile/snapshots/test_init.ambr index 90f165d1e6e..ffdf6a6251a 100644 --- a/tests/components/tile/snapshots/test_init.ambr +++ b/tests/components/tile/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/todo/__init__.py b/tests/components/todo/__init__.py index 0138e561fad..53772ab144e 100644 --- a/tests/components/todo/__init__.py +++ b/tests/components/todo/__init__.py @@ -3,7 +3,7 @@ from homeassistant.components.todo import DOMAIN, TodoItem, TodoListEntity from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import MockConfigEntry, MockPlatform, mock_platform @@ -44,7 +44,7 @@ async def create_mock_platform( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test event platform via config entry.""" async_add_entities(entities) diff --git a/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr b/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr index ef7cb386b33..a63319a6c76 100644 --- a/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr +++ b/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/totalconnect/snapshots/test_binary_sensor.ambr b/tests/components/totalconnect/snapshots/test_binary_sensor.ambr index 1eccff1dfc3..ac79455a0d5 100644 --- a/tests/components/totalconnect/snapshots/test_binary_sensor.ambr +++ b/tests/components/totalconnect/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -156,6 +159,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -206,6 +210,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -256,6 +261,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -306,6 +312,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -356,6 +363,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -406,6 +414,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -456,6 +465,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -506,6 +516,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -556,6 +567,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -606,6 +618,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -656,6 +669,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -706,6 +720,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -756,6 +771,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -806,6 +822,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -854,6 +871,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -902,6 +920,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -949,6 +968,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -997,6 +1017,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1045,6 +1066,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1093,6 +1115,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1143,6 +1166,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1193,6 +1217,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/totalconnect/snapshots/test_button.ambr b/tests/components/totalconnect/snapshots/test_button.ambr index af3318591c6..96d38567236 100644 --- a/tests/components/totalconnect/snapshots/test_button.ambr +++ b/tests/components/totalconnect/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_binary_sensor.ambr b/tests/components/tplink/snapshots/test_binary_sensor.ambr index 125592b053c..17aa2c248e5 100644 --- a/tests/components/tplink/snapshots/test_binary_sensor.ambr +++ b/tests/components/tplink/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -39,6 +40,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -86,6 +88,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -133,6 +136,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -166,6 +170,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -213,6 +218,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -260,6 +266,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -307,6 +314,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -354,6 +362,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -384,6 +393,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tplink/snapshots/test_button.ambr b/tests/components/tplink/snapshots/test_button.ambr index c0c74e11923..bb4e9f85d58 100644 --- a/tests/components/tplink/snapshots/test_button.ambr +++ b/tests/components/tplink/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -177,6 +181,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -210,6 +215,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -243,6 +249,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -276,6 +283,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -309,6 +317,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -342,6 +351,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -388,6 +398,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -434,6 +445,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -480,6 +492,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -526,6 +539,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -556,6 +570,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tplink/snapshots/test_camera.ambr b/tests/components/tplink/snapshots/test_camera.ambr index 4417395078a..e037c2c9e40 100644 --- a/tests/components/tplink/snapshots/test_camera.ambr +++ b/tests/components/tplink/snapshots/test_camera.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tplink/snapshots/test_climate.ambr b/tests/components/tplink/snapshots/test_climate.ambr index e0173e8f59e..02492de92b9 100644 --- a/tests/components/tplink/snapshots/test_climate.ambr +++ b/tests/components/tplink/snapshots/test_climate.ambr @@ -13,6 +13,7 @@ 'min_temp': 5, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/tplink/snapshots/test_fan.ambr b/tests/components/tplink/snapshots/test_fan.ambr index 1a7392dc63a..9c395dc2f21 100644 --- a/tests/components/tplink/snapshots/test_fan.ambr +++ b/tests/components/tplink/snapshots/test_fan.ambr @@ -8,6 +8,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -61,6 +62,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -114,6 +116,7 @@ 'preset_modes': None, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +165,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( diff --git a/tests/components/tplink/snapshots/test_number.ambr b/tests/components/tplink/snapshots/test_number.ambr index 4bdb92aeab6..0415039a0ce 100644 --- a/tests/components/tplink/snapshots/test_number.ambr +++ b/tests/components/tplink/snapshots/test_number.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -47,6 +48,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -157,6 +160,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -267,6 +272,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -322,6 +328,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -377,6 +384,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -432,6 +440,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_select.ambr b/tests/components/tplink/snapshots/test_select.ambr index c851979f34c..e5191937ee9 100644 --- a/tests/components/tplink/snapshots/test_select.ambr +++ b/tests/components/tplink/snapshots/test_select.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -64,6 +65,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -137,6 +139,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +197,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_sensor.ambr b/tests/components/tplink/snapshots/test_sensor.ambr index 093b92ef315..72198e579a1 100644 --- a/tests/components/tplink/snapshots/test_sensor.ambr +++ b/tests/components/tplink/snapshots/test_sensor.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -42,6 +43,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -75,6 +77,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +127,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -173,6 +177,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -209,6 +214,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -247,6 +253,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -301,6 +308,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -334,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -387,6 +396,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -441,6 +451,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -493,6 +504,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -541,6 +553,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -602,6 +615,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -638,6 +652,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -676,6 +691,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -725,6 +741,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -758,6 +775,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -796,6 +814,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -832,6 +851,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -879,6 +899,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -915,6 +936,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -951,6 +973,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -984,6 +1007,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1017,6 +1041,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1053,6 +1078,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1089,6 +1115,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1125,6 +1152,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1163,6 +1191,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1212,6 +1241,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1245,6 +1275,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1280,6 +1311,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1315,6 +1347,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1369,6 +1402,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1423,6 +1457,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1461,6 +1496,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1496,6 +1532,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': , @@ -1534,6 +1571,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1588,6 +1626,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_siren.ambr b/tests/components/tplink/snapshots/test_siren.ambr index 7141ccfa084..7365e449707 100644 --- a/tests/components/tplink/snapshots/test_siren.ambr +++ b/tests/components/tplink/snapshots/test_siren.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -47,6 +48,7 @@ ), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_switch.ambr b/tests/components/tplink/snapshots/test_switch.ambr index f22f8d0cd36..bd89da8e841 100644 --- a/tests/components/tplink/snapshots/test_switch.ambr +++ b/tests/components/tplink/snapshots/test_switch.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -42,6 +43,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -88,6 +90,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -134,6 +137,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -180,6 +184,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -226,6 +231,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -272,6 +278,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -318,6 +325,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -364,6 +372,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -410,6 +419,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -456,6 +466,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -502,6 +513,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -548,6 +560,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -594,6 +607,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink/snapshots/test_vacuum.ambr b/tests/components/tplink/snapshots/test_vacuum.ambr index c0a48327e26..e010c9545d1 100644 --- a/tests/components/tplink/snapshots/test_vacuum.ambr +++ b/tests/components/tplink/snapshots/test_vacuum.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ tuple( @@ -47,6 +48,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink_omada/snapshots/test_sensor.ambr b/tests/components/tplink_omada/snapshots/test_sensor.ambr index 6c332eb9696..62167fc9d40 100644 --- a/tests/components/tplink_omada/snapshots/test_sensor.ambr +++ b/tests/components/tplink_omada/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +126,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -174,6 +177,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -232,6 +236,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +295,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tplink_omada/snapshots/test_switch.ambr b/tests/components/tplink_omada/snapshots/test_switch.ambr index a13d386e721..dde196deaaf 100644 --- a/tests/components/tplink_omada/snapshots/test_switch.ambr +++ b/tests/components/tplink_omada/snapshots/test_switch.ambr @@ -71,6 +71,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -117,6 +118,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tractive/snapshots/test_binary_sensor.ambr b/tests/components/tractive/snapshots/test_binary_sensor.ambr index 4b610e927d5..761626347a7 100644 --- a/tests/components/tractive/snapshots/test_binary_sensor.ambr +++ b/tests/components/tractive/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tractive/snapshots/test_device_tracker.ambr b/tests/components/tractive/snapshots/test_device_tracker.ambr index 4e7c5bfe173..ef511299e68 100644 --- a/tests/components/tractive/snapshots/test_device_tracker.ambr +++ b/tests/components/tractive/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tractive/snapshots/test_diagnostics.ambr b/tests/components/tractive/snapshots/test_diagnostics.ambr index 11427a84801..3613f7e5997 100644 --- a/tests/components/tractive/snapshots/test_diagnostics.ambr +++ b/tests/components/tractive/snapshots/test_diagnostics.ambr @@ -17,6 +17,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': 'very_unique_string', 'version': 1, diff --git a/tests/components/tractive/snapshots/test_sensor.ambr b/tests/components/tractive/snapshots/test_sensor.ambr index f10cfb29226..4551492e36e 100644 --- a/tests/components/tractive/snapshots/test_sensor.ambr +++ b/tests/components/tractive/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -116,6 +118,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -164,6 +167,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -213,6 +217,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -313,6 +319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -367,6 +374,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -419,6 +427,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -475,6 +484,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tractive/snapshots/test_switch.ambr b/tests/components/tractive/snapshots/test_switch.ambr index 08e0c984d0c..d443611ef92 100644 --- a/tests/components/tractive/snapshots/test_switch.ambr +++ b/tests/components/tractive/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/tts/common.py b/tests/components/tts/common.py index b1eae12d694..921cab4cba2 100644 --- a/tests/components/tts/common.py +++ b/tests/components/tts/common.py @@ -24,7 +24,7 @@ from homeassistant.components.tts import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import async_setup_component @@ -249,7 +249,7 @@ async def mock_config_entry_setup( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test tts platform via config entry.""" async_add_entities([tts_entity]) diff --git a/tests/components/tuya/snapshots/test_config_flow.ambr b/tests/components/tuya/snapshots/test_config_flow.ambr index a5a68a12a22..90d83d69814 100644 --- a/tests/components/tuya/snapshots/test_config_flow.ambr +++ b/tests/components/tuya/snapshots/test_config_flow.ambr @@ -24,6 +24,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '12345', 'unique_id': '12345', 'version': 1, @@ -54,6 +56,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Old Tuya configuration entry', 'unique_id': '12345', 'version': 1, @@ -107,10 +111,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'mocked_username', 'unique_id': None, 'version': 1, }), + 'subentries': tuple( + ), 'title': 'mocked_username', 'type': , 'version': 1, diff --git a/tests/components/twentemilieu/snapshots/test_calendar.ambr b/tests/components/twentemilieu/snapshots/test_calendar.ambr index 1df4beb4232..0576fcd6a70 100644 --- a/tests/components/twentemilieu/snapshots/test_calendar.ambr +++ b/tests/components/twentemilieu/snapshots/test_calendar.ambr @@ -51,6 +51,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -81,6 +82,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), diff --git a/tests/components/twentemilieu/snapshots/test_sensor.ambr b/tests/components/twentemilieu/snapshots/test_sensor.ambr index 86ffc171082..b40ac0ba9e6 100644 --- a/tests/components/twentemilieu/snapshots/test_sensor.ambr +++ b/tests/components/twentemilieu/snapshots/test_sensor.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -129,6 +132,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), @@ -178,6 +182,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +213,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), @@ -257,6 +263,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -287,6 +294,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), @@ -336,6 +344,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -366,6 +375,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://www.twentemilieu.nl', 'connections': set({ }), diff --git a/tests/components/twinkly/snapshots/test_diagnostics.ambr b/tests/components/twinkly/snapshots/test_diagnostics.ambr index 814dc7dfc1f..511bf9addd3 100644 --- a/tests/components/twinkly/snapshots/test_diagnostics.ambr +++ b/tests/components/twinkly/snapshots/test_diagnostics.ambr @@ -69,6 +69,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Twinkly', 'unique_id': '00:2d:13:3b:aa:bb', 'version': 1, diff --git a/tests/components/twinkly/snapshots/test_light.ambr b/tests/components/twinkly/snapshots/test_light.ambr index a97c3f941ff..77a97a0cdd9 100644 --- a/tests/components/twinkly/snapshots/test_light.ambr +++ b/tests/components/twinkly/snapshots/test_light.ambr @@ -14,6 +14,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/twinkly/snapshots/test_select.ambr b/tests/components/twinkly/snapshots/test_select.ambr index 21e09d6b022..26edd4b731d 100644 --- a/tests/components/twinkly/snapshots/test_select.ambr +++ b/tests/components/twinkly/snapshots/test_select.ambr @@ -16,6 +16,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_button.ambr b/tests/components/unifi/snapshots/test_button.ambr index 3729bd31cf0..369b0823063 100644 --- a/tests/components/unifi/snapshots/test_button.ambr +++ b/tests/components/unifi/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_device_tracker.ambr b/tests/components/unifi/snapshots/test_device_tracker.ambr index 3debd512050..5d3407e4e8e 100644 --- a/tests/components/unifi/snapshots/test_device_tracker.ambr +++ b/tests/components/unifi/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -55,6 +56,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -104,6 +106,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_diagnostics.ambr b/tests/components/unifi/snapshots/test_diagnostics.ambr index 4ba90a00113..aa7337be0ba 100644 --- a/tests/components/unifi/snapshots/test_diagnostics.ambr +++ b/tests/components/unifi/snapshots/test_diagnostics.ambr @@ -42,6 +42,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': '1', 'version': 1, diff --git a/tests/components/unifi/snapshots/test_image.ambr b/tests/components/unifi/snapshots/test_image.ambr index 32e1a5ff622..05cca2c305b 100644 --- a/tests/components/unifi/snapshots/test_image.ambr +++ b/tests/components/unifi/snapshots/test_image.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_sensor.ambr b/tests/components/unifi/snapshots/test_sensor.ambr index e14658b2b96..4d109f630c5 100644 --- a/tests/components/unifi/snapshots/test_sensor.ambr +++ b/tests/components/unifi/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -70,6 +71,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -131,6 +133,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -179,6 +182,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -228,6 +232,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -282,6 +287,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -336,6 +342,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -385,6 +392,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -435,6 +443,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -485,6 +494,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -549,6 +559,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -610,6 +621,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -659,6 +671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -708,6 +721,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -759,6 +773,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -810,6 +825,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -861,6 +877,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -912,6 +929,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -963,6 +981,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1014,6 +1033,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1065,6 +1085,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1119,6 +1140,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1173,6 +1195,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1224,6 +1247,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1278,6 +1302,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1332,6 +1357,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1386,6 +1412,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1440,6 +1467,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1491,6 +1519,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1545,6 +1574,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1612,6 +1642,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1673,6 +1704,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1722,6 +1754,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1771,6 +1804,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1822,6 +1856,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1871,6 +1906,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1920,6 +1956,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1971,6 +2008,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2020,6 +2058,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_switch.ambr b/tests/components/unifi/snapshots/test_switch.ambr index 45e6188a3f4..c07a4799b5a 100644 --- a/tests/components/unifi/snapshots/test_switch.ambr +++ b/tests/components/unifi/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -99,6 +101,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +245,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -287,6 +293,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -334,6 +341,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -381,6 +389,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -428,6 +437,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -475,6 +485,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/unifi/snapshots/test_update.ambr b/tests/components/unifi/snapshots/test_update.ambr index 405cb9d52a6..ef3803ac53d 100644 --- a/tests/components/unifi/snapshots/test_update.ambr +++ b/tests/components/unifi/snapshots/test_update.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -124,6 +126,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -183,6 +186,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/update/test_init.py b/tests/components/update/test_init.py index d4916de8039..f3eb3f9344c 100644 --- a/tests/components/update/test_init.py +++ b/tests/components/update/test_init.py @@ -43,7 +43,7 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.event import async_track_state_change_event from homeassistant.setup import async_setup_component @@ -857,7 +857,7 @@ async def test_name(hass: HomeAssistant) -> None: async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test update platform via config entry.""" async_add_entities([entity1, entity2, entity3, entity4]) diff --git a/tests/components/uptime/snapshots/test_config_flow.ambr b/tests/components/uptime/snapshots/test_config_flow.ambr index 38312667375..93b1da60998 100644 --- a/tests/components/uptime/snapshots/test_config_flow.ambr +++ b/tests/components/uptime/snapshots/test_config_flow.ambr @@ -27,10 +27,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Uptime', 'unique_id': None, 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Uptime', 'type': , 'version': 1, diff --git a/tests/components/uptime/snapshots/test_sensor.ambr b/tests/components/uptime/snapshots/test_sensor.ambr index 561e4b83320..d6d896dbcec 100644 --- a/tests/components/uptime/snapshots/test_sensor.ambr +++ b/tests/components/uptime/snapshots/test_sensor.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -49,6 +50,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/utility_meter/snapshots/test_diagnostics.ambr b/tests/components/utility_meter/snapshots/test_diagnostics.ambr index 6cdf121d7e3..ef235bba99d 100644 --- a/tests/components/utility_meter/snapshots/test_diagnostics.ambr +++ b/tests/components/utility_meter/snapshots/test_diagnostics.ambr @@ -25,6 +25,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Energy Bill', 'unique_id': None, 'version': 2, diff --git a/tests/components/v2c/snapshots/test_diagnostics.ambr b/tests/components/v2c/snapshots/test_diagnostics.ambr index 96567b80c54..780a00acd64 100644 --- a/tests/components/v2c/snapshots/test_diagnostics.ambr +++ b/tests/components/v2c/snapshots/test_diagnostics.ambr @@ -16,6 +16,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': 'ABC123', 'version': 1, diff --git a/tests/components/v2c/snapshots/test_sensor.ambr b/tests/components/v2c/snapshots/test_sensor.ambr index 7b9ae4a9ff3..46054b21324 100644 --- a/tests/components/v2c/snapshots/test_sensor.ambr +++ b/tests/components/v2c/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -312,6 +318,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -396,6 +403,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -482,6 +490,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -533,6 +542,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -580,6 +590,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vacuum/conftest.py b/tests/components/vacuum/conftest.py index 6e6639431d0..2c700daece0 100644 --- a/tests/components/vacuum/conftest.py +++ b/tests/components/vacuum/conftest.py @@ -9,7 +9,7 @@ from homeassistant.components.vacuum import DOMAIN as VACUUM_DOMAIN, VacuumEntit from homeassistant.config_entries import ConfigEntry, ConfigFlow from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er, frame -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import MockVacuum @@ -87,7 +87,7 @@ async def setup_vacuum_platform_test_entity( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test vacuum platform via config entry.""" async_add_entities([entity]) diff --git a/tests/components/valve/test_init.py b/tests/components/valve/test_init.py index d8eb38a3b9b..a26f88f6982 100644 --- a/tests/components/valve/test_init.py +++ b/tests/components/valve/test_init.py @@ -22,7 +22,7 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -174,7 +174,7 @@ def mock_config_entry(hass: HomeAssistant) -> tuple[MockConfigEntry, list[ValveE async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test platform via config entry.""" async_add_entities(entities) diff --git a/tests/components/velbus/snapshots/test_binary_sensor.ambr b/tests/components/velbus/snapshots/test_binary_sensor.ambr index 58630b9f6c9..70db53257a1 100644 --- a/tests/components/velbus/snapshots/test_binary_sensor.ambr +++ b/tests/components/velbus/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_button.ambr b/tests/components/velbus/snapshots/test_button.ambr index 952af21b43c..856ebdb1e21 100644 --- a/tests/components/velbus/snapshots/test_button.ambr +++ b/tests/components/velbus/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_climate.ambr b/tests/components/velbus/snapshots/test_climate.ambr index b1933e51868..1d1f49d14d9 100644 --- a/tests/components/velbus/snapshots/test_climate.ambr +++ b/tests/components/velbus/snapshots/test_climate.ambr @@ -19,6 +19,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_cover.ambr b/tests/components/velbus/snapshots/test_cover.ambr index a9cbd4aae73..0be18034bc0 100644 --- a/tests/components/velbus/snapshots/test_cover.ambr +++ b/tests/components/velbus/snapshots/test_cover.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_diagnostics.ambr b/tests/components/velbus/snapshots/test_diagnostics.ambr index 406a5f2d84e..c8bff1841e8 100644 --- a/tests/components/velbus/snapshots/test_diagnostics.ambr +++ b/tests/components/velbus/snapshots/test_diagnostics.ambr @@ -16,6 +16,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 2, diff --git a/tests/components/velbus/snapshots/test_init.ambr b/tests/components/velbus/snapshots/test_init.ambr index a55a00ef0f2..1e17753a02f 100644 --- a/tests/components/velbus/snapshots/test_init.ambr +++ b/tests/components/velbus/snapshots/test_init.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -34,6 +35,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -64,6 +66,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -94,6 +97,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -124,6 +128,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -154,6 +159,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -184,6 +190,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -214,6 +221,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/velbus/snapshots/test_light.ambr b/tests/components/velbus/snapshots/test_light.ambr index b7009a0c66a..6dd2ca4939d 100644 --- a/tests/components/velbus/snapshots/test_light.ambr +++ b/tests/components/velbus/snapshots/test_light.ambr @@ -10,6 +10,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_select.ambr b/tests/components/velbus/snapshots/test_select.ambr index 288eb10a3c3..94bb109fc71 100644 --- a/tests/components/velbus/snapshots/test_select.ambr +++ b/tests/components/velbus/snapshots/test_select.ambr @@ -13,6 +13,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_sensor.ambr b/tests/components/velbus/snapshots/test_sensor.ambr index 6860ad73e2c..6f562f399af 100644 --- a/tests/components/velbus/snapshots/test_sensor.ambr +++ b/tests/components/velbus/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -211,6 +215,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/velbus/snapshots/test_switch.ambr b/tests/components/velbus/snapshots/test_switch.ambr index e9090c396d1..60458b196a8 100644 --- a/tests/components/velbus/snapshots/test_switch.ambr +++ b/tests/components/velbus/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vesync/snapshots/test_fan.ambr b/tests/components/vesync/snapshots/test_fan.ambr index fddc75630d2..0b56a08eeff 100644 --- a/tests/components/vesync/snapshots/test_fan.ambr +++ b/tests/components/vesync/snapshots/test_fan.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -46,6 +47,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -96,6 +98,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -137,6 +140,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -193,6 +197,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -235,6 +240,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -292,6 +298,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -334,6 +341,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -391,6 +399,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -429,6 +438,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -467,6 +477,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -505,6 +516,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -543,6 +555,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -581,6 +594,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -625,6 +639,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -684,6 +699,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -722,6 +738,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/vesync/snapshots/test_light.ambr b/tests/components/vesync/snapshots/test_light.ambr index b89cf8cdd4d..bed711b1040 100644 --- a/tests/components/vesync/snapshots/test_light.ambr +++ b/tests/components/vesync/snapshots/test_light.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -42,6 +43,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -80,6 +82,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -118,6 +121,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -156,6 +160,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -197,6 +202,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +252,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -287,6 +294,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -338,6 +346,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -376,6 +385,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -414,6 +424,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -452,6 +463,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -490,6 +502,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -535,6 +548,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -595,6 +609,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/vesync/snapshots/test_sensor.ambr b/tests/components/vesync/snapshots/test_sensor.ambr index ca7a5cf3ea6..c701fa8a324 100644 --- a/tests/components/vesync/snapshots/test_sensor.ambr +++ b/tests/components/vesync/snapshots/test_sensor.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -43,6 +44,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -74,6 +76,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -134,6 +137,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -173,6 +177,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -220,6 +225,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -259,6 +265,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +297,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -323,6 +331,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -399,6 +408,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -438,6 +448,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -469,6 +480,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -502,6 +514,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -578,6 +591,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -616,6 +630,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -654,6 +669,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -693,6 +709,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -741,6 +758,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -780,6 +798,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -828,6 +847,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -867,6 +887,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -900,6 +921,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -933,6 +955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -966,6 +989,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -999,6 +1023,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1032,6 +1057,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1160,6 +1186,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1198,6 +1225,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -1236,6 +1264,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/vesync/snapshots/test_switch.ambr b/tests/components/vesync/snapshots/test_switch.ambr index a736f1cd186..1faed941338 100644 --- a/tests/components/vesync/snapshots/test_switch.ambr +++ b/tests/components/vesync/snapshots/test_switch.ambr @@ -4,6 +4,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -42,6 +43,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -80,6 +82,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -118,6 +121,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -156,6 +160,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -194,6 +199,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -232,6 +238,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -270,6 +277,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -308,6 +316,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -345,6 +354,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -391,6 +401,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -429,6 +440,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -467,6 +479,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -504,6 +517,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/fixtures/RoomSensor1.json b/tests/components/vicare/fixtures/RoomSensor1.json index b970e54a48c..6c2f38db8d1 100644 --- a/tests/components/vicare/fixtures/RoomSensor1.json +++ b/tests/components/vicare/fixtures/RoomSensor1.json @@ -51,6 +51,24 @@ "timestamp": "2024-03-01T04:40:59.911Z", "uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/zigbee-d87a3bfffe5d844a/features/device.name" }, + { + "apiVersion": 1, + "commands": {}, + "deviceId": "zigbee-d87a3bfffe5d844a", + "feature": "device.power.battery", + "gatewayId": "################", + "isEnabled": true, + "isReady": true, + "properties": { + "level": { + "type": "number", + "unit": "percent", + "value": 89 + } + }, + "timestamp": "2025-02-03T02:30:52.279Z", + "uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/zigbee-d87a3bfffe5d844a/features/device.power.battery" + }, { "apiVersion": 1, "commands": {}, diff --git a/tests/components/vicare/snapshots/test_binary_sensor.ambr b/tests/components/vicare/snapshots/test_binary_sensor.ambr index ec2451cd466..93e407ea505 100644 --- a/tests/components/vicare/snapshots/test_binary_sensor.ambr +++ b/tests/components/vicare/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -334,6 +341,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +388,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/snapshots/test_button.ambr b/tests/components/vicare/snapshots/test_button.ambr index 9fadc6a983f..17dfc29e96e 100644 --- a/tests/components/vicare/snapshots/test_button.ambr +++ b/tests/components/vicare/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/snapshots/test_climate.ambr b/tests/components/vicare/snapshots/test_climate.ambr index aea0ea879c2..e1709acea42 100644 --- a/tests/components/vicare/snapshots/test_climate.ambr +++ b/tests/components/vicare/snapshots/test_climate.ambr @@ -18,6 +18,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -101,6 +102,7 @@ 'target_temp_step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/snapshots/test_diagnostics.ambr b/tests/components/vicare/snapshots/test_diagnostics.ambr index ae9b05389c7..0b1dcef5a29 100644 --- a/tests/components/vicare/snapshots/test_diagnostics.ambr +++ b/tests/components/vicare/snapshots/test_diagnostics.ambr @@ -4731,6 +4731,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': 'ViCare', 'version': 1, diff --git a/tests/components/vicare/snapshots/test_fan.ambr b/tests/components/vicare/snapshots/test_fan.ambr index b5b02af39b1..0bac421e2c7 100644 --- a/tests/components/vicare/snapshots/test_fan.ambr +++ b/tests/components/vicare/snapshots/test_fan.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/snapshots/test_number.ambr b/tests/components/vicare/snapshots/test_number.ambr index 5a030fc0213..b26d2d33590 100644 --- a/tests/components/vicare/snapshots/test_number.ambr +++ b/tests/components/vicare/snapshots/test_number.ambr @@ -11,6 +11,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -68,6 +69,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,64 @@ 'state': 'unavailable', }) # --- +# name: test_all_entities[number.model0_dhw_temperature-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'max': 100.0, + 'min': 0.0, + 'mode': , + 'step': 1, + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'number', + 'entity_category': , + 'entity_id': 'number.model0_dhw_temperature', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'DHW temperature', + 'platform': 'vicare', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'dhw_temperature', + 'unique_id': 'gateway0_deviceSerialVitodens300W-dhw_temperature', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[number.model0_dhw_temperature-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', + 'friendly_name': 'model0 DHW temperature', + 'max': 100.0, + 'min': 0.0, + 'mode': , + 'step': 1, + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'number.model0_dhw_temperature', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- # name: test_all_entities[number.model0_heating_curve_shift-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -125,6 +185,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -182,6 +243,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -239,6 +301,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -294,6 +357,7 @@ 'step': 0.1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -349,6 +413,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -406,6 +471,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -463,6 +529,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -520,6 +587,7 @@ 'step': 1.0, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -565,60 +633,3 @@ 'state': 'unavailable', }) # --- -# name: test_all_entities[number.model0_dhw_temperature-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'max': 100.0, - 'min': 0.0, - 'mode': , - 'step': 1, - }), - 'config_entry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'number', - 'entity_category': , - 'entity_id': 'number.model0_dhw_temperature', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'DHW temperature', - 'platform': 'vicare', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'dhw_temperature', - 'unique_id': 'gateway0_deviceSerialVitodens300W-dhw_temperature', - 'unit_of_measurement': , - }) -# --- -# name: test_all_entities[number.model0_dhw_temperature-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'temperature', - 'friendly_name': 'model0 DHW temperature', - 'max': 100.0, - 'min': 0.0, - 'mode': , - 'step': 1, - 'unit_of_measurement': , - }), - 'context': , - 'entity_id': 'number.model0_dhw_temperature', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unavailable', - }) -# --- diff --git a/tests/components/vicare/snapshots/test_sensor.ambr b/tests/components/vicare/snapshots/test_sensor.ambr index ace22391797..a0d4bf374c8 100644 --- a/tests/components/vicare/snapshots/test_sensor.ambr +++ b/tests/components/vicare/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -109,6 +111,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -159,6 +162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -208,6 +212,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -257,6 +262,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -306,6 +312,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -355,6 +362,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -404,6 +412,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -455,6 +464,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -506,6 +516,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -557,6 +568,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -608,6 +620,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -659,6 +672,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -710,6 +724,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -759,6 +774,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -808,6 +824,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -857,6 +874,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -906,6 +924,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -957,6 +976,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1008,6 +1028,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1059,6 +1080,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1110,6 +1132,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1158,6 +1181,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1206,6 +1230,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1255,6 +1280,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1306,6 +1332,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1357,6 +1384,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1408,6 +1436,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1459,6 +1488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1510,6 +1540,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1561,6 +1592,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1612,6 +1644,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1663,6 +1696,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1714,6 +1748,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1765,6 +1800,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1816,6 +1852,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1867,6 +1904,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1917,6 +1955,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1966,6 +2005,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2017,6 +2057,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2068,6 +2109,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2119,6 +2161,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2168,6 +2211,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2217,6 +2261,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2266,6 +2311,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2317,6 +2363,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2367,6 +2414,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2418,6 +2466,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2474,6 +2523,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2537,6 +2587,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2585,6 +2636,58 @@ 'state': 'permanent', }) # --- +# name: test_room_sensors[sensor.model0_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.model0_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'vicare', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'gateway0_zigbee_d87a3bfffe5d844a-battery_level', + 'unit_of_measurement': '%', + }) +# --- +# name: test_room_sensors[sensor.model0_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'model0 Battery', + 'state_class': , + 'unit_of_measurement': '%', + }), + 'context': , + 'entity_id': 'sensor.model0_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '89', + }) +# --- # name: test_room_sensors[sensor.model0_humidity-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -2594,6 +2697,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2645,6 +2749,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2696,6 +2801,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2747,6 +2853,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vicare/snapshots/test_water_heater.ambr b/tests/components/vicare/snapshots/test_water_heater.ambr index bca04b1bbfa..7b7ab91e086 100644 --- a/tests/components/vicare/snapshots/test_water_heater.ambr +++ b/tests/components/vicare/snapshots/test_water_heater.ambr @@ -9,6 +9,7 @@ 'min_temp': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -65,6 +66,7 @@ 'min_temp': 10, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vodafone_station/snapshots/test_button.ambr b/tests/components/vodafone_station/snapshots/test_button.ambr index dc7953ac42a..736f590241a 100644 --- a/tests/components/vodafone_station/snapshots/test_button.ambr +++ b/tests/components/vodafone_station/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vodafone_station/snapshots/test_device_tracker.ambr b/tests/components/vodafone_station/snapshots/test_device_tracker.ambr index e019ea73ab9..7f98aad1405 100644 --- a/tests/components/vodafone_station/snapshots/test_device_tracker.ambr +++ b/tests/components/vodafone_station/snapshots/test_device_tracker.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -56,6 +57,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/vodafone_station/snapshots/test_diagnostics.ambr b/tests/components/vodafone_station/snapshots/test_diagnostics.ambr index 478080700cd..be2956e0aab 100644 --- a/tests/components/vodafone_station/snapshots/test_diagnostics.ambr +++ b/tests/components/vodafone_station/snapshots/test_diagnostics.ambr @@ -41,6 +41,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/vodafone_station/snapshots/test_sensor.ambr b/tests/components/vodafone_station/snapshots/test_sensor.ambr index eb1676938b5..169ee92a24b 100644 --- a/tests/components/vodafone_station/snapshots/test_sensor.ambr +++ b/tests/components/vodafone_station/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -64,6 +65,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -111,6 +113,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -158,6 +161,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -204,6 +208,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/voip/test_config_flow.py b/tests/components/voip/test_config_flow.py index 1b7aaad7c03..05f14afa4e7 100644 --- a/tests/components/voip/test_config_flow.py +++ b/tests/components/voip/test_config_flow.py @@ -80,3 +80,30 @@ async def test_options_flow(hass: HomeAssistant) -> None: ) assert result["type"] is FlowResultType.CREATE_ENTRY assert config_entry.options == {"sip_port": 5061} + + # Manual with user + result = await hass.config_entries.options.async_init( + config_entry.entry_id, + ) + result = await hass.config_entries.options.async_configure( + result["flow_id"], + user_input={"sip_port": 5061, "sip_user": "HA"}, + ) + assert result["type"] is FlowResultType.CREATE_ENTRY + assert config_entry.options == {"sip_port": 5061, "sip_user": "HA"} + + # Manual remove user + result = await hass.config_entries.options.async_init( + config_entry.entry_id, + ) + + assert config_entry.options == {"sip_port": 5061, "sip_user": "HA"} + + result = await hass.config_entries.options.async_configure( + result["flow_id"], + user_input={"sip_port": 5060, "sip_user": ""}, + ) + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert config_entry.options == {"sip_port": 5060} diff --git a/tests/components/wake_word/test_init.py b/tests/components/wake_word/test_init.py index cdaf7e0e3f0..e6e8ff72a6d 100644 --- a/tests/components/wake_word/test_init.py +++ b/tests/components/wake_word/test_init.py @@ -13,7 +13,7 @@ from homeassistant.components import wake_word from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.setup import async_setup_component from .common import mock_wake_word_entity_platform @@ -143,7 +143,7 @@ async def mock_config_entry_setup( async def async_setup_entry_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test stt platform via config entry.""" async_add_entities([mock_provider_entity]) diff --git a/tests/components/water_heater/test_init.py b/tests/components/water_heater/test_init.py index 67f0c1de36e..191acdf24f9 100644 --- a/tests/components/water_heater/test_init.py +++ b/tests/components/water_heater/test_init.py @@ -23,7 +23,7 @@ from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -145,7 +145,7 @@ async def test_operation_mode_validation( async def async_setup_entry_water_heater_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test water_heater platform via config entry.""" async_add_entities([water_heater_entity]) diff --git a/tests/components/watergate/snapshots/test_sensor.ambr b/tests/components/watergate/snapshots/test_sensor.ambr index a58c7c0eab8..b4b6c4ee0a4 100644 --- a/tests/components/watergate/snapshots/test_sensor.ambr +++ b/tests/components/watergate/snapshots/test_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -113,6 +115,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -162,6 +165,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -211,6 +215,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -262,6 +267,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -313,6 +319,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -364,6 +371,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -415,6 +423,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -464,6 +473,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/watttime/snapshots/test_diagnostics.ambr b/tests/components/watttime/snapshots/test_diagnostics.ambr index 0c137acc36b..3cc5e1d6f66 100644 --- a/tests/components/watttime/snapshots/test_diagnostics.ambr +++ b/tests/components/watttime/snapshots/test_diagnostics.ambr @@ -27,6 +27,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/weather/__init__.py b/tests/components/weather/__init__.py index 2dbffbbd617..301e055129d 100644 --- a/tests/components/weather/__init__.py +++ b/tests/components/weather/__init__.py @@ -21,7 +21,7 @@ from homeassistant.components.weather import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from tests.common import ( MockConfigEntry, @@ -90,7 +90,7 @@ async def create_entity( async def async_setup_entry_weather_platform( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up test weather platform via config entry.""" async_add_entities([weather_entity]) diff --git a/tests/components/weatherflow_cloud/snapshots/test_sensor.ambr b/tests/components/weatherflow_cloud/snapshots/test_sensor.ambr index 95be86664a2..c06229302c5 100644 --- a/tests/components/weatherflow_cloud/snapshots/test_sensor.ambr +++ b/tests/components/weatherflow_cloud/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -62,6 +63,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -117,6 +119,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -172,6 +175,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -227,6 +231,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -277,6 +282,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -327,6 +333,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -377,6 +384,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -427,6 +435,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -477,6 +486,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -535,6 +545,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -593,6 +604,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -648,6 +660,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -703,6 +716,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -758,6 +772,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/weatherflow_cloud/snapshots/test_weather.ambr b/tests/components/weatherflow_cloud/snapshots/test_weather.ambr index 569b744529c..0b0d66c34a7 100644 --- a/tests/components/weatherflow_cloud/snapshots/test_weather.ambr +++ b/tests/components/weatherflow_cloud/snapshots/test_weather.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/webmin/snapshots/test_diagnostics.ambr b/tests/components/webmin/snapshots/test_diagnostics.ambr index 8299b0eafba..c64fa212a98 100644 --- a/tests/components/webmin/snapshots/test_diagnostics.ambr +++ b/tests/components/webmin/snapshots/test_diagnostics.ambr @@ -253,6 +253,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': '**REDACTED**', 'unique_id': None, 'version': 1, diff --git a/tests/components/webmin/snapshots/test_sensor.ambr b/tests/components/webmin/snapshots/test_sensor.ambr index 6af768d63a8..a2068f662ba 100644 --- a/tests/components/webmin/snapshots/test_sensor.ambr +++ b/tests/components/webmin/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -57,6 +58,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -106,6 +108,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -155,6 +158,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -269,6 +274,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -326,6 +332,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -376,6 +383,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -426,6 +434,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -476,6 +485,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -525,6 +535,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -574,6 +585,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -623,6 +635,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -680,6 +693,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -737,6 +751,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -794,6 +809,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -844,6 +860,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -894,6 +911,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -944,6 +962,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -993,6 +1012,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1042,6 +1062,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1091,6 +1112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1148,6 +1170,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1205,6 +1228,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1262,6 +1286,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1319,6 +1344,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1376,6 +1402,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1433,6 +1460,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1482,6 +1510,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1531,6 +1560,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1580,6 +1610,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1637,6 +1668,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1694,6 +1726,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1751,6 +1784,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/webostv/snapshots/test_diagnostics.ambr b/tests/components/webostv/snapshots/test_diagnostics.ambr index 07ee50af1f8..030554b963a 100644 --- a/tests/components/webostv/snapshots/test_diagnostics.ambr +++ b/tests/components/webostv/snapshots/test_diagnostics.ambr @@ -59,6 +59,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'LG webOS TV MODEL', 'unique_id': '**REDACTED**', 'version': 1, diff --git a/tests/components/webostv/snapshots/test_media_player.ambr b/tests/components/webostv/snapshots/test_media_player.ambr index 23f45a0f325..9c097b166ec 100644 --- a/tests/components/webostv/snapshots/test_media_player.ambr +++ b/tests/components/webostv/snapshots/test_media_player.ambr @@ -39,6 +39,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/weheat/snapshots/test_binary_sensor.ambr b/tests/components/weheat/snapshots/test_binary_sensor.ambr index 08d609ca610..cd2aa13135a 100644 --- a/tests/components/weheat/snapshots/test_binary_sensor.ambr +++ b/tests/components/weheat/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -146,6 +149,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/weheat/snapshots/test_sensor.ambr b/tests/components/weheat/snapshots/test_sensor.ambr index 1a54711d6c5..77f85224913 100644 --- a/tests/components/weheat/snapshots/test_sensor.ambr +++ b/tests/components/weheat/snapshots/test_sensor.ambr @@ -18,6 +18,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -78,6 +79,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -132,6 +134,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -182,6 +185,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -232,6 +236,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -284,6 +289,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -338,6 +344,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -392,6 +399,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -446,6 +454,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -497,6 +506,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -551,6 +561,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -605,6 +616,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -659,6 +671,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -713,6 +726,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -764,6 +778,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -818,6 +833,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -872,6 +888,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/whirlpool/snapshots/test_diagnostics.ambr b/tests/components/whirlpool/snapshots/test_diagnostics.ambr index c60ce17b952..ee8abe04bf1 100644 --- a/tests/components/whirlpool/snapshots/test_diagnostics.ambr +++ b/tests/components/whirlpool/snapshots/test_diagnostics.ambr @@ -38,6 +38,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/whois/snapshots/test_config_flow.ambr b/tests/components/whois/snapshots/test_config_flow.ambr index 937502d4d6c..0d99b0596e3 100644 --- a/tests/components/whois/snapshots/test_config_flow.ambr +++ b/tests/components/whois/snapshots/test_config_flow.ambr @@ -30,10 +30,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Example.com', 'unique_id': 'example.com', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Example.com', 'type': , 'version': 1, @@ -70,10 +74,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Example.com', 'unique_id': 'example.com', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Example.com', 'type': , 'version': 1, @@ -110,10 +118,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Example.com', 'unique_id': 'example.com', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Example.com', 'type': , 'version': 1, @@ -150,10 +162,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Example.com', 'unique_id': 'example.com', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Example.com', 'type': , 'version': 1, @@ -190,10 +206,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Example.com', 'unique_id': 'example.com', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Example.com', 'type': , 'version': 1, diff --git a/tests/components/whois/snapshots/test_sensor.ambr b/tests/components/whois/snapshots/test_sensor.ambr index 4310bc77ebf..b5b1dde1c3d 100644 --- a/tests/components/whois/snapshots/test_sensor.ambr +++ b/tests/components/whois/snapshots/test_sensor.ambr @@ -19,6 +19,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -49,6 +50,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -128,6 +131,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -181,6 +185,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -211,6 +216,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -260,6 +266,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -290,6 +297,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -339,6 +347,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -369,6 +378,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -417,6 +427,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -447,6 +458,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -495,6 +507,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -525,6 +538,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -573,6 +587,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -603,6 +618,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -651,6 +667,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -681,6 +698,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -730,6 +748,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/withings/snapshots/test_init.ambr b/tests/components/withings/snapshots/test_init.ambr index be221cad313..ec711def829 100644 --- a/tests/components/withings/snapshots/test_init.ambr +++ b/tests/components/withings/snapshots/test_init.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), @@ -35,6 +36,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': None, 'connections': set({ }), diff --git a/tests/components/withings/snapshots/test_sensor.ambr b/tests/components/withings/snapshots/test_sensor.ambr index cfecfb1e28e..543cba05e21 100644 --- a/tests/components/withings/snapshots/test_sensor.ambr +++ b/tests/components/withings/snapshots/test_sensor.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -66,6 +67,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -120,6 +122,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -175,6 +178,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -225,6 +229,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -275,6 +280,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -326,6 +332,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +387,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -427,6 +435,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -479,6 +488,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -530,6 +540,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -578,6 +589,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -631,6 +643,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -684,6 +697,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -731,6 +745,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -778,6 +793,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -825,6 +841,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -875,6 +892,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -927,6 +945,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -978,6 +997,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1032,6 +1052,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1086,6 +1107,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1140,6 +1162,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1194,6 +1217,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1248,6 +1272,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1302,6 +1327,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1356,6 +1382,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1410,6 +1437,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1464,6 +1492,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1518,6 +1547,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1572,6 +1602,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1626,6 +1657,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1679,6 +1711,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1729,6 +1762,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1783,6 +1817,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1834,6 +1869,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1889,6 +1925,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1938,6 +1975,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1989,6 +2027,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2087,6 +2126,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2187,6 +2227,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2238,6 +2279,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2288,6 +2330,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2338,6 +2381,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2388,6 +2432,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2438,6 +2483,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2493,6 +2539,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2547,6 +2594,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2601,6 +2649,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2655,6 +2704,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2709,6 +2759,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2763,6 +2814,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2815,6 +2867,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2868,6 +2921,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2919,6 +2973,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -2970,6 +3025,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3021,6 +3077,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3075,6 +3132,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3125,6 +3183,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3174,6 +3233,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3223,6 +3283,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3278,6 +3339,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3328,6 +3390,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3378,6 +3441,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3429,6 +3493,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3479,6 +3544,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3530,6 +3596,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3581,6 +3648,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3632,6 +3700,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3684,6 +3753,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3730,6 +3800,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3778,6 +3849,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3828,6 +3900,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3878,6 +3951,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3929,6 +4003,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -3983,6 +4058,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/wled/snapshots/test_button.ambr b/tests/components/wled/snapshots/test_button.ambr index 4e6260bc9bd..a22c1a3fb85 100644 --- a/tests/components/wled/snapshots/test_button.ambr +++ b/tests/components/wled/snapshots/test_button.ambr @@ -20,6 +20,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -50,6 +51,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( diff --git a/tests/components/wled/snapshots/test_number.ambr b/tests/components/wled/snapshots/test_number.ambr index 0fb6cff3d51..a99831d1440 100644 --- a/tests/components/wled/snapshots/test_number.ambr +++ b/tests/components/wled/snapshots/test_number.ambr @@ -28,6 +28,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -58,6 +59,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -119,6 +121,7 @@ 'step': 1, }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -149,6 +152,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( diff --git a/tests/components/wled/snapshots/test_select.ambr b/tests/components/wled/snapshots/test_select.ambr index 2998583f8b3..ca3b0a5dc6e 100644 --- a/tests/components/wled/snapshots/test_select.ambr +++ b/tests/components/wled/snapshots/test_select.ambr @@ -30,6 +30,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -60,6 +61,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -259,6 +261,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -289,6 +292,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -350,6 +354,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -380,6 +385,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -441,6 +447,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -471,6 +478,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( diff --git a/tests/components/wled/snapshots/test_switch.ambr b/tests/components/wled/snapshots/test_switch.ambr index ee3a72ba872..99358153fe1 100644 --- a/tests/components/wled/snapshots/test_switch.ambr +++ b/tests/components/wled/snapshots/test_switch.ambr @@ -21,6 +21,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -51,6 +52,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -103,6 +105,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -133,6 +136,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -186,6 +190,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -216,6 +221,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( @@ -269,6 +275,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -299,6 +306,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': None, 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://127.0.0.1', 'connections': set({ tuple( diff --git a/tests/components/wmspro/snapshots/test_cover.ambr b/tests/components/wmspro/snapshots/test_cover.ambr index 0456f074d49..53b2f6205cb 100644 --- a/tests/components/wmspro/snapshots/test_cover.ambr +++ b/tests/components/wmspro/snapshots/test_cover.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'terrasse', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://webcontrol/control', 'connections': set({ }), diff --git a/tests/components/wmspro/snapshots/test_light.ambr b/tests/components/wmspro/snapshots/test_light.ambr index d13e444645d..d6ccebfb5ea 100644 --- a/tests/components/wmspro/snapshots/test_light.ambr +++ b/tests/components/wmspro/snapshots/test_light.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'terrasse', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://webcontrol/control', 'connections': set({ }), diff --git a/tests/components/wmspro/snapshots/test_scene.ambr b/tests/components/wmspro/snapshots/test_scene.ambr index 940d4e31e83..b5dddb368c9 100644 --- a/tests/components/wmspro/snapshots/test_scene.ambr +++ b/tests/components/wmspro/snapshots/test_scene.ambr @@ -17,6 +17,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'raum_0', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://webcontrol/control', 'connections': set({ }), diff --git a/tests/components/workday/snapshots/test_diagnostics.ambr b/tests/components/workday/snapshots/test_diagnostics.ambr index f41b86b7f6d..e7331b911a8 100644 --- a/tests/components/workday/snapshots/test_diagnostics.ambr +++ b/tests/components/workday/snapshots/test_diagnostics.ambr @@ -40,6 +40,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/components/wyoming/snapshots/test_config_flow.ambr b/tests/components/wyoming/snapshots/test_config_flow.ambr index bdead0f2028..d288c531407 100644 --- a/tests/components/wyoming/snapshots/test_config_flow.ambr +++ b/tests/components/wyoming/snapshots/test_config_flow.ambr @@ -36,10 +36,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'hassio', + 'subentries': list([ + ]), 'title': 'Piper', 'unique_id': '1234', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Piper', 'type': , 'version': 1, @@ -82,10 +86,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'hassio', + 'subentries': list([ + ]), 'title': 'Piper', 'unique_id': '1234', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Piper', 'type': , 'version': 1, @@ -127,10 +135,14 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'zeroconf', + 'subentries': list([ + ]), 'title': 'Test Satellite', 'unique_id': 'test_zeroconf_name._wyoming._tcp.local._Test Satellite', 'version': 1, }), + 'subentries': tuple( + ), 'title': 'Test Satellite', 'type': , 'version': 1, diff --git a/tests/components/wyoming/test_satellite.py b/tests/components/wyoming/test_satellite.py index f293f976242..0e4bb3da78c 100644 --- a/tests/components/wyoming/test_satellite.py +++ b/tests/components/wyoming/test_satellite.py @@ -5,6 +5,7 @@ from __future__ import annotations import asyncio from collections.abc import Callable import io +import tempfile from typing import Any from unittest.mock import patch import wave @@ -17,17 +18,18 @@ from wyoming.info import Info from wyoming.ping import Ping, Pong from wyoming.pipeline import PipelineStage, RunPipeline from wyoming.satellite import RunSatellite +from wyoming.snd import Played from wyoming.timer import TimerCancelled, TimerFinished, TimerStarted, TimerUpdated from wyoming.tts import Synthesize from wyoming.vad import VoiceStarted, VoiceStopped from wyoming.wake import Detect, Detection -from homeassistant.components import assist_pipeline, wyoming +from homeassistant.components import assist_pipeline, assist_satellite, wyoming from homeassistant.components.wyoming.assist_satellite import WyomingAssistSatellite from homeassistant.components.wyoming.devices import SatelliteDevice from homeassistant.const import STATE_ON from homeassistant.core import HomeAssistant, State -from homeassistant.helpers import intent as intent_helper +from homeassistant.helpers import entity_registry as er, intent as intent_helper from homeassistant.setup import async_setup_component from . import SATELLITE_INFO, WAKE_WORD_INFO, MockAsyncTcpClient @@ -65,7 +67,7 @@ def get_test_wav() -> bytes: wav_file.setnchannels(1) # Single frame - wav_file.writeframes(b"123") + wav_file.writeframes(b"1234") return wav_io.getvalue() @@ -73,10 +75,15 @@ def get_test_wav() -> bytes: class SatelliteAsyncTcpClient(MockAsyncTcpClient): """Satellite AsyncTcpClient.""" - def __init__(self, responses: list[Event]) -> None: + def __init__( + self, responses: list[Event], block_until_inject: bool = False + ) -> None: """Initialize client.""" super().__init__(responses) + self.block_until_inject = block_until_inject + self._responses_ready = asyncio.Event() + self.connect_event = asyncio.Event() self.run_satellite_event = asyncio.Event() self.detect_event = asyncio.Event() @@ -188,6 +195,9 @@ class SatelliteAsyncTcpClient(MockAsyncTcpClient): async def read_event(self) -> Event | None: """Receive.""" + if self.block_until_inject and (not self.responses): + await self._responses_ready.wait() + event = await super().read_event() # Keep sending audio chunks instead of None @@ -196,6 +206,7 @@ class SatelliteAsyncTcpClient(MockAsyncTcpClient): def inject_event(self, event: Event) -> None: """Put an event in as the next response.""" self.responses = [event, *self.responses] + self._responses_ready.set() async def test_satellite_pipeline(hass: HomeAssistant) -> None: @@ -416,7 +427,7 @@ async def test_satellite_pipeline(hass: HomeAssistant) -> None: assert mock_client.tts_audio_chunk.rate == 22050 assert mock_client.tts_audio_chunk.width == 2 assert mock_client.tts_audio_chunk.channels == 1 - assert mock_client.tts_audio_chunk.audio == b"123" + assert mock_client.tts_audio_chunk.audio == b"1234" # Pipeline finished pipeline_event_callback( @@ -1283,3 +1294,85 @@ async def test_timers(hass: HomeAssistant) -> None: timer_finished = mock_client.timer_finished assert timer_finished is not None assert timer_finished.id == timer_started.id + + +async def test_announce( + hass: HomeAssistant, entity_registry: er.EntityRegistry +) -> None: + """Test announce on satellite.""" + assert await async_setup_component(hass, assist_pipeline.DOMAIN, {}) + + def async_process_play_media_url(hass: HomeAssistant, media_id: str) -> str: + # Don't create a URL + return media_id + + with ( + tempfile.NamedTemporaryFile(mode="wb+", suffix=".wav") as temp_wav_file, + patch( + "homeassistant.components.wyoming.data.load_wyoming_info", + return_value=SATELLITE_INFO, + ), + patch( + "homeassistant.components.wyoming.assist_satellite.AsyncTcpClient", + SatelliteAsyncTcpClient(responses=[], block_until_inject=True), + ) as mock_client, + patch( + "homeassistant.components.assist_satellite.entity.async_process_play_media_url", + new=async_process_play_media_url, + ), + ): + # Use test WAV data for media + with wave.open(temp_wav_file.name, "wb") as wav_file: + wav_file.setframerate(22050) + wav_file.setsampwidth(2) + wav_file.setnchannels(1) + wav_file.writeframes(bytes(22050 * 2)) # 1 sec + + temp_wav_file.seek(0) + + entry = await setup_config_entry(hass) + device: SatelliteDevice = hass.data[wyoming.DOMAIN][entry.entry_id].device + assert device is not None + + satellite_entry = next( + ( + maybe_entry + for maybe_entry in er.async_entries_for_device( + entity_registry, device.device_id + ) + if maybe_entry.domain == assist_satellite.DOMAIN + ), + None, + ) + assert satellite_entry is not None + + async with asyncio.timeout(1): + await mock_client.connect_event.wait() + await mock_client.run_satellite_event.wait() + + announce_task = hass.async_create_background_task( + hass.services.async_call( + assist_satellite.DOMAIN, + "announce", + { + "entity_id": satellite_entry.entity_id, + "media_id": temp_wav_file.name, + }, + blocking=True, + ), + "wyoming_satellite_announce", + ) + + # Wait for audio to come from ffmpeg + async with asyncio.timeout(1): + await mock_client.tts_audio_start_event.wait() + await mock_client.tts_audio_chunk_event.wait() + await mock_client.tts_audio_stop_event.wait() + + # Stop announcement from blocking + mock_client.inject_event(Played().event()) + await announce_task + + # Stop the satellite + await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() diff --git a/tests/components/yale/snapshots/test_binary_sensor.ambr b/tests/components/yale/snapshots/test_binary_sensor.ambr index e294cb7c76c..9db0d760efb 100644 --- a/tests/components/yale/snapshots/test_binary_sensor.ambr +++ b/tests/components/yale/snapshots/test_binary_sensor.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'tmt100_name', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://account.aaecosystem.com', 'connections': set({ }), diff --git a/tests/components/yale/snapshots/test_lock.ambr b/tests/components/yale/snapshots/test_lock.ambr index b1a9f6a4d86..00653a9b0c1 100644 --- a/tests/components/yale/snapshots/test_lock.ambr +++ b/tests/components/yale/snapshots/test_lock.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'online_with_doorsense_name', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'https://account.aaecosystem.com', 'connections': set({ tuple( diff --git a/tests/components/yale_smart_alarm/snapshots/test_alarm_control_panel.ambr b/tests/components/yale_smart_alarm/snapshots/test_alarm_control_panel.ambr index fcdb7baca03..daa232ab141 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_alarm_control_panel.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_alarm_control_panel.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/yale_smart_alarm/snapshots/test_binary_sensor.ambr b/tests/components/yale_smart_alarm/snapshots/test_binary_sensor.ambr index e519a880de9..39b3ef09196 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_binary_sensor.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_binary_sensor.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -53,6 +54,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -100,6 +102,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -147,6 +150,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -194,6 +198,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -241,6 +246,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -288,6 +294,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -335,6 +342,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -382,6 +390,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -429,6 +438,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/yale_smart_alarm/snapshots/test_button.ambr b/tests/components/yale_smart_alarm/snapshots/test_button.ambr index 951caced170..7d52d1d7206 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_button.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_button.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/yale_smart_alarm/snapshots/test_lock.ambr b/tests/components/yale_smart_alarm/snapshots/test_lock.ambr index 34da7db087a..e7c97b9001b 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_lock.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_lock.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -54,6 +55,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -102,6 +104,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -150,6 +153,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -198,6 +202,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -246,6 +251,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/yale_smart_alarm/snapshots/test_select.ambr b/tests/components/yale_smart_alarm/snapshots/test_select.ambr index 52ec7a99c2c..2899e716ea1 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_select.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_select.ambr @@ -12,6 +12,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -69,6 +70,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -126,6 +128,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -183,6 +186,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -240,6 +244,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -297,6 +302,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/yale_smart_alarm/snapshots/test_switch.ambr b/tests/components/yale_smart_alarm/snapshots/test_switch.ambr index f631a6fcbfe..17c44bf6ebf 100644 --- a/tests/components/yale_smart_alarm/snapshots/test_switch.ambr +++ b/tests/components/yale_smart_alarm/snapshots/test_switch.ambr @@ -6,6 +6,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -52,6 +53,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -98,6 +100,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -144,6 +147,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -190,6 +194,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -236,6 +241,7 @@ 'area_id': None, 'capabilities': None, 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/youless/snapshots/test_sensor.ambr b/tests/components/youless/snapshots/test_sensor.ambr index 9e79b5b9b5e..8cb28776d74 100644 --- a/tests/components/youless/snapshots/test_sensor.ambr +++ b/tests/components/youless/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -110,6 +112,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -161,6 +164,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -212,6 +216,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -263,6 +268,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -314,6 +320,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -365,6 +372,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -416,6 +424,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -467,6 +476,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -518,6 +528,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -569,6 +580,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -620,6 +632,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -671,6 +684,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -725,6 +739,7 @@ ]), }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -778,6 +793,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -829,6 +845,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -880,6 +897,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -931,6 +949,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -982,6 +1001,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1033,6 +1053,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -1084,6 +1105,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/zeversolar/snapshots/test_sensor.ambr b/tests/components/zeversolar/snapshots/test_sensor.ambr index aaef2c43d79..f948eec79df 100644 --- a/tests/components/zeversolar/snapshots/test_sensor.ambr +++ b/tests/components/zeversolar/snapshots/test_sensor.ambr @@ -8,6 +8,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, @@ -59,6 +60,7 @@ 'state_class': , }), 'config_entry_id': , + 'config_subentry_id': , 'device_class': None, 'device_id': , 'disabled_by': None, diff --git a/tests/components/zha/snapshots/test_diagnostics.ambr b/tests/components/zha/snapshots/test_diagnostics.ambr index c9a5e80b1c9..7a599b00a21 100644 --- a/tests/components/zha/snapshots/test_diagnostics.ambr +++ b/tests/components/zha/snapshots/test_diagnostics.ambr @@ -113,6 +113,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 4, diff --git a/tests/helpers/snapshots/test_entity_platform.ambr b/tests/helpers/snapshots/test_entity_platform.ambr index 84cbb07bd73..55ff772e08e 100644 --- a/tests/helpers/snapshots/test_entity_platform.ambr +++ b/tests/helpers/snapshots/test_entity_platform.ambr @@ -3,6 +3,7 @@ DeviceRegistryEntrySnapshot({ 'area_id': 'heliport', 'config_entries': , + 'config_entries_subentries': , 'configuration_url': 'http://192.168.0.100/config', 'connections': set({ tuple( @@ -35,3 +36,40 @@ 'via_device_id': , }) # --- +# name: test_device_info_called.1 + DeviceRegistryEntrySnapshot({ + 'area_id': 'heliport', + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': 'http://192.168.0.100/config', + 'connections': set({ + tuple( + 'mac', + 'efgh', + ), + }), + 'disabled_by': None, + 'entry_type': , + 'hw_version': 'test-hw', + 'id': , + 'identifiers': set({ + tuple( + 'hue', + 'efgh', + ), + }), + 'is_new': False, + 'labels': set({ + }), + 'manufacturer': 'test-manuf', + 'model': 'test-model', + 'model_id': None, + 'name': 'test-name', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'suggested_area': 'Heliport', + 'sw_version': 'test-sw', + 'via_device_id': , + }) +# --- diff --git a/tests/helpers/test_device_registry.py b/tests/helpers/test_device_registry.py index be4ace87894..29edfb3fea7 100644 --- a/tests/helpers/test_device_registry.py +++ b/tests/helpers/test_device_registry.py @@ -173,6 +173,109 @@ async def test_multiple_config_entries( assert entry3.primary_config_entry == config_entry_1.entry_id +async def test_multiple_config_subentries( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Make sure we do not get duplicate entries.""" + config_entry_1 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_1.add_to_hass(hass) + config_entry_2 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_2.add_to_hass(hass) + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == {config_entry_1.entry_id: {None}} + entry_id = entry.id + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id=None, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert entry.id == entry_id + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == {config_entry_1.entry_id: {None}} + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert entry.id == entry_id + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1"} + } + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-2", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert entry.id == entry_id + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1", "mock-subentry-id-1-2"} + } + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_2.entry_id, + config_subentry_id="mock-subentry-id-2-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert entry.id == entry_id + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + @pytest.mark.parametrize("load_registries", [False]) @pytest.mark.usefixtures("freezer") async def test_loading_from_storage( @@ -191,6 +294,7 @@ async def test_loading_from_storage( { "area_id": "12345A", "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": "https://example.com/config", "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": created_at, @@ -215,6 +319,7 @@ async def test_loading_from_storage( "deleted_devices": [ { "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "connections": [["Zigbee", "23.45.67.89.01"]], "created_at": created_at, "id": "bcdefghijklmn", @@ -233,6 +338,7 @@ async def test_loading_from_storage( assert registry.deleted_devices["bcdefghijklmn"] == dr.DeletedDeviceEntry( config_entries={mock_config_entry.entry_id}, + config_entries_subentries={mock_config_entry.entry_id: {None}}, connections={("Zigbee", "23.45.67.89.01")}, created_at=datetime.fromisoformat(created_at), id="bcdefghijklmn", @@ -251,6 +357,7 @@ async def test_loading_from_storage( assert entry == dr.DeviceEntry( area_id="12345A", config_entries={mock_config_entry.entry_id}, + config_entries_subentries={mock_config_entry.entry_id: {None}}, configuration_url="https://example.com/config", connections={("Zigbee", "01.23.45.67.89")}, created_at=datetime.fromisoformat(created_at), @@ -285,6 +392,7 @@ async def test_loading_from_storage( ) assert entry == dr.DeviceEntry( config_entries={mock_config_entry.entry_id}, + config_entries_subentries={mock_config_entry.entry_id: {None}}, connections={("Zigbee", "23.45.67.89.01")}, created_at=datetime.fromisoformat(created_at), id="bcdefghijklmn", @@ -384,6 +492,7 @@ async def test_migration_from_1_1( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -407,6 +516,7 @@ async def test_migration_from_1_1( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -431,6 +541,7 @@ async def test_migration_from_1_1( "deleted_devices": [ { "config_entries": ["123456"], + "config_entries_subentries": {"123456": [None]}, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", "id": "deletedid", @@ -528,6 +639,7 @@ async def test_migration_from_1_2( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -551,6 +663,7 @@ async def test_migration_from_1_2( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -662,6 +775,7 @@ async def test_migration_fom_1_3( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -685,6 +799,7 @@ async def test_migration_fom_1_3( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -798,6 +913,7 @@ async def test_migration_from_1_4( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -821,6 +937,7 @@ async def test_migration_from_1_4( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -936,6 +1053,7 @@ async def test_migration_from_1_5( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -959,6 +1077,7 @@ async def test_migration_from_1_5( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -1076,6 +1195,7 @@ async def test_migration_from_1_6( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -1099,6 +1219,7 @@ async def test_migration_from_1_6( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -1218,6 +1339,7 @@ async def test_migration_from_1_7( { "area_id": None, "config_entries": [mock_config_entry.entry_id], + "config_entries_subentries": {mock_config_entry.entry_id: [None]}, "configuration_url": None, "connections": [["Zigbee", "01.23.45.67.89"]], "created_at": "1970-01-01T00:00:00+00:00", @@ -1241,6 +1363,7 @@ async def test_migration_from_1_7( { "area_id": None, "config_entries": ["234567"], + "config_entries_subentries": {"234567": [None]}, "configuration_url": None, "connections": [], "created_at": "1970-01-01T00:00:00+00:00", @@ -1303,6 +1426,10 @@ async def test_removing_config_entries( assert entry.id == entry2.id assert entry.id != entry3.id assert entry2.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry2.config_entries_subentries == { + config_entry_1.entry_id: {None}, + config_entry_2.entry_id: {None}, + } device_registry.async_clear_config_entry(config_entry_1.entry_id) entry = device_registry.async_get_device(identifiers={("bridgeid", "0123")}) @@ -1311,6 +1438,7 @@ async def test_removing_config_entries( ) assert entry.config_entries == {config_entry_2.entry_id} + assert entry.config_entries_subentries == {config_entry_2.entry_id: {None}} assert entry3_removed is None await hass.async_block_till_done() @@ -1325,6 +1453,7 @@ async def test_removing_config_entries( "device_id": entry.id, "changes": { "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": {config_entry_1.entry_id: {None}}, }, } assert update_events[2].data == { @@ -1336,6 +1465,10 @@ async def test_removing_config_entries( "device_id": entry.id, "changes": { "config_entries": {config_entry_1.entry_id, config_entry_2.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: {None}, + config_entry_2.entry_id: {None}, + }, "primary_config_entry": config_entry_1.entry_id, }, } @@ -1382,6 +1515,10 @@ async def test_deleted_device_removing_config_entries( assert entry.id == entry2.id assert entry.id != entry3.id assert entry2.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry2.config_entries_subentries == { + config_entry_1.entry_id: {None}, + config_entry_2.entry_id: {None}, + } device_registry.async_remove_device(entry.id) device_registry.async_remove_device(entry3.id) @@ -1400,6 +1537,7 @@ async def test_deleted_device_removing_config_entries( "device_id": entry2.id, "changes": { "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": {config_entry_1.entry_id: {None}}, }, } assert update_events[2].data == { @@ -1418,10 +1556,16 @@ async def test_deleted_device_removing_config_entries( device_registry.async_clear_config_entry(config_entry_1.entry_id) assert len(device_registry.devices) == 0 assert len(device_registry.deleted_devices) == 2 + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == {config_entry_2.entry_id} + assert entry.config_entries_subentries == {config_entry_2.entry_id: {None}} device_registry.async_clear_config_entry(config_entry_2.entry_id) assert len(device_registry.devices) == 0 assert len(device_registry.deleted_devices) == 2 + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == set() + assert entry.config_entries_subentries == {} # No event when a deleted device is purged await hass.async_block_till_done() @@ -1454,6 +1598,427 @@ async def test_deleted_device_removing_config_entries( assert entry3.id != entry4.id +async def test_removing_config_subentries( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Make sure we do not get duplicate entries.""" + update_events = async_capture_events(hass, dr.EVENT_DEVICE_REGISTRY_UPDATED) + config_entry_1 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_1.add_to_hass(hass) + config_entry_2 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_2.add_to_hass(hass) + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry2 = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry3 = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-2", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry4 = device_registry.async_get_or_create( + config_entry_id=config_entry_2.entry_id, + config_subentry_id="mock-subentry-id-2-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "4567")}, + manufacturer="manufacturer", + model="model", + ) + + assert len(device_registry.devices) == 1 + assert entry.id == entry2.id + assert entry.id == entry3.id + assert entry.id == entry4.id + assert entry4.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry4.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + device_registry.async_update_device( + entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id=None, + ) + entry = device_registry.async_get_device(identifiers={("bridgeid", "0123")}) + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + hass.config_entries.async_remove_subentry(config_entry_1, "mock-subentry-id-1-1") + entry = device_registry.async_get_device(identifiers={("bridgeid", "0123")}) + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + hass.config_entries.async_remove_subentry(config_entry_1, "mock-subentry-id-1-2") + entry = device_registry.async_get_device(identifiers={("bridgeid", "0123")}) + assert entry.config_entries == {config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_2.entry_id: {"mock-subentry-id-2-1"} + } + + hass.config_entries.async_remove_subentry(config_entry_2, "mock-subentry-id-2-1") + assert device_registry.async_get_device(identifiers={("bridgeid", "0123")}) is None + assert device_registry.async_get_device(identifiers={("bridgeid", "4567")}) is None + + await hass.async_block_till_done() + + assert len(update_events) == 8 + assert update_events[0].data == { + "action": "create", + "device_id": entry.id, + } + assert update_events[1].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": {config_entry_1.entry_id: {None}}, + }, + } + assert update_events[2].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1"} + }, + }, + } + assert update_events[3].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: { + None, + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + } + }, + "identifiers": {("bridgeid", "0123")}, + }, + } + assert update_events[4].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: { + None, + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: { + "mock-subentry-id-2-1", + }, + }, + }, + } + assert update_events[5].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: { + "mock-subentry-id-2-1", + }, + }, + }, + } + assert update_events[6].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries": {config_entry_1.entry_id, config_entry_2.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: { + "mock-subentry-id-2-1", + }, + }, + "primary_config_entry": config_entry_1.entry_id, + }, + } + assert update_events[7].data == { + "action": "remove", + "device_id": entry.id, + } + + +async def test_deleted_device_removing_config_subentries( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Make sure we do not get duplicate entries.""" + update_events = async_capture_events(hass, dr.EVENT_DEVICE_REGISTRY_UPDATED) + config_entry_1 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_1.add_to_hass(hass) + config_entry_2 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_2.add_to_hass(hass) + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry2 = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry3 = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-2", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry4 = device_registry.async_get_or_create( + config_entry_id=config_entry_2.entry_id, + config_subentry_id="mock-subentry-id-2-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "4567")}, + manufacturer="manufacturer", + model="model", + ) + + assert len(device_registry.devices) == 1 + assert len(device_registry.deleted_devices) == 0 + assert entry.id == entry2.id + assert entry.id == entry3.id + assert entry.id == entry4.id + assert entry4.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry4.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + device_registry.async_remove_device(entry.id) + + assert len(device_registry.devices) == 0 + assert len(device_registry.deleted_devices) == 1 + + await hass.async_block_till_done() + + assert len(update_events) == 5 + assert update_events[0].data == { + "action": "create", + "device_id": entry.id, + } + assert update_events[1].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": {config_entry_1.entry_id: {None}}, + }, + } + assert update_events[2].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: {None, "mock-subentry-id-1-1"} + }, + }, + } + assert update_events[3].data == { + "action": "update", + "device_id": entry.id, + "changes": { + "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: { + None, + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + } + }, + "identifiers": {("bridgeid", "0123")}, + }, + } + assert update_events[4].data == { + "action": "remove", + "device_id": entry.id, + } + + device_registry.async_clear_config_subentry(config_entry_1.entry_id, None) + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + assert entry.orphaned_timestamp is None + + hass.config_entries.async_remove_subentry(config_entry_1, "mock-subentry-id-1-1") + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + assert entry.orphaned_timestamp is None + + # Remove the same subentry again + device_registry.async_clear_config_subentry( + config_entry_1.entry_id, "mock-subentry-id-1-1" + ) + assert ( + device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) is entry + ) + + hass.config_entries.async_remove_subentry(config_entry_1, "mock-subentry-id-1-2") + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == {config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_2.entry_id: {"mock-subentry-id-2-1"} + } + assert entry.orphaned_timestamp is None + + hass.config_entries.async_remove_subentry(config_entry_2, "mock-subentry-id-2-1") + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == set() + assert entry.config_entries_subentries == {} + assert entry.orphaned_timestamp is not None + + # No event when a deleted device is purged + await hass.async_block_till_done() + assert len(update_events) == 5 + + # Re-add, expect to keep the device id + hass.config_entries.async_add_subentry( + config_entry_2, + config_entries.ConfigSubentry( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + restored_entry = device_registry.async_get_or_create( + config_entry_id=config_entry_2.entry_id, + config_subentry_id="mock-subentry-id-2-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert restored_entry.id == entry.id + + # Remove again, and trigger purge + device_registry.async_remove_device(entry.id) + hass.config_entries.async_remove_subentry(config_entry_2, "mock-subentry-id-2-1") + entry = device_registry.deleted_devices.get_entry({("bridgeid", "0123")}, None) + assert entry.config_entries == set() + assert entry.config_entries_subentries == {} + assert entry.orphaned_timestamp is not None + + future_time = time.time() + dr.ORPHANED_DEVICE_KEEP_SECONDS + 1 + + with patch("time.time", return_value=future_time): + device_registry.async_purge_expired_orphaned_devices() + + assert len(device_registry.devices) == 0 + assert len(device_registry.deleted_devices) == 0 + + # Re-add, expect to get a new device id after the purge + new_entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + assert new_entry.id != entry.id + + async def test_removing_area_id( device_registry: dr.DeviceRegistry, mock_config_entry: MockConfigEntry ) -> None: @@ -1834,6 +2399,7 @@ async def test_update( assert updated_entry == dr.DeviceEntry( area_id="12345A", config_entries={mock_config_entry.entry_id}, + config_entries_subentries={mock_config_entry.entry_id: {None}}, configuration_url="https://example.com/config", connections={("mac", "65:43:21:fe:dc:ba")}, created_at=created_at, @@ -2090,6 +2656,7 @@ async def test_update_remove_config_entries( "device_id": entry2.id, "changes": { "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": {config_entry_1.entry_id: {None}}, }, } assert update_events[2].data == { @@ -2100,7 +2667,11 @@ async def test_update_remove_config_entries( "action": "update", "device_id": entry.id, "changes": { - "config_entries": {config_entry_1.entry_id, config_entry_2.entry_id} + "config_entries": {config_entry_1.entry_id, config_entry_2.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: {None}, + config_entry_2.entry_id: {None}, + }, }, } assert update_events[4].data == { @@ -2112,6 +2683,11 @@ async def test_update_remove_config_entries( config_entry_2.entry_id, config_entry_3.entry_id, }, + "config_entries_subentries": { + config_entry_1.entry_id: {None}, + config_entry_2.entry_id: {None}, + config_entry_3.entry_id: {None}, + }, "primary_config_entry": config_entry_1.entry_id, }, } @@ -2119,7 +2695,11 @@ async def test_update_remove_config_entries( "action": "update", "device_id": entry2.id, "changes": { - "config_entries": {config_entry_2.entry_id, config_entry_3.entry_id} + "config_entries": {config_entry_2.entry_id, config_entry_3.entry_id}, + "config_entries_subentries": { + config_entry_2.entry_id: {None}, + config_entry_3.entry_id: {None}, + }, }, } assert update_events[6].data == { @@ -2128,6 +2708,282 @@ async def test_update_remove_config_entries( } +async def test_update_remove_config_subentries( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Make sure we do not get duplicate entries.""" + update_events = async_capture_events(hass, dr.EVENT_DEVICE_REGISTRY_UPDATED) + config_entry_1 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_1.add_to_hass(hass) + config_entry_2 = MockConfigEntry( + subentries_data=( + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ) + ) + config_entry_2.add_to_hass(hass) + config_entry_3 = MockConfigEntry() + config_entry_3.add_to_hass(hass) + + entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + identifiers={("bridgeid", "0123")}, + manufacturer="manufacturer", + model="model", + ) + entry_id = entry.id + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1"} + } + + entry = device_registry.async_update_device( + entry_id, + add_config_entry_id=config_entry_1.entry_id, + add_config_subentry_id="mock-subentry-id-1-2", + ) + assert entry.config_entries == {config_entry_1.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1", "mock-subentry-id-1-2"} + } + + # Try adding the same subentry again + assert ( + device_registry.async_update_device( + entry_id, + add_config_entry_id=config_entry_1.entry_id, + add_config_subentry_id="mock-subentry-id-1-2", + ) + is entry + ) + + entry = device_registry.async_update_device( + entry_id, + add_config_entry_id=config_entry_2.entry_id, + add_config_subentry_id="mock-subentry-id-2-1", + ) + assert entry.config_entries == {config_entry_1.entry_id, config_entry_2.entry_id} + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + } + + entry = device_registry.async_update_device( + entry_id, + add_config_entry_id=config_entry_3.entry_id, + add_config_subentry_id=None, + ) + assert entry.config_entries == { + config_entry_1.entry_id, + config_entry_2.entry_id, + config_entry_3.entry_id, + } + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-1", "mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + } + + # Try to add a subentry without specifying entry + with pytest.raises( + HomeAssistantError, + match="Can't add config subentry without specifying config entry", + ): + device_registry.async_update_device(entry_id, add_config_subentry_id="blabla") + + # Try to add an unknown subentry + with pytest.raises( + HomeAssistantError, + match=f"Config entry {config_entry_3.entry_id} has no subentry blabla", + ): + device_registry.async_update_device( + entry_id, + add_config_entry_id=config_entry_3.entry_id, + add_config_subentry_id="blabla", + ) + + # Try to remove a subentry without specifying entry + with pytest.raises( + HomeAssistantError, + match="Can't remove config subentry without specifying config entry", + ): + device_registry.async_update_device( + entry_id, remove_config_subentry_id="blabla" + ) + + assert len(device_registry.devices) == 1 + + entry = device_registry.async_update_device( + entry_id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-1-1", + ) + assert entry.config_entries == { + config_entry_1.entry_id, + config_entry_2.entry_id, + config_entry_3.entry_id, + } + assert entry.config_entries_subentries == { + config_entry_1.entry_id: {"mock-subentry-id-1-2"}, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + } + + # Try removing the same subentry again + assert ( + device_registry.async_update_device( + entry_id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-1-1", + ) + is entry + ) + + entry = device_registry.async_update_device( + entry_id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-1-2", + ) + assert entry.config_entries == {config_entry_2.entry_id, config_entry_3.entry_id} + assert entry.config_entries_subentries == { + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + } + + entry = device_registry.async_update_device( + entry_id, + remove_config_entry_id=config_entry_2.entry_id, + remove_config_subentry_id="mock-subentry-id-2-1", + ) + assert entry.config_entries == {config_entry_3.entry_id} + assert entry.config_entries_subentries == { + config_entry_3.entry_id: {None}, + } + + entry = device_registry.async_update_device( + entry_id, + remove_config_entry_id=config_entry_3.entry_id, + remove_config_subentry_id=None, + ) + assert entry is None + + await hass.async_block_till_done() + + assert len(update_events) == 8 + assert update_events[0].data == { + "action": "create", + "device_id": entry_id, + } + assert update_events[1].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: {"mock-subentry-id-1-1"} + }, + }, + } + assert update_events[2].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + } + }, + }, + } + assert update_events[3].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries": {config_entry_1.entry_id, config_entry_2.entry_id}, + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + }, + }, + } + assert update_events[4].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-1", + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + }, + }, + } + assert update_events[5].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries": { + config_entry_1.entry_id, + config_entry_2.entry_id, + config_entry_3.entry_id, + }, + "config_entries_subentries": { + config_entry_1.entry_id: { + "mock-subentry-id-1-2", + }, + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + }, + "primary_config_entry": config_entry_1.entry_id, + }, + } + assert update_events[6].data == { + "action": "update", + "device_id": entry_id, + "changes": { + "config_entries": {config_entry_2.entry_id, config_entry_3.entry_id}, + "config_entries_subentries": { + config_entry_2.entry_id: {"mock-subentry-id-2-1"}, + config_entry_3.entry_id: {None}, + }, + }, + } + assert update_events[7].data == { + "action": "remove", + "device_id": entry_id, + } + + async def test_update_suggested_area( hass: HomeAssistant, device_registry: dr.DeviceRegistry, @@ -2542,6 +3398,7 @@ async def test_restore_shared_device( "device_id": entry.id, "changes": { "config_entries": {config_entry_1.entry_id}, + "config_entries_subentries": {config_entry_1.entry_id: {None}}, "identifiers": {("entry_123", "0123")}, }, } @@ -2566,6 +3423,7 @@ async def test_restore_shared_device( "device_id": entry.id, "changes": { "config_entries": {config_entry_2.entry_id}, + "config_entries_subentries": {config_entry_2.entry_id: {None}}, "identifiers": {("entry_234", "2345")}, }, } @@ -2871,6 +3729,7 @@ async def test_loading_invalid_configuration_url_from_storage( { "area_id": None, "config_entries": ["1234"], + "config_entries_subentries": {"1234": [None]}, "configuration_url": "invalid", "connections": [], "created_at": "2024-01-01T00:00:00+00:00", diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 5e8c9fc88f7..6cf0e7c54d2 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -35,7 +35,7 @@ from homeassistant.core import ( from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr, entity, entity_registry as er from homeassistant.helpers.entity_component import async_update_entity -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import UNDEFINED, UndefinedType from tests.common import ( @@ -986,7 +986,7 @@ async def _test_friendly_name( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([ent]) @@ -1314,7 +1314,7 @@ async def test_entity_name_translation_placeholder_errors( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([ent]) @@ -1542,7 +1542,7 @@ async def test_friendly_name_updated( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( diff --git a/tests/helpers/test_entity_platform.py b/tests/helpers/test_entity_platform.py index eb076eb9f25..41b7271150a 100644 --- a/tests/helpers/test_entity_platform.py +++ b/tests/helpers/test_entity_platform.py @@ -11,7 +11,7 @@ import pytest from syrupy.assertion import SnapshotAssertion import voluptuous as vol -from homeassistant.config_entries import ConfigEntry +from homeassistant.config_entries import ConfigEntry, ConfigSubentryData from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, PERCENTAGE, EntityCategory from homeassistant.core import ( CoreState, @@ -36,7 +36,10 @@ from homeassistant.helpers.entity_component import ( DEFAULT_SCAN_INTERVAL, EntityComponent, ) -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddConfigEntryEntitiesCallback, + AddEntitiesCallback, +) from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import dt as dt_util @@ -223,7 +226,7 @@ async def test_set_scan_interval_via_platform(hass: HomeAssistant) -> None: def platform_setup( hass: HomeAssistant, config: ConfigType, - add_entities: entity_platform.AddEntitiesCallback, + add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Test the platform setup.""" @@ -862,13 +865,28 @@ async def test_setup_entry( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" - async_add_entities([MockEntity(name="test1", unique_id="unique")]) + async_add_entities([MockEntity(name="test1", unique_id="unique1")]) + async_add_entities( + [MockEntity(name="test2", unique_id="unique2")], + config_subentry_id="mock-subentry-id-1", + ) platform = MockPlatform(async_setup_entry=async_setup_entry) - config_entry = MockConfigEntry(entry_id="super-mock-id") + config_entry = MockConfigEntry( + entry_id="super-mock-id", + subentries_data=( + ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ), + ) config_entry.add_to_hass(hass) entity_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform @@ -878,11 +896,16 @@ async def test_setup_entry( await hass.async_block_till_done() full_name = f"{config_entry.domain}.{entity_platform.domain}" assert full_name in hass.config.components - assert len(hass.states.async_entity_ids()) == 1 - assert len(entity_registry.entities) == 1 + assert len(hass.states.async_entity_ids()) == 2 + assert len(entity_registry.entities) == 2 entity_registry_entry = entity_registry.entities["test_domain.test1"] assert entity_registry_entry.config_entry_id == "super-mock-id" + assert entity_registry_entry.config_subentry_id is None + + entity_registry_entry = entity_registry.entities["test_domain.test2"] + assert entity_registry_entry.config_entry_id == "super-mock-id" + assert entity_registry_entry.config_subentry_id == "mock-subentry-id-1" async def test_setup_entry_platform_not_ready( @@ -1138,7 +1161,18 @@ async def test_device_info_called( snapshot: SnapshotAssertion, ) -> None: """Test device info is forwarded correctly.""" - config_entry = MockConfigEntry(entry_id="super-mock-id") + config_entry = MockConfigEntry( + entry_id="super-mock-id", + subentries_data=( + ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ), + ) config_entry.add_to_hass(hass) via = device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, @@ -1151,7 +1185,7 @@ async def test_device_info_called( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -1177,6 +1211,28 @@ async def test_device_info_called( ), ] ) + async_add_entities( + [ + # Valid device info + MockEntity( + unique_id="efgh", + device_info={ + "identifiers": {("hue", "efgh")}, + "configuration_url": "http://192.168.0.100/config", + "connections": {(dr.CONNECTION_NETWORK_MAC, "efgh")}, + "manufacturer": "test-manuf", + "model": "test-model", + "name": "test-name", + "sw_version": "test-sw", + "hw_version": "test-hw", + "suggested_area": "Heliport", + "entry_type": dr.DeviceEntryType.SERVICE, + "via_device": ("hue", "via-id"), + }, + ), + ], + config_subentry_id="mock-subentry-id-1", + ) platform = MockPlatform(async_setup_entry=async_setup_entry) entity_platform = MockEntityPlatform( @@ -1186,11 +1242,20 @@ async def test_device_info_called( assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() - assert len(hass.states.async_entity_ids()) == 2 + assert len(hass.states.async_entity_ids()) == 3 device = device_registry.async_get_device(identifiers={("hue", "1234")}) assert device == snapshot assert device.config_entries == {config_entry.entry_id} + assert device.config_entries_subentries == {config_entry.entry_id: {None}} + assert device.primary_config_entry == config_entry.entry_id + assert device.via_device_id == via.id + device = device_registry.async_get_device(identifiers={("hue", "efgh")}) + assert device == snapshot + assert device.config_entries == {config_entry.entry_id} + assert device.config_entries_subentries == { + config_entry.entry_id: {"mock-subentry-id-1"} + } assert device.primary_config_entry == config_entry.entry_id assert device.via_device_id == via.id @@ -1214,7 +1279,7 @@ async def test_device_info_not_overrides( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -1267,7 +1332,7 @@ async def test_device_info_homeassistant_url( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -1319,7 +1384,7 @@ async def test_device_info_change_to_no_url( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -1391,7 +1456,7 @@ async def test_entity_disabled_by_device( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([entity_disabled]) @@ -1877,7 +1942,7 @@ async def test_setup_entry_with_entities_that_block_forever( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -1926,7 +1991,7 @@ async def test_cancellation_is_not_blocked( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -2024,7 +2089,7 @@ async def test_entity_name_influences_entity_id( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -2112,7 +2177,7 @@ async def test_translated_entity_name_influences_entity_id( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities( @@ -2200,7 +2265,7 @@ async def test_translated_device_class_name_influences_entity_id( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([TranslatedDeviceClassEntity(device_class, has_entity_name)]) @@ -2262,7 +2327,7 @@ async def test_device_name_defaulting_config_entry( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([DeviceNameEntity()]) @@ -2318,7 +2383,7 @@ async def test_device_type_error_checking( async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setup entry method.""" async_add_entities([DeviceNameEntity()]) @@ -2337,3 +2402,41 @@ async def test_device_type_error_checking( assert len(device_registry.devices) == 0 assert len(entity_registry.entities) == number_of_entities assert len(hass.states.async_all()) == number_of_entities + + +async def test_add_entity_unknown_subentry( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test adding an entity to an unknown subentry.""" + + async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, + ) -> None: + """Mock setup entry method.""" + async_add_entities( + [MockEntity(name="test", unique_id="unique")], + config_subentry_id="unknown-subentry", + ) + + platform = MockPlatform(async_setup_entry=async_setup_entry) + config_entry = MockConfigEntry(entry_id="super-mock-id") + config_entry.add_to_hass(hass) + entity_platform = MockEntityPlatform( + hass, platform_name=config_entry.domain, platform=platform + ) + + assert not await entity_platform.async_setup_entry(config_entry) + await hass.async_block_till_done() + full_name = f"{config_entry.domain}.{entity_platform.domain}" + assert full_name not in hass.config.components + assert len(hass.states.async_entity_ids()) == 0 + assert len(entity_registry.entities) == 0 + + assert ( + "Can't add entities to unknown subentry unknown-subentry " + "of config entry super-mock-id" + ) in caplog.text diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 19289b09f95..416f2d5121d 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -78,7 +78,19 @@ def test_get_or_create_updates_data( freezer: FrozenDateTimeFactory, ) -> None: """Test that we update data in get_or_create.""" - orig_config_entry = MockConfigEntry(domain="light") + config_subentry_id = "blabla" + orig_config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id=config_subentry_id, + subentry_type="test", + title="Mock title", + unique_id="test", + ) + ], + ) orig_config_entry.add_to_hass(hass) orig_device_entry = device_registry.async_get_or_create( config_entry_id=orig_config_entry.entry_id, @@ -93,6 +105,7 @@ def test_get_or_create_updates_data( "5678", capabilities={"max": 100}, config_entry=orig_config_entry, + config_subentry_id=config_subentry_id, device_id=orig_device_entry.id, disabled_by=er.RegistryEntryDisabler.HASS, entity_category=EntityCategory.CONFIG, @@ -114,6 +127,7 @@ def test_get_or_create_updates_data( "hue", capabilities={"max": 100}, config_entry_id=orig_config_entry.entry_id, + config_subentry_id=config_subentry_id, created_at=created, device_class=None, device_id=orig_device_entry.id, @@ -148,6 +162,7 @@ def test_get_or_create_updates_data( "5678", capabilities={"new-max": 150}, config_entry=new_config_entry, + config_subentry_id=None, device_id=new_device_entry.id, disabled_by=er.RegistryEntryDisabler.USER, entity_category=EntityCategory.DIAGNOSTIC, @@ -169,6 +184,7 @@ def test_get_or_create_updates_data( area_id=None, capabilities={"new-max": 150}, config_entry_id=new_config_entry.entry_id, + config_subentry_id=None, created_at=created, device_class=None, device_id=new_device_entry.id, @@ -496,6 +512,7 @@ async def test_load_bad_data( "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": "2024-02-14T12:00:00.900075+00:00", "device_class": None, "device_id": None, @@ -526,6 +543,7 @@ async def test_load_bad_data( "capabilities": None, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": "2024-02-14T12:00:00.900075+00:00", "device_class": None, "device_id": None, @@ -554,6 +572,7 @@ async def test_load_bad_data( "deleted_entities": [ { "config_entry_id": None, + "config_subentry_id": None, "created_at": "2024-02-14T12:00:00.900075+00:00", "entity_id": "test.test3", "id": "00003", @@ -564,6 +583,7 @@ async def test_load_bad_data( }, { "config_entry_id": None, + "config_subentry_id": None, "created_at": "2024-02-14T12:00:00.900075+00:00", "entity_id": "test.test4", "id": "00004", @@ -711,6 +731,118 @@ async def test_deleted_entity_removing_config_entry_id( assert entity_registry.deleted_entities[("light", "hue", "1234")] == deleted_entry2 +async def test_removing_config_subentry_id( + hass: HomeAssistant, entity_registry: er.EntityRegistry +) -> None: + """Test that we update config subentry id in registry.""" + update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) + mock_config = MockConfigEntry( + domain="light", + entry_id="mock-id-1", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ) + ], + ) + mock_config.add_to_hass(hass) + + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=mock_config, + config_subentry_id="mock-subentry-id-1", + ) + assert entry.config_subentry_id == "mock-subentry-id-1" + hass.config_entries.async_remove_subentry(mock_config, "mock-subentry-id-1") + + assert not entity_registry.entities + + await hass.async_block_till_done() + + assert len(update_events) == 2 + assert update_events[0].data == { + "action": "create", + "entity_id": entry.entity_id, + } + assert update_events[1].data == { + "action": "remove", + "entity_id": entry.entity_id, + } + + +async def test_deleted_entity_removing_config_subentry_id( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test that we update config subentry id in registry on deleted entity.""" + mock_config = MockConfigEntry( + domain="light", + entry_id="mock-id-1", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + mock_config.add_to_hass(hass) + + entry1 = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=mock_config, + config_subentry_id="mock-subentry-id-1", + ) + assert entry1.config_subentry_id == "mock-subentry-id-1" + entry2 = entity_registry.async_get_or_create( + "light", + "hue", + "1234", + config_entry=mock_config, + config_subentry_id="mock-subentry-id-2", + ) + assert entry2.config_subentry_id == "mock-subentry-id-2" + entity_registry.async_remove(entry1.entity_id) + entity_registry.async_remove(entry2.entity_id) + + assert len(entity_registry.entities) == 0 + assert len(entity_registry.deleted_entities) == 2 + deleted_entry1 = entity_registry.deleted_entities[("light", "hue", "5678")] + assert deleted_entry1.config_entry_id == "mock-id-1" + assert deleted_entry1.config_subentry_id == "mock-subentry-id-1" + assert deleted_entry1.orphaned_timestamp is None + deleted_entry2 = entity_registry.deleted_entities[("light", "hue", "1234")] + assert deleted_entry2.config_entry_id == "mock-id-1" + assert deleted_entry2.config_subentry_id == "mock-subentry-id-2" + assert deleted_entry2.orphaned_timestamp is None + + hass.config_entries.async_remove_subentry(mock_config, "mock-subentry-id-1") + assert len(entity_registry.entities) == 0 + assert len(entity_registry.deleted_entities) == 2 + deleted_entry1 = entity_registry.deleted_entities[("light", "hue", "5678")] + assert deleted_entry1.config_entry_id is None + assert deleted_entry1.config_subentry_id is None + assert deleted_entry1.orphaned_timestamp is not None + assert entity_registry.deleted_entities[("light", "hue", "1234")] == deleted_entry2 + + async def test_removing_area_id(entity_registry: er.EntityRegistry) -> None: """Make sure we can clear area id.""" entry = entity_registry.async_get_or_create("light", "hue", "5678") @@ -766,6 +898,7 @@ async def test_migration_1_1(hass: HomeAssistant, hass_storage: dict[str, Any]) "capabilities": {}, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": "1970-01-01T00:00:00+00:00", "device_id": None, "disabled_by": None, @@ -944,6 +1077,7 @@ async def test_migration_1_11( "capabilities": {}, "categories": {}, "config_entry_id": None, + "config_subentry_id": None, "created_at": "1970-01-01T00:00:00+00:00", "device_id": None, "disabled_by": None, @@ -972,6 +1106,7 @@ async def test_migration_1_11( "deleted_entities": [ { "config_entry_id": None, + "config_subentry_id": None, "created_at": "1970-01-01T00:00:00+00:00", "entity_id": "test.deleted_entity", "id": "23456", @@ -1431,7 +1566,7 @@ async def test_remove_config_entry_from_device_removes_entities_2( config_entry_2.entry_id, } - # Create one entity for each config entry + # Create an entity without config entry entry_1 = entity_registry.async_get_or_create( "light", "hue", @@ -1451,6 +1586,208 @@ async def test_remove_config_entry_from_device_removes_entities_2( assert entity_registry.async_is_registered(entry_1.entity_id) +async def test_remove_config_subentry_from_device_removes_entities( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: + """Test that we remove entities tied to a device when config subentry is removed.""" + config_entry_1 = MockConfigEntry( + domain="hue", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + config_entry_1.add_to_hass(hass) + + # Create device with three config subentries + device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-2", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + device_entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + assert device_entry.config_entries == {config_entry_1.entry_id} + assert device_entry.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1", "mock-subentry-id-2"}, + } + + # Create one entity entry for each config entry or subentry + entry_1 = entity_registry.async_get_or_create( + "light", + "hue", + "1234", + config_entry=config_entry_1, + config_subentry_id="mock-subentry-id-1", + device_id=device_entry.id, + ) + + entry_2 = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=config_entry_1, + config_subentry_id="mock-subentry-id-2", + device_id=device_entry.id, + ) + + entry_3 = entity_registry.async_get_or_create( + "sensor", + "device_tracker", + "6789", + config_entry=config_entry_1, + config_subentry_id=None, + device_id=device_entry.id, + ) + + assert entity_registry.async_is_registered(entry_1.entity_id) + assert entity_registry.async_is_registered(entry_2.entity_id) + assert entity_registry.async_is_registered(entry_3.entity_id) + + # Remove the first config subentry from the device, the entity associated with it + # should be removed + device_registry.async_update_device( + device_entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-1", + ) + await hass.async_block_till_done() + + assert device_registry.async_get(device_entry.id) + assert not entity_registry.async_is_registered(entry_1.entity_id) + assert entity_registry.async_is_registered(entry_2.entity_id) + assert entity_registry.async_is_registered(entry_3.entity_id) + + # Remove the second config subentry from the device, the entity associated with it + # should be removed + device_registry.async_update_device( + device_entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id=None, + ) + await hass.async_block_till_done() + + assert device_registry.async_get(device_entry.id) + assert not entity_registry.async_is_registered(entry_1.entity_id) + assert entity_registry.async_is_registered(entry_2.entity_id) + assert not entity_registry.async_is_registered(entry_3.entity_id) + + # Remove the third config subentry from the device, the entity associated with it + # (and the device itself) should be removed + device_registry.async_update_device( + device_entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-2", + ) + await hass.async_block_till_done() + + assert not device_registry.async_get(device_entry.id) + assert not entity_registry.async_is_registered(entry_1.entity_id) + assert not entity_registry.async_is_registered(entry_2.entity_id) + assert not entity_registry.async_is_registered(entry_3.entity_id) + + +async def test_remove_config_subentry_from_device_removes_entities_2( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: + """Test that we don't remove entities with no config entry when device is modified.""" + config_entry_1 = MockConfigEntry( + domain="hue", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + config_entry_1.add_to_hass(hass) + + # Create device with three config subentries + device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-1", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + config_subentry_id="mock-subentry-id-2", + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + device_entry = device_registry.async_get_or_create( + config_entry_id=config_entry_1.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + assert device_entry.config_entries == {config_entry_1.entry_id} + assert device_entry.config_entries_subentries == { + config_entry_1.entry_id: {None, "mock-subentry-id-1", "mock-subentry-id-2"}, + } + + # Create an entity without config entry or subentry + entry_1 = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + device_id=device_entry.id, + ) + + assert entity_registry.async_is_registered(entry_1.entity_id) + + # Remove the first config subentry from the device + device_registry.async_update_device( + device_entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id=None, + ) + await hass.async_block_till_done() + + assert device_registry.async_get(device_entry.id) + assert entity_registry.async_is_registered(entry_1.entity_id) + + # Remove the second config subentry from the device + device_registry.async_update_device( + device_entry.id, + remove_config_entry_id=config_entry_1.entry_id, + remove_config_subentry_id="mock-subentry-id-1", + ) + await hass.async_block_till_done() + + assert device_registry.async_get(device_entry.id) + assert entity_registry.async_is_registered(entry_1.entity_id) + + async def test_update_device_race( hass: HomeAssistant, device_registry: dr.DeviceRegistry, @@ -1881,11 +2218,45 @@ async def test_unique_id_non_string( ) +@pytest.mark.parametrize( + ("create_kwargs", "migrate_kwargs", "new_subentry_id"), + [ + ({}, {}, None), + ({"config_subentry_id": None}, {}, None), + ({}, {"new_config_subentry_id": None}, None), + ({}, {"new_config_subentry_id": "mock-subentry-id-2"}, "mock-subentry-id-2"), + ( + {"config_subentry_id": "mock-subentry-id-1"}, + {"new_config_subentry_id": None}, + None, + ), + ( + {"config_subentry_id": "mock-subentry-id-1"}, + {"new_config_subentry_id": "mock-subentry-id-2"}, + "mock-subentry-id-2", + ), + ], +) def test_migrate_entity_to_new_platform( - hass: HomeAssistant, entity_registry: er.EntityRegistry + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + create_kwargs: dict, + migrate_kwargs: dict, + new_subentry_id: str | None, ) -> None: """Test migrate_entity_to_new_platform.""" - orig_config_entry = MockConfigEntry(domain="light") + orig_config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) orig_config_entry.add_to_hass(hass) orig_unique_id = "5678" @@ -1900,6 +2271,7 @@ def test_migrate_entity_to_new_platform( original_device_class="mock-device-class", original_icon="initial-original_icon", original_name="initial-original_name", + **create_kwargs, ) assert entity_registry.async_get("light.light") is orig_entry entity_registry.async_update_entity( @@ -1908,7 +2280,18 @@ def test_migrate_entity_to_new_platform( icon="new_icon", ) - new_config_entry = MockConfigEntry(domain="light") + new_config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) new_config_entry.add_to_hass(hass) new_unique_id = "1234" @@ -1917,6 +2300,7 @@ def test_migrate_entity_to_new_platform( "hue2", new_unique_id=new_unique_id, new_config_entry_id=new_config_entry.entry_id, + **migrate_kwargs, ) assert not entity_registry.async_get_entity_id("light", "hue", orig_unique_id) @@ -1924,6 +2308,7 @@ def test_migrate_entity_to_new_platform( assert (new_entry := entity_registry.async_get("light.light")) is not orig_entry assert new_entry.config_entry_id == new_config_entry.entry_id + assert new_entry.config_subentry_id == new_subentry_id assert new_entry.unique_id == new_unique_id assert new_entry.name == "new_name" assert new_entry.icon == "new_icon" @@ -1956,6 +2341,99 @@ def test_migrate_entity_to_new_platform( ) +def test_migrate_entity_to_new_platform_error_handling( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test migrate_entity_to_new_platform.""" + orig_config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + orig_config_entry.add_to_hass(hass) + orig_unique_id = "5678" + + orig_entry = entity_registry.async_get_or_create( + "light", + "hue", + orig_unique_id, + suggested_object_id="light", + config_entry=orig_config_entry, + config_subentry_id="mock-subentry-id-1", + disabled_by=er.RegistryEntryDisabler.USER, + entity_category=EntityCategory.CONFIG, + original_device_class="mock-device-class", + original_icon="initial-original_icon", + original_name="initial-original_name", + ) + assert entity_registry.async_get("light.light") is orig_entry + + new_config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + new_config_entry.add_to_hass(hass) + new_unique_id = "1234" + + # Test migrating nonexisting entity + with pytest.raises(KeyError, match="'light.not_a_real_light'"): + entity_registry.async_update_entity_platform( + "light.not_a_real_light", + "hue2", + new_unique_id=new_unique_id, + new_config_entry_id=new_config_entry.entry_id, + ) + + # Test migrate entity without new config entry ID + with pytest.raises( + ValueError, + match="new_config_entry_id required because light.light is already linked to a config entry", + ): + entity_registry.async_update_entity_platform( + "light.light", + "hue3", + ) + + # Test migrate entity without new config subentry ID + with pytest.raises( + ValueError, + match="Can't change config entry without changing subentry", + ): + entity_registry.async_update_entity_platform( + "light.light", + "hue3", + new_config_entry_id=new_config_entry.entry_id, + ) + + # Test entity with a state + hass.states.async_set("light.light", "on") + with pytest.raises( + ValueError, match="Only entities that haven't been loaded can be migrated" + ): + entity_registry.async_update_entity_platform( + "light.light", + "hue2", + new_unique_id=new_unique_id, + new_config_entry_id=new_config_entry.entry_id, + ) + + async def test_restore_entity( hass: HomeAssistant, entity_registry: er.EntityRegistry, @@ -1963,13 +2441,28 @@ async def test_restore_entity( ) -> None: """Make sure entity registry id is stable and entity_id is reused if possible.""" update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) - config_entry = MockConfigEntry(domain="light") + config_entry = MockConfigEntry( + domain="light", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) config_entry.add_to_hass(hass) entry1 = entity_registry.async_get_or_create( "light", "hue", "1234", config_entry=config_entry ) entry2 = entity_registry.async_get_or_create( - "light", "hue", "5678", config_entry=config_entry + "light", + "hue", + "5678", + config_entry=config_entry, + config_subentry_id="mock-subentry-id-1-1", ) entry1 = entity_registry.async_update_entity( @@ -1993,8 +2486,11 @@ async def test_restore_entity( # entity_id is not restored assert attr.evolve(entry1, entity_id="light.hue_1234") == entry1_restored assert entry2 != entry2_restored - # Config entry is not restored - assert attr.evolve(entry2, config_entry_id=None) == entry2_restored + # Config entry and subentry are not restored + assert ( + attr.evolve(entry2, config_entry_id=None, config_subentry_id=None) + == entry2_restored + ) # Remove two of the entities again, then bump time entity_registry.async_remove(entry1_restored.entity_id) @@ -2305,3 +2801,132 @@ async def test_async_remove_thread_safety( match="Detected code that calls entity_registry.async_remove from a thread.", ): await hass.async_add_executor_job(entity_registry.async_remove, entry.entity_id) + + +async def test_subentry( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test subentry error handling.""" + entry1 = MockConfigEntry( + domain="light", + entry_id="mock-id-1", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-1-2", + subentry_type="test", + title="Mock title", + unique_id="test", + ), + ], + ) + entry1.add_to_hass(hass) + entry2 = MockConfigEntry( + domain="light", + entry_id="mock-id-2", + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="mock-subentry-id-2-1", + subentry_type="test", + title="Mock title", + unique_id="test", + ) + ], + ) + entry2.add_to_hass(hass) + + with pytest.raises( + ValueError, match="Config entry mock-id-1 has no subentry bad-subentry-id" + ): + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry1, + config_subentry_id="bad-subentry-id", + ) + + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry1, + config_subentry_id="mock-subentry-id-1-1", + ) + assert entry.config_subentry_id == "mock-subentry-id-1-1" + + # Try updating subentry + with pytest.raises( + ValueError, match="Config entry mock-id-1 has no subentry bad-subentry-id" + ): + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry1, + config_subentry_id="bad-subentry-id", + ) + + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry1, + config_subentry_id="mock-subentry-id-1-2", + ) + assert entry.config_subentry_id == "mock-subentry-id-1-2" + + with pytest.raises( + ValueError, match="Can't change config entry without changing subentry" + ): + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry2, + ) + + with pytest.raises( + ValueError, match="Config entry mock-id-2 has no subentry mock-subentry-id-1-2" + ): + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry2, + config_subentry_id="mock-subentry-id-1-2", + ) + + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry2, + config_subentry_id="mock-subentry-id-2-1", + ) + assert entry.config_subentry_id == "mock-subentry-id-2-1" + + entry = entity_registry.async_get_or_create( + "light", + "hue", + "5678", + config_entry=entry1, + config_subentry_id=None, + ) + assert entry.config_subentry_id is None + + entry = entity_registry.async_update_entity( + entry.entity_id, + config_entry_id=entry2.entry_id, + config_subentry_id="mock-subentry-id-2-1", + ) + assert entry.config_subentry_id == "mock-subentry-id-2-1" diff --git a/tests/pylint/test_enforce_type_hints.py b/tests/pylint/test_enforce_type_hints.py index 6c53e9832d9..efa3ca9523a 100644 --- a/tests/pylint/test_enforce_type_hints.py +++ b/tests/pylint/test_enforce_type_hints.py @@ -1370,7 +1370,7 @@ def test_valid_generic( async def async_setup_entry( #@ hass: HomeAssistant, entry: {entry_annotation}, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: pass """, @@ -1402,7 +1402,7 @@ def test_invalid_generic( async def async_setup_entry( #@ hass: HomeAssistant, entry: {entry_annotation}, #@ - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: pass """, diff --git a/tests/snapshots/test_config_entries.ambr b/tests/snapshots/test_config_entries.ambr index 51e56f4874e..08b532677f4 100644 --- a/tests/snapshots/test_config_entries.ambr +++ b/tests/snapshots/test_config_entries.ambr @@ -16,6 +16,8 @@ 'pref_disable_new_entities': False, 'pref_disable_polling': False, 'source': 'user', + 'subentries': list([ + ]), 'title': 'Mock Title', 'unique_id': None, 'version': 1, diff --git a/tests/syrupy.py b/tests/syrupy.py index 5b1e5faa23d..3c8e398f0f8 100644 --- a/tests/syrupy.py +++ b/tests/syrupy.py @@ -160,6 +160,7 @@ class HomeAssistantSnapshotSerializer(AmberDataSerializer): attrs.asdict(data) | { "config_entries": ANY, + "config_entries_subentries": ANY, "id": ANY, } ) @@ -188,6 +189,7 @@ class HomeAssistantSnapshotSerializer(AmberDataSerializer): attrs.asdict(data) | { "config_entry_id": ANY, + "config_subentry_id": ANY, "device_id": ANY, "id": ANY, "options": {k: dict(v) for k, v in data.options.items()}, diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 3ea1a16e898..a5cf3ad3a1a 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -4,6 +4,7 @@ from __future__ import annotations import asyncio from collections.abc import Generator +from contextlib import AbstractContextManager, nullcontext as does_not_raise from datetime import timedelta import logging import re @@ -38,7 +39,7 @@ from homeassistant.exceptions import ( ) from homeassistant.helpers import entity_registry as er, frame, issue_registry as ir from homeassistant.helpers.discovery_flow import DiscoveryKey -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.json import json_dumps from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo from homeassistant.helpers.service_info.hassio import HassioServiceInfo @@ -468,7 +469,7 @@ async def test_remove_entry( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" async_add_entities([entity]) @@ -511,6 +512,7 @@ async def test_remove_entry( assert len(entity_registry.entities) == 1 entity_entry = list(entity_registry.entities.values())[0] assert entity_entry.config_entry_id == entry.entry_id + assert entity_entry.config_subentry_id is None # Remove entry result = await manager.async_remove("test2") @@ -905,7 +907,7 @@ async def test_entries_excludes_ignore_and_disabled( async def test_saving_and_loading( - hass: HomeAssistant, freezer: FrozenDateTimeFactory + hass: HomeAssistant, freezer: FrozenDateTimeFactory, hass_storage: dict[str, Any] ) -> None: """Test that we're saving and loading correctly.""" mock_integration( @@ -922,7 +924,20 @@ async def test_saving_and_loading( async def async_step_user(self, user_input=None): """Test user step.""" await self.async_set_unique_id("unique") - return self.async_create_entry(title="Test Title", data={"token": "abcd"}) + subentries = [ + config_entries.ConfigSubentryData( + data={"foo": "bar"}, subentry_type="test", title="subentry 1" + ), + config_entries.ConfigSubentryData( + data={"sun": "moon"}, + subentry_type="test", + title="subentry 2", + unique_id="very_unique", + ), + ] + return self.async_create_entry( + title="Test Title", data={"token": "abcd"}, subentries=subentries + ) with mock_config_flow("test", TestFlow): await hass.config_entries.flow.async_init( @@ -971,6 +986,100 @@ async def test_saving_and_loading( # To execute the save await hass.async_block_till_done() + stored_data = hass_storage["core.config_entries"] + assert stored_data == { + "data": { + "entries": [ + { + "created_at": ANY, + "data": { + "token": "abcd", + }, + "disabled_by": None, + "discovery_keys": {}, + "domain": "test", + "entry_id": ANY, + "minor_version": 1, + "modified_at": ANY, + "options": {}, + "pref_disable_new_entities": True, + "pref_disable_polling": True, + "source": "user", + "subentries": [ + { + "data": {"foo": "bar"}, + "subentry_id": ANY, + "subentry_type": "test", + "title": "subentry 1", + "unique_id": None, + }, + { + "data": {"sun": "moon"}, + "subentry_id": ANY, + "subentry_type": "test", + "title": "subentry 2", + "unique_id": "very_unique", + }, + ], + "title": "Test Title", + "unique_id": "unique", + "version": 5, + }, + { + "created_at": ANY, + "data": { + "username": "bla", + }, + "disabled_by": None, + "discovery_keys": { + "test": [ + {"domain": "test", "key": "blah", "version": 1}, + ], + }, + "domain": "test", + "entry_id": ANY, + "minor_version": 1, + "modified_at": ANY, + "options": {}, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "source": "user", + "subentries": [], + "title": "Test 2 Title", + "unique_id": None, + "version": 3, + }, + { + "created_at": ANY, + "data": { + "username": "bla", + }, + "disabled_by": None, + "discovery_keys": { + "test": [ + {"domain": "test", "key": ["a", "b"], "version": 1}, + ], + }, + "domain": "test", + "entry_id": ANY, + "minor_version": 1, + "modified_at": ANY, + "options": {}, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "source": "user", + "subentries": [], + "title": "Test 2 Title", + "unique_id": None, + "version": 3, + }, + ], + }, + "key": "core.config_entries", + "minor_version": 5, + "version": 1, + } + # Now load written data in new config manager manager = config_entries.ConfigEntries(hass, {}) await manager.async_initialize() @@ -983,6 +1092,25 @@ async def test_saving_and_loading( ): assert orig.as_dict() == loaded.as_dict() + hass.config_entries.async_update_entry( + entry_1, + pref_disable_polling=False, + pref_disable_new_entities=False, + ) + + # To trigger the call_later + freezer.tick(1.0) + async_fire_time_changed(hass) + # To execute the save + await hass.async_block_till_done() + + # Assert no data is lost when storing again + expected_stored_data = stored_data + expected_stored_data["data"]["entries"][0]["modified_at"] = ANY + expected_stored_data["data"]["entries"][0]["pref_disable_new_entities"] = False + expected_stored_data["data"]["entries"][0]["pref_disable_polling"] = False + assert hass_storage["core.config_entries"] == expected_stored_data | {} + @freeze_time("2024-02-14 12:00:00") async def test_as_dict(snapshot: SnapshotAssertion) -> None: @@ -1144,7 +1272,7 @@ async def test_discovery_notification( notifications = async_get_persistent_notifications(hass) assert "config_entry_discovery" not in notifications - # Start first discovery flow to assert that reconfigure notification fires + # Start first discovery flow to assert that discovery notification fires flow1 = await hass.config_entries.flow.async_init( "test", context={"source": config_entries.SOURCE_DISCOVERY} ) @@ -1416,6 +1544,45 @@ async def test_update_entry_options_and_trigger_listener( assert len(update_listener_calls) == 1 +async def test_update_subentry_and_trigger_listener( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test that we can update subentry and trigger listener.""" + entry = MockConfigEntry(domain="test", options={"first": True}) + entry.add_to_manager(manager) + update_listener_calls = [] + + subentry = config_entries.ConfigSubentry( + data={"test": "test"}, + subentry_type="test", + unique_id="test", + title="Mock title", + ) + + async def update_listener( + hass: HomeAssistant, entry: config_entries.ConfigEntry + ) -> None: + """Test function.""" + assert entry.subentries == expected_subentries + update_listener_calls.append(None) + + entry.add_update_listener(update_listener) + + expected_subentries = {subentry.subentry_id: subentry} + assert manager.async_add_subentry(entry, subentry) is True + + await hass.async_block_till_done(wait_background_tasks=True) + assert entry.subentries == expected_subentries + assert len(update_listener_calls) == 1 + + expected_subentries = {} + assert manager.async_remove_subentry(entry, subentry.subentry_id) is True + + await hass.async_block_till_done(wait_background_tasks=True) + assert entry.subentries == expected_subentries + assert len(update_listener_calls) == 2 + + async def test_setup_raise_not_ready( hass: HomeAssistant, manager: config_entries.ConfigEntries, @@ -1742,20 +1909,413 @@ async def test_entry_options_unknown_config_entry( mock_integration(hass, MockModule("test")) mock_platform(hass, "test.config_flow", None) - class TestFlow: - """Test flow.""" - - @staticmethod - @callback - def async_get_options_flow(config_entry): - """Test options flow.""" - with pytest.raises(config_entries.UnknownEntry): await manager.options.async_create_flow( "blah", context={"source": "test"}, data=None ) +async def test_create_entry_subentries( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test a config entry being created with subentries.""" + + subentrydata = config_entries.ConfigSubentryData( + data={"test": "test"}, + title="Mock title", + subentry_type="test", + unique_id="test", + ) + + async def mock_async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Mock setup.""" + hass.async_create_task( + hass.config_entries.flow.async_init( + "comp", + context={"source": config_entries.SOURCE_IMPORT}, + data={"data": "data", "subentry": subentrydata}, + ) + ) + return True + + async_setup_entry = AsyncMock(return_value=True) + mock_integration( + hass, + MockModule( + "comp", async_setup=mock_async_setup, async_setup_entry=async_setup_entry + ), + ) + mock_platform(hass, "comp.config_flow", None) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + VERSION = 1 + + async def async_step_import(self, user_input): + """Test import step creating entry, with subentry.""" + return self.async_create_entry( + title="title", + data={"example": user_input["data"]}, + subentries=[user_input["subentry"]], + ) + + with patch.dict(config_entries.HANDLERS, {"comp": TestFlow}): + assert await async_setup_component(hass, "comp", {}) + + await hass.async_block_till_done() + + assert len(async_setup_entry.mock_calls) == 1 + + entries = hass.config_entries.async_entries("comp") + assert len(entries) == 1 + assert entries[0].supported_subentry_types == {} + assert entries[0].data == {"example": "data"} + assert len(entries[0].subentries) == 1 + subentry_id = list(entries[0].subentries)[0] + subentry = config_entries.ConfigSubentry( + data=subentrydata["data"], + subentry_id=subentry_id, + subentry_type="test", + title=subentrydata["title"], + unique_id="test", + ) + assert entries[0].subentries == {subentry_id: subentry} + + +async def test_entry_subentry( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test that we can add a subentry to an entry.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow): + flow = await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry + + await manager.subentries.async_finish_flow( + flow, + { + "data": {"second": True}, + "title": "Mock title", + "type": data_entry_flow.FlowResultType.CREATE_ENTRY, + "unique_id": "test", + }, + ) + + assert entry.data == {"first": True} + assert entry.options == {} + subentry_id = list(entry.subentries)[0] + assert entry.subentries == { + subentry_id: config_entries.ConfigSubentry( + data={"second": True}, + subentry_id=subentry_id, + subentry_type="test", + title="Mock title", + unique_id="test", + ) + } + assert entry.supported_subentry_types == { + "test": {"supports_reconfigure": False} + } + + +async def test_entry_subentry_non_string( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test adding an invalid subentry to an entry.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow): + flow = await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry + + with pytest.raises(HomeAssistantError): + await manager.subentries.async_finish_flow( + flow, + { + "data": {"second": True}, + "title": "Mock title", + "type": data_entry_flow.FlowResultType.CREATE_ENTRY, + "unique_id": 123, + }, + ) + + +@pytest.mark.parametrize("context", [None, {}, {"bla": "bleh"}]) +async def test_entry_subentry_no_context( + hass: HomeAssistant, manager: config_entries.ConfigEntries, context: dict | None +) -> None: + """Test starting a subentry flow without "source" in context.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow), pytest.raises(KeyError): + await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context=context, data=None + ) + + +@pytest.mark.parametrize( + ("unique_id", "expected_result"), + [(None, does_not_raise()), ("test", pytest.raises(HomeAssistantError))], +) +async def test_entry_subentry_duplicate( + hass: HomeAssistant, + manager: config_entries.ConfigEntries, + unique_id: str | None, + expected_result: AbstractContextManager, +) -> None: + """Test adding a duplicated subentry to an entry.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry( + domain="test", + data={"first": True}, + subentries_data=[ + config_entries.ConfigSubentryData( + data={}, + subentry_id="blabla", + subentry_type="test", + title="Mock title", + unique_id=unique_id, + ) + ], + ) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow): + flow = await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry + + with expected_result: + await manager.subentries.async_finish_flow( + flow, + { + "data": {"second": True}, + "title": "Mock title", + "type": data_entry_flow.FlowResultType.CREATE_ENTRY, + "unique_id": unique_id, + }, + ) + + +async def test_entry_subentry_abort( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test that we can abort subentry flow.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow): + flow = await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry + + assert await manager.subentries.async_finish_flow( + flow, {"type": data_entry_flow.FlowResultType.ABORT, "reason": "test"} + ) + + +async def test_entry_subentry_unknown_config_entry( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test attempting to start a subentry flow for an unknown config entry.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + + with pytest.raises(config_entries.UnknownEntry): + await manager.subentries.async_create_flow( + ("blah", "blah"), context={"source": "test"}, data=None + ) + + +async def test_entry_subentry_deleted_config_entry( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test attempting to finish a subentry flow for a deleted config entry.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with mock_config_flow("test", TestFlow): + flow = await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry + + await hass.config_entries.async_remove(entry.entry_id) + + with pytest.raises(config_entries.UnknownEntry): + await manager.subentries.async_finish_flow( + flow, + { + "data": {"second": True}, + "title": "Mock title", + "type": data_entry_flow.FlowResultType.CREATE_ENTRY, + "unique_id": "test", + }, + ) + + +async def test_entry_subentry_unsupported_subentry_type( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test attempting to start a subentry flow for a config entry without support.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + class SubentryFlowHandler(config_entries.ConfigSubentryFlow): + """Test subentry flow handler.""" + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry: ConfigEntry + ) -> dict[str, type[config_entries.ConfigSubentryFlow]]: + return {"test": TestFlow.SubentryFlowHandler} + + with ( + mock_config_flow("test", TestFlow), + pytest.raises(data_entry_flow.UnknownHandler), + ): + await manager.subentries.async_create_flow( + ( + entry.entry_id, + "unknown", + ), + context={"source": "test"}, + data=None, + ) + + +async def test_entry_subentry_unsupported( + hass: HomeAssistant, manager: config_entries.ConfigEntries +) -> None: + """Test attempting to start a subentry flow for a config entry without support.""" + mock_integration(hass, MockModule("test")) + mock_platform(hass, "test.config_flow", None) + entry = MockConfigEntry(domain="test", data={"first": True}) + entry.add_to_manager(manager) + + class TestFlow(config_entries.ConfigFlow): + """Test flow.""" + + with ( + mock_config_flow("test", TestFlow), + pytest.raises(data_entry_flow.UnknownHandler), + ): + await manager.subentries.async_create_flow( + (entry.entry_id, "test"), context={"source": "test"}, data=None + ) + + async def test_entry_setup_succeed( hass: HomeAssistant, manager: config_entries.ConfigEntries ) -> None: @@ -3909,21 +4469,20 @@ async def test_updating_entry_with_and_without_changes( assert manager.async_update_entry(entry) is False - for change in ( - {"data": {"second": True, "third": 456}}, - {"data": {"second": True}}, - {"minor_version": 2}, - {"options": {"hello": True}}, - {"pref_disable_new_entities": True}, - {"pref_disable_polling": True}, - {"title": "sometitle"}, - {"unique_id": "abcd1234"}, - {"version": 2}, + for change, expected_value in ( + ({"data": {"second": True, "third": 456}}, {"second": True, "third": 456}), + ({"data": {"second": True}}, {"second": True}), + ({"minor_version": 2}, 2), + ({"options": {"hello": True}}, {"hello": True}), + ({"pref_disable_new_entities": True}, True), + ({"pref_disable_polling": True}, True), + ({"title": "sometitle"}, "sometitle"), + ({"unique_id": "abcd1234"}, "abcd1234"), + ({"version": 2}, 2), ): assert manager.async_update_entry(entry, **change) is True key = next(iter(change)) - value = next(iter(change.values())) - assert getattr(entry, key) == value + assert getattr(entry, key) == expected_value assert manager.async_update_entry(entry, **change) is False assert manager.async_entry_for_domain_unique_id("test", "abc123") is None @@ -5457,6 +6016,7 @@ async def test_unhashable_unique_id_fails( minor_version=1, options={}, source="test", + subentries_data=(), title="title", unique_id=unique_id, version=1, @@ -5492,6 +6052,7 @@ async def test_unhashable_unique_id_fails_on_update( minor_version=1, options={}, source="test", + subentries_data=(), title="title", unique_id="123", version=1, @@ -5522,6 +6083,7 @@ async def test_string_unique_id_no_warning( minor_version=1, options={}, source="test", + subentries_data=(), title="title", unique_id="123", version=1, @@ -5564,6 +6126,7 @@ async def test_hashable_unique_id( minor_version=1, options={}, source="test", + subentries_data=(), title="title", unique_id=unique_id, version=1, @@ -5598,6 +6161,7 @@ async def test_no_unique_id_no_warning( minor_version=1, options={}, source="test", + subentries_data=(), title="title", unique_id=None, version=1, @@ -6062,7 +6626,7 @@ async def test_raise_wrong_exception_in_forwarded_platform( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" raise exc @@ -6136,7 +6700,7 @@ async def test_config_entry_unloaded_during_platform_setups( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" await asyncio.sleep(0) @@ -6208,7 +6772,7 @@ async def test_non_awaited_async_forward_entry_setups( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" await forward_event.wait() @@ -6280,7 +6844,7 @@ async def test_non_awaited_async_forward_entry_setup( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" await forward_event.wait() @@ -6355,7 +6919,7 @@ async def test_config_entry_unloaded_during_platform_setup( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" await asyncio.sleep(0) @@ -6430,7 +6994,7 @@ async def test_config_entry_late_platform_setup( async def mock_setup_entry_platform( hass: HomeAssistant, entry: config_entries.ConfigEntry, - async_add_entities: AddEntitiesCallback, + async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Mock setting up platform.""" await asyncio.sleep(0) @@ -6522,6 +7086,7 @@ async def test_migration_from_1_2( "pref_disable_new_entities": False, "pref_disable_polling": False, "source": "import", + "subentries": {}, "title": "Sun", "unique_id": None, "version": 1, @@ -6848,7 +7413,7 @@ async def test_get_reauth_entry( async def test_get_reconfigure_entry( hass: HomeAssistant, manager: config_entries.ConfigEntries ) -> None: - """Test _get_context_entry behavior.""" + """Test _get_reconfigure_entry behavior.""" entry = MockConfigEntry( title="test_title", domain="test",