Skip to content
Merged
28 changes: 23 additions & 5 deletions homeassistant/components/fritzbox/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
from .const import CONF_COORDINATOR, DOMAIN
from .coordinator import FritzboxDataUpdateCoordinator
from .model import FritzEntityDescriptionMixinBase

Expand Down Expand Up @@ -68,9 +68,27 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome binary sensor from ConfigEntry."""
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
[

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the brackets to make it a generator expression instead of a list comprehension.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FritzboxBinarySensor(coordinator, ain, description)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", [])
for description in BINARY_SENSOR_TYPES
if description.suitable(device)
]
Comment thread
mib1185 marked this conversation as resolved.
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
[
Expand Down
24 changes: 18 additions & 6 deletions homeassistant/components/fritzbox/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,33 @@

from homeassistant.components.button import ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzboxDataUpdateCoordinator, FritzBoxEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
from .const import CONF_COORDINATOR, DOMAIN


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome template from ConfigEntry."""
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

def _add_new_templates(event: Event) -> None:
"""Add newly discovered template."""
async_add_entities(
[FritzBoxTemplate(coordinator, ain) for ain in event.data.get("ains", [])]
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_templates", _add_new_templates
)
)

async_add_entities(
[FritzBoxTemplate(coordinator, ain) for ain in coordinator.data.templates]
Expand All @@ -37,7 +49,7 @@ def device_info(self) -> DeviceInfo:
"""Return device specific attributes."""
return DeviceInfo(
name=self.data.name,
identifiers={(FRITZBOX_DOMAIN, self.ain)},
identifiers={(DOMAIN, self.ain)},
configuration_url=self.coordinator.configuration_url,
manufacturer="AVM",
model="SmartHome Template",
Expand Down
26 changes: 21 additions & 5 deletions homeassistant/components/fritzbox/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
PRECISION_HALVES,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
Expand All @@ -28,7 +28,7 @@
ATTR_STATE_SUMMER_MODE,
ATTR_STATE_WINDOW_OPEN,
CONF_COORDINATOR,
DOMAIN as FRITZBOX_DOMAIN,
DOMAIN,
)
from .model import ClimateExtraAttributes

Expand All @@ -50,9 +50,25 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome thermostat from ConfigEntry."""
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
[
FritzboxThermostat(coordinator, ain)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", []) and device.has_thermostat
]
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
[
Expand Down
16 changes: 16 additions & 0 deletions homeassistant/components/fritzbox/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ def _update_fritz_devices(self) -> FritzboxCoordinatorData:
for template in templates:
template_data[template.ain] = template

if self.data:
new_devices = [ain for ain in device_data if ain not in self.data.devices]
if new_devices:
self.hass.bus.fire(
Comment thread
mib1185 marked this conversation as resolved.
Outdated
f"{DOMAIN}_{self.entry.entry_id}_new_devices", {"ains": new_devices}
)

new_templates = [
ain for ain in template_data if ain not in self.data.templates
]
if new_templates:
self.hass.bus.fire(
f"{DOMAIN}_{self.entry.entry_id}_new_templates",
{"ains": new_templates},
)

Comment thread
mib1185 marked this conversation as resolved.
return FritzboxCoordinatorData(devices=device_data, templates=template_data)

async def _async_update_data(self) -> FritzboxCoordinatorData:
Expand Down
24 changes: 19 additions & 5 deletions homeassistant/components/fritzbox/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,34 @@
CoverEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
from .const import CONF_COORDINATOR, DOMAIN


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome cover from ConfigEntry."""
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
FritzboxCover(coordinator, ain)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", []) and device.has_blind
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
FritzboxCover(coordinator, ain)
Expand Down
59 changes: 35 additions & 24 deletions homeassistant/components/fritzbox/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from typing import Any, cast

from pyfritzhome import FritzhomeDevice
from requests.exceptions import HTTPError

from homeassistant.components.light import (
Expand All @@ -13,17 +14,11 @@
LightEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import (
COLOR_MODE,
COLOR_TEMP_MODE,
CONF_COORDINATOR,
DOMAIN as FRITZBOX_DOMAIN,
LOGGER,
)
from .const import COLOR_MODE, COLOR_TEMP_MODE, CONF_COORDINATOR, DOMAIN, LOGGER

SUPPORTED_COLOR_MODES = {ColorMode.COLOR_TEMP, ColorMode.HS}

Expand All @@ -32,31 +27,47 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome light from ConfigEntry."""
entities: list[FritzboxLight] = []
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]

for ain, device in coordinator.data.devices.items():
if not device.has_lightbulb:
continue
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _prepare_light_entity(ain: str, device: FritzhomeDevice) -> FritzboxLight:
supported_color_temps = await hass.async_add_executor_job(
device.get_color_temps
)

supported_colors = await hass.async_add_executor_job(device.get_colors)

entities.append(
FritzboxLight(
coordinator,
ain,
supported_colors,
supported_color_temps,
)
return FritzboxLight(
coordinator,
ain,
supported_colors,
supported_color_temps,
)

async_add_entities(entities)
async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
[
await _prepare_light_entity(ain, device)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", []) and device.has_lightbulb
]
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
[
await _prepare_light_entity(ain, device)
for ain, device in coordinator.data.devices.items()
if device.has_lightbulb
]
)


class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
Expand Down
27 changes: 24 additions & 3 deletions homeassistant/components/fritzbox/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@
UnitOfPower,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utc_from_timestamp

from . import FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
from .const import CONF_COORDINATOR, DOMAIN
from .coordinator import FritzboxDataUpdateCoordinator
from .model import FritzEntityDescriptionMixinBase


Expand Down Expand Up @@ -212,7 +213,27 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome sensor from ConfigEntry."""
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
[
FritzBoxSensor(coordinator, ain, description)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", [])
for description in SENSOR_TYPES
if description.suitable(device)
]
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
[
Expand Down
26 changes: 21 additions & 5 deletions homeassistant/components/fritzbox/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,36 @@

from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
from .const import CONF_COORDINATOR, DOMAIN


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the FRITZ!SmartHome switch from ConfigEntry."""
coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
coordinator: FritzboxDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
CONF_COORDINATOR
]

async def _add_new_devices(event: Event) -> None:
"""Add newly discovered devices."""
async_add_entities(
[
FritzboxSwitch(coordinator, ain)
for ain, device in coordinator.data.devices.items()
if ain in event.data.get("ains", []) and device.has_switch
]
)

entry.async_on_unload(
hass.bus.async_listen(
f"{DOMAIN}_{entry.entry_id}_new_devices", _add_new_devices
)
)

async_add_entities(
[
Expand Down