Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions homeassistant/components/rituals_perfume_genie/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""The Rituals Perfume Genie integration."""
import asyncio

import aiohttp
from pyrituals import Account

Expand All @@ -8,7 +10,7 @@
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .const import ACCOUNT_HASH, COORDINATORS, DEVICES, DOMAIN
from .const import ACCOUNT_HASH, DOMAIN
from .coordinator import RitualsDataUpdateCoordinator

PLATFORMS = [
Expand All @@ -30,20 +32,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except aiohttp.ClientError as err:
raise ConfigEntryNotReady from err

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
COORDINATORS: {},
DEVICES: {},
# Create a coordinator for each diffuser
coordinators = {
diffuser.hublot: RitualsDataUpdateCoordinator(hass, diffuser)
for diffuser in account_devices
}

for device in account_devices:
hublot = device.hublot

coordinator = RitualsDataUpdateCoordinator(hass, device)
await coordinator.async_config_entry_first_refresh()

hass.data[DOMAIN][entry.entry_id][DEVICES][hublot] = device
hass.data[DOMAIN][entry.entry_id][COORDINATORS][hublot] = coordinator
# Refresh all coordinators
await asyncio.gather(
*[
coordinator.async_config_entry_first_refresh()
for coordinator in coordinators.values()
]
)

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinators
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True
Expand Down
23 changes: 10 additions & 13 deletions homeassistant/components/rituals_perfume_genie/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Support for Rituals Perfume Genie binary sensors."""
from __future__ import annotations

from pyrituals import Diffuser

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
Expand All @@ -12,7 +10,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import COORDINATORS, DEVICES, DOMAIN
from .const import DOMAIN
from .coordinator import RitualsDataUpdateCoordinator
from .entity import DiffuserEntity

Expand All @@ -25,13 +23,14 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the diffuser binary sensors."""
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][
config_entry.entry_id
]

async_add_entities(
DiffuserBatteryChargingBinarySensor(diffuser, coordinators[hublot])
for hublot, diffuser in diffusers.items()
if diffuser.has_battery
DiffuserBatteryChargingBinarySensor(coordinator)
for coordinator in coordinators.values()
if coordinator.diffuser.has_battery
)


Expand All @@ -41,13 +40,11 @@ class DiffuserBatteryChargingBinarySensor(DiffuserEntity, BinarySensorEntity):
_attr_device_class = BinarySensorDeviceClass.BATTERY_CHARGING
_attr_entity_category = EntityCategory.DIAGNOSTIC

def __init__(
self, diffuser: Diffuser, coordinator: RitualsDataUpdateCoordinator
) -> None:
def __init__(self, coordinator: RitualsDataUpdateCoordinator) -> None:
"""Initialize the battery charging binary sensor."""
super().__init__(diffuser, coordinator, CHARGING_SUFFIX)
super().__init__(coordinator, CHARGING_SUFFIX)

@property
def is_on(self) -> bool:
"""Return the state of the battery charging binary sensor."""
return self._diffuser.charging
return self.coordinator.diffuser.charging
3 changes: 0 additions & 3 deletions homeassistant/components/rituals_perfume_genie/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@

ACCOUNT_HASH = "account_hash"

COORDINATORS = "coordinators"
DEVICES = "devices"

UPDATE_INTERVAL = timedelta(minutes=2)
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
class RitualsDataUpdateCoordinator(DataUpdateCoordinator[None]):
"""Class to manage fetching Rituals Perfume Genie device data from single endpoint."""

def __init__(self, hass: HomeAssistant, device: Diffuser) -> None:
def __init__(self, hass: HomeAssistant, diffuser: Diffuser) -> None:
"""Initialize global Rituals Perfume Genie data updater."""
self._device = device
self.diffuser = diffuser
super().__init__(
hass,
_LOGGER,
name=f"{DOMAIN}-{device.hublot}",
name=f"{DOMAIN}-{diffuser.hublot}",
update_interval=UPDATE_INTERVAL,
)

async def _async_update_data(self) -> None:
"""Fetch data from Rituals."""
await self._device.update_data()
await self.diffuser.update_data()
15 changes: 5 additions & 10 deletions homeassistant/components/rituals_perfume_genie/entity.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Base class for Rituals Perfume Genie diffuser entity."""
from __future__ import annotations

from pyrituals import Diffuser

from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity

Expand All @@ -19,28 +17,25 @@ class DiffuserEntity(CoordinatorEntity[RitualsDataUpdateCoordinator]):

def __init__(
self,
diffuser: Diffuser,
coordinator: RitualsDataUpdateCoordinator,
entity_suffix: str,
) -> None:
"""Init from config, hookup diffuser and coordinator."""
super().__init__(coordinator)
self._diffuser = diffuser

hublot = self._diffuser.hublot
hubname = self._diffuser.name
hublot = coordinator.diffuser.hublot
hubname = coordinator.diffuser.name

self._attr_name = f"{hubname}{entity_suffix}"
self._attr_unique_id = f"{hublot}{entity_suffix}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, hublot)},
manufacturer=MANUFACTURER,
model=MODEL if diffuser.has_battery else MODEL2,
model=MODEL if coordinator.diffuser.has_battery else MODEL2,
name=hubname,
sw_version=diffuser.version,
sw_version=coordinator.diffuser.version,
)

@property
def available(self) -> bool:
"""Return if the entity is available."""
return super().available and self._diffuser.is_online
return super().available and self.coordinator.diffuser.is_online
28 changes: 11 additions & 17 deletions homeassistant/components/rituals_perfume_genie/number.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
"""Support for Rituals Perfume Genie numbers."""
from __future__ import annotations

from pyrituals import Diffuser

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 .const import COORDINATORS, DEVICES, DOMAIN
from .const import DOMAIN
from .coordinator import RitualsDataUpdateCoordinator
from .entity import DiffuserEntity

Expand All @@ -24,14 +22,12 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the diffuser numbers."""
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
entities: list[DiffuserEntity] = []
for hublot, diffuser in diffusers.items():
coordinator = coordinators[hublot]
entities.append(DiffuserPerfumeAmount(diffuser, coordinator))

async_add_entities(entities)
coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][
config_entry.entry_id
]
async_add_entities(
DiffuserPerfumeAmount(coordinator) for coordinator in coordinators.values()
)


class DiffuserPerfumeAmount(DiffuserEntity, NumberEntity):
Expand All @@ -41,16 +37,14 @@ class DiffuserPerfumeAmount(DiffuserEntity, NumberEntity):
_attr_native_max_value = MAX_PERFUME_AMOUNT
_attr_native_min_value = MIN_PERFUME_AMOUNT

def __init__(
self, diffuser: Diffuser, coordinator: RitualsDataUpdateCoordinator
) -> None:
def __init__(self, coordinator: RitualsDataUpdateCoordinator) -> None:
"""Initialize the diffuser perfume amount number."""
super().__init__(diffuser, coordinator, PERFUME_AMOUNT_SUFFIX)
super().__init__(coordinator, PERFUME_AMOUNT_SUFFIX)

@property
def native_value(self) -> int:
"""Return the current perfume amount."""
return self._diffuser.perfume_amount
return self.coordinator.diffuser.perfume_amount

async def async_set_native_value(self, value: float) -> None:
"""Set the perfume amount."""
Expand All @@ -59,4 +53,4 @@ async def async_set_native_value(self, value: float) -> None:
f"Can't set the perfume amount to {value}. Perfume amount must be an"
" integer."
)
await self._diffuser.set_perfume_amount(int(value))
await self.coordinator.diffuser.set_perfume_amount(int(value))
27 changes: 13 additions & 14 deletions homeassistant/components/rituals_perfume_genie/select.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
"""Support for Rituals Perfume Genie numbers."""
from __future__ import annotations

from pyrituals import Diffuser

from homeassistant.components.select import SelectEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import AREA_SQUARE_METERS, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import COORDINATORS, DEVICES, DOMAIN
from .const import DOMAIN
from .coordinator import RitualsDataUpdateCoordinator
from .entity import DiffuserEntity

Expand All @@ -22,11 +20,12 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the diffuser select entities."""
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
coordinators: dict[str, RitualsDataUpdateCoordinator] = hass.data[DOMAIN][
config_entry.entry_id
]

async_add_entities(
DiffuserRoomSize(diffuser, coordinators[hublot])
for hublot, diffuser in diffusers.items()
DiffuserRoomSize(coordinator) for coordinator in coordinators.values()
)


Expand All @@ -38,18 +37,18 @@ class DiffuserRoomSize(DiffuserEntity, SelectEntity):
_attr_options = ["15", "30", "60", "100"]
_attr_entity_category = EntityCategory.CONFIG

def __init__(
self, diffuser: Diffuser, coordinator: RitualsDataUpdateCoordinator
) -> None:
def __init__(self, coordinator: RitualsDataUpdateCoordinator) -> None:
"""Initialize the diffuser room size select entity."""
super().__init__(diffuser, coordinator, ROOM_SIZE_SUFFIX)
self._attr_entity_registry_enabled_default = diffuser.has_battery
super().__init__(coordinator, ROOM_SIZE_SUFFIX)
self._attr_entity_registry_enabled_default = (
self.coordinator.diffuser.has_battery
)

@property
def current_option(self) -> str:
"""Return the diffuser room size."""
return str(self._diffuser.room_size_square_meter)
return str(self.coordinator.diffuser.room_size_square_meter)

async def async_select_option(self, option: str) -> None:
"""Change the diffuser room size."""
await self._diffuser.set_room_size_square_meter(int(option))
await self.coordinator.diffuser.set_room_size_square_meter(int(option))
Loading