mirror of
https://github.com/home-assistant/core.git
synced 2025-05-02 13:17:53 +00:00
Rituals Perfume Genie improvements (#49277)
* Rituals Perfume Genie integration improvements * Add return type FlowResultDict to async_step_user * Rollback async_update_data * Add return type to DiffuserEntity init * check super().available too * Merge iterations * Use RitualsPerufmeGenieDataUpdateCoordinator
This commit is contained in:
parent
006bcde435
commit
ad967cfebb
@ -3,8 +3,8 @@ import asyncio
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from aiohttp.client_exceptions import ClientConnectorError
|
import aiohttp
|
||||||
from pyrituals import Account
|
from pyrituals import Account, Diffuser
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -19,6 +19,7 @@ PLATFORMS = ["binary_sensor", "sensor", "switch"]
|
|||||||
EMPTY_CREDENTIALS = ""
|
EMPTY_CREDENTIALS = ""
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
UPDATE_INTERVAL = timedelta(seconds=30)
|
UPDATE_INTERVAL = timedelta(seconds=30)
|
||||||
|
|
||||||
|
|
||||||
@ -30,38 +31,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
account_devices = await account.get_devices()
|
account_devices = await account.get_devices()
|
||||||
except ClientConnectorError as ex:
|
except aiohttp.ClientError as err:
|
||||||
raise ConfigEntryNotReady from ex
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
hublots = []
|
|
||||||
devices = {}
|
|
||||||
for device in account_devices:
|
|
||||||
hublot = device.data[HUB][HUBLOT]
|
|
||||||
hublots.append(hublot)
|
|
||||||
devices[hublot] = device
|
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
|
||||||
COORDINATORS: {},
|
COORDINATORS: {},
|
||||||
DEVICES: devices,
|
DEVICES: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
for hublot in hublots:
|
for device in account_devices:
|
||||||
device = hass.data[DOMAIN][entry.entry_id][DEVICES][hublot]
|
hublot = device.data[HUB][HUBLOT]
|
||||||
|
|
||||||
async def async_update_data():
|
|
||||||
await device.update_data()
|
|
||||||
return device.data
|
|
||||||
|
|
||||||
coordinator = DataUpdateCoordinator(
|
|
||||||
hass,
|
|
||||||
_LOGGER,
|
|
||||||
name=f"{DOMAIN}-{hublot}",
|
|
||||||
update_method=async_update_data,
|
|
||||||
update_interval=UPDATE_INTERVAL,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
coordinator = RitualsPerufmeGenieDataUpdateCoordinator(hass, device)
|
||||||
await coordinator.async_refresh()
|
await coordinator.async_refresh()
|
||||||
|
|
||||||
|
hass.data[DOMAIN][entry.entry_id][DEVICES][hublot] = device
|
||||||
hass.data[DOMAIN][entry.entry_id][COORDINATORS][hublot] = coordinator
|
hass.data[DOMAIN][entry.entry_id][COORDINATORS][hublot] = coordinator
|
||||||
|
|
||||||
for platform in PLATFORMS:
|
for platform in PLATFORMS:
|
||||||
@ -86,3 +70,22 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
|
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
|
class RitualsPerufmeGenieDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
"""Class to manage fetching Rituals Perufme Genie device data from single endpoint."""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, device: Diffuser):
|
||||||
|
"""Initialize global Rituals Perufme Genie data updater."""
|
||||||
|
self._device = device
|
||||||
|
super().__init__(
|
||||||
|
hass,
|
||||||
|
_LOGGER,
|
||||||
|
name=f"{DOMAIN}-{device.data[HUB][HUBLOT]}",
|
||||||
|
update_interval=UPDATE_INTERVAL,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _async_update_data(self) -> dict:
|
||||||
|
"""Fetch data from Rituals."""
|
||||||
|
await self._device.update_data()
|
||||||
|
return self._device.data
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
"""Support for Rituals Perfume Genie binary sensors."""
|
"""Support for Rituals Perfume Genie binary sensors."""
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
from pyrituals import Diffuser
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
DEVICE_CLASS_BATTERY_CHARGING,
|
DEVICE_CLASS_BATTERY_CHARGING,
|
||||||
BinarySensorEntity,
|
BinarySensorEntity,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID
|
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID
|
||||||
from .entity import SENSORS, DiffuserEntity
|
from .entity import SENSORS, DiffuserEntity
|
||||||
@ -11,7 +18,9 @@ CHARGING_SUFFIX = " Battery Charging"
|
|||||||
BATTERY_CHARGING_ID = 21
|
BATTERY_CHARGING_ID = 21
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: Callable
|
||||||
|
) -> None:
|
||||||
"""Set up the diffuser binary sensors."""
|
"""Set up the diffuser binary sensors."""
|
||||||
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
||||||
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
||||||
@ -27,18 +36,16 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
class DiffuserBatteryChargingBinarySensor(DiffuserEntity, BinarySensorEntity):
|
class DiffuserBatteryChargingBinarySensor(DiffuserEntity, BinarySensorEntity):
|
||||||
"""Representation of a diffuser battery charging binary sensor."""
|
"""Representation of a diffuser battery charging binary sensor."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the battery charging binary sensor."""
|
"""Initialize the battery charging binary sensor."""
|
||||||
super().__init__(diffuser, coordinator, CHARGING_SUFFIX)
|
super().__init__(diffuser, coordinator, CHARGING_SUFFIX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self) -> bool:
|
||||||
"""Return the state of the battery charging binary sensor."""
|
"""Return the state of the battery charging binary sensor."""
|
||||||
return bool(
|
return self.coordinator.data[HUB][SENSORS][BATTERY][ID] == BATTERY_CHARGING_ID
|
||||||
self.coordinator.data[HUB][SENSORS][BATTERY][ID] == BATTERY_CHARGING_ID
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self) -> str:
|
||||||
"""Return the device class of the battery charging binary sensor."""
|
"""Return the device class of the battery charging binary sensor."""
|
||||||
return DEVICE_CLASS_BATTERY_CHARGING
|
return DEVICE_CLASS_BATTERY_CHARGING
|
||||||
|
@ -7,6 +7,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
|
||||||
|
from homeassistant.data_entry_flow import FlowResultDict
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .const import ACCOUNT_HASH, DOMAIN
|
from .const import ACCOUNT_HASH, DOMAIN
|
||||||
@ -27,7 +28,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
VERSION = 1
|
VERSION = 1
|
||||||
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(self, user_input=None) -> FlowResultDict:
|
||||||
"""Handle the initial step."""
|
"""Handle the initial step."""
|
||||||
if user_input is None:
|
if user_input is None:
|
||||||
return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA)
|
return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA)
|
||||||
|
@ -1,19 +1,31 @@
|
|||||||
"""Base class for Rituals Perfume Genie diffuser entity."""
|
"""Base class for Rituals Perfume Genie diffuser entity."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pyrituals import Diffuser
|
||||||
|
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import ATTRIBUTES, DOMAIN, HUB, HUBLOT, SENSORS
|
from .const import ATTRIBUTES, BATTERY, DOMAIN, HUB, HUBLOT, SENSORS
|
||||||
|
|
||||||
MANUFACTURER = "Rituals Cosmetics"
|
MANUFACTURER = "Rituals Cosmetics"
|
||||||
MODEL = "Diffuser"
|
MODEL = "The Perfume Genie"
|
||||||
|
MODEL2 = "The Perfume Genie 2.0"
|
||||||
|
|
||||||
ROOMNAME = "roomnamec"
|
ROOMNAME = "roomnamec"
|
||||||
|
STATUS = "status"
|
||||||
VERSION = "versionc"
|
VERSION = "versionc"
|
||||||
|
|
||||||
|
AVAILABLE_STATE = 1
|
||||||
|
|
||||||
|
|
||||||
class DiffuserEntity(CoordinatorEntity):
|
class DiffuserEntity(CoordinatorEntity):
|
||||||
"""Representation of a diffuser entity."""
|
"""Representation of a diffuser entity."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator, entity_suffix):
|
def __init__(
|
||||||
|
self, diffuser: Diffuser, coordinator: CoordinatorEntity, entity_suffix: str
|
||||||
|
) -> None:
|
||||||
"""Init from config, hookup diffuser and coordinator."""
|
"""Init from config, hookup diffuser and coordinator."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._diffuser = diffuser
|
self._diffuser = diffuser
|
||||||
@ -22,22 +34,29 @@ class DiffuserEntity(CoordinatorEntity):
|
|||||||
self._hubname = self.coordinator.data[HUB][ATTRIBUTES][ROOMNAME]
|
self._hubname = self.coordinator.data[HUB][ATTRIBUTES][ROOMNAME]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self) -> str:
|
||||||
"""Return the unique ID of the entity."""
|
"""Return the unique ID of the entity."""
|
||||||
return f"{self._hublot}{self._entity_suffix}"
|
return f"{self._hublot}{self._entity_suffix}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self) -> str:
|
||||||
"""Return the name of the entity."""
|
"""Return the name of the entity."""
|
||||||
return f"{self._hubname}{self._entity_suffix}"
|
return f"{self._hubname}{self._entity_suffix}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def available(self) -> bool:
|
||||||
|
"""Return if the entity is available."""
|
||||||
|
return (
|
||||||
|
super().available and self.coordinator.data[HUB][STATUS] == AVAILABLE_STATE
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_info(self) -> dict[str, Any]:
|
||||||
"""Return information about the device."""
|
"""Return information about the device."""
|
||||||
return {
|
return {
|
||||||
"name": self._hubname,
|
"name": self._hubname,
|
||||||
"identifiers": {(DOMAIN, self._hublot)},
|
"identifiers": {(DOMAIN, self._hublot)},
|
||||||
"manufacturer": MANUFACTURER,
|
"manufacturer": MANUFACTURER,
|
||||||
"model": MODEL,
|
"model": MODEL if BATTERY in self._diffuser.data[HUB][SENSORS] else MODEL2,
|
||||||
"sw_version": self.coordinator.data[HUB][SENSORS][VERSION],
|
"sw_version": self.coordinator.data[HUB][SENSORS][VERSION],
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
"""Support for Rituals Perfume Genie sensors."""
|
"""Support for Rituals Perfume Genie sensors."""
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
from pyrituals import Diffuser
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_BATTERY_LEVEL,
|
|
||||||
DEVICE_CLASS_BATTERY,
|
DEVICE_CLASS_BATTERY,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID, SENSORS
|
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID, SENSORS
|
||||||
from .entity import DiffuserEntity
|
from .entity import DiffuserEntity
|
||||||
@ -26,7 +32,9 @@ WIFI_SUFFIX = " Wifi"
|
|||||||
ATTR_SIGNAL_STRENGTH = "signal_strength"
|
ATTR_SIGNAL_STRENGTH = "signal_strength"
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: Callable
|
||||||
|
) -> None:
|
||||||
"""Set up the diffuser sensors."""
|
"""Set up the diffuser sensors."""
|
||||||
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
||||||
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
||||||
@ -45,19 +53,19 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
class DiffuserPerfumeSensor(DiffuserEntity):
|
class DiffuserPerfumeSensor(DiffuserEntity):
|
||||||
"""Representation of a diffuser perfume sensor."""
|
"""Representation of a diffuser perfume sensor."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the perfume sensor."""
|
"""Initialize the perfume sensor."""
|
||||||
super().__init__(diffuser, coordinator, PERFUME_SUFFIX)
|
super().__init__(diffuser, coordinator, PERFUME_SUFFIX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self):
|
def icon(self) -> str:
|
||||||
"""Return the perfume sensor icon."""
|
"""Return the perfume sensor icon."""
|
||||||
if self.coordinator.data[HUB][SENSORS][PERFUME][ID] == PERFUME_NO_CARTRIDGE_ID:
|
if self.coordinator.data[HUB][SENSORS][PERFUME][ID] == PERFUME_NO_CARTRIDGE_ID:
|
||||||
return "mdi:tag-remove"
|
return "mdi:tag-remove"
|
||||||
return "mdi:tag-text"
|
return "mdi:tag-text"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> str:
|
||||||
"""Return the state of the perfume sensor."""
|
"""Return the state of the perfume sensor."""
|
||||||
return self.coordinator.data[HUB][SENSORS][PERFUME][TITLE]
|
return self.coordinator.data[HUB][SENSORS][PERFUME][TITLE]
|
||||||
|
|
||||||
@ -65,19 +73,19 @@ class DiffuserPerfumeSensor(DiffuserEntity):
|
|||||||
class DiffuserFillSensor(DiffuserEntity):
|
class DiffuserFillSensor(DiffuserEntity):
|
||||||
"""Representation of a diffuser fill sensor."""
|
"""Representation of a diffuser fill sensor."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the fill sensor."""
|
"""Initialize the fill sensor."""
|
||||||
super().__init__(diffuser, coordinator, FILL_SUFFIX)
|
super().__init__(diffuser, coordinator, FILL_SUFFIX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self):
|
def icon(self) -> str:
|
||||||
"""Return the fill sensor icon."""
|
"""Return the fill sensor icon."""
|
||||||
if self.coordinator.data[HUB][SENSORS][FILL][ID] == FILL_NO_CARTRIDGE_ID:
|
if self.coordinator.data[HUB][SENSORS][FILL][ID] == FILL_NO_CARTRIDGE_ID:
|
||||||
return "mdi:beaker-question"
|
return "mdi:beaker-question"
|
||||||
return "mdi:beaker"
|
return "mdi:beaker"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> str:
|
||||||
"""Return the state of the fill sensor."""
|
"""Return the state of the fill sensor."""
|
||||||
return self.coordinator.data[HUB][SENSORS][FILL][TITLE]
|
return self.coordinator.data[HUB][SENSORS][FILL][TITLE]
|
||||||
|
|
||||||
@ -85,12 +93,12 @@ class DiffuserFillSensor(DiffuserEntity):
|
|||||||
class DiffuserBatterySensor(DiffuserEntity):
|
class DiffuserBatterySensor(DiffuserEntity):
|
||||||
"""Representation of a diffuser battery sensor."""
|
"""Representation of a diffuser battery sensor."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the battery sensor."""
|
"""Initialize the battery sensor."""
|
||||||
super().__init__(diffuser, coordinator, BATTERY_SUFFIX)
|
super().__init__(diffuser, coordinator, BATTERY_SUFFIX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> int:
|
||||||
"""Return the state of the battery sensor."""
|
"""Return the state of the battery sensor."""
|
||||||
# Use ICON because TITLE may change in the future.
|
# Use ICON because TITLE may change in the future.
|
||||||
# ICON filename does not match the image.
|
# ICON filename does not match the image.
|
||||||
@ -103,19 +111,12 @@ class DiffuserBatterySensor(DiffuserEntity):
|
|||||||
}[self.coordinator.data[HUB][SENSORS][BATTERY][ICON]]
|
}[self.coordinator.data[HUB][SENSORS][BATTERY][ICON]]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self) -> str:
|
||||||
"""Return the class of the battery sensor."""
|
"""Return the class of the battery sensor."""
|
||||||
return DEVICE_CLASS_BATTERY
|
return DEVICE_CLASS_BATTERY
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def unit_of_measurement(self) -> str:
|
||||||
"""Return the battery state attributes."""
|
|
||||||
return {
|
|
||||||
ATTR_BATTERY_LEVEL: self.coordinator.data[HUB][SENSORS][BATTERY][TITLE],
|
|
||||||
}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Return the battery unit of measurement."""
|
"""Return the battery unit of measurement."""
|
||||||
return PERCENTAGE
|
return PERCENTAGE
|
||||||
|
|
||||||
@ -123,12 +124,12 @@ class DiffuserBatterySensor(DiffuserEntity):
|
|||||||
class DiffuserWifiSensor(DiffuserEntity):
|
class DiffuserWifiSensor(DiffuserEntity):
|
||||||
"""Representation of a diffuser wifi sensor."""
|
"""Representation of a diffuser wifi sensor."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the wifi sensor."""
|
"""Initialize the wifi sensor."""
|
||||||
super().__init__(diffuser, coordinator, WIFI_SUFFIX)
|
super().__init__(diffuser, coordinator, WIFI_SUFFIX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> int:
|
||||||
"""Return the state of the wifi sensor."""
|
"""Return the state of the wifi sensor."""
|
||||||
# Use ICON because TITLE may change in the future.
|
# Use ICON because TITLE may change in the future.
|
||||||
return {
|
return {
|
||||||
@ -139,18 +140,11 @@ class DiffuserWifiSensor(DiffuserEntity):
|
|||||||
}[self.coordinator.data[HUB][SENSORS][WIFI][ICON]]
|
}[self.coordinator.data[HUB][SENSORS][WIFI][ICON]]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self) -> str:
|
||||||
"""Return the class of the wifi sensor."""
|
"""Return the class of the wifi sensor."""
|
||||||
return DEVICE_CLASS_SIGNAL_STRENGTH
|
return DEVICE_CLASS_SIGNAL_STRENGTH
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def unit_of_measurement(self) -> str:
|
||||||
"""Return the wifi state attributes."""
|
|
||||||
return {
|
|
||||||
ATTR_SIGNAL_STRENGTH: self.coordinator.data[HUB][SENSORS][WIFI][TITLE],
|
|
||||||
}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Return the wifi unit of measurement."""
|
"""Return the wifi unit of measurement."""
|
||||||
return PERCENTAGE
|
return PERCENTAGE
|
||||||
|
@ -1,20 +1,28 @@
|
|||||||
"""Support for Rituals Perfume Genie switches."""
|
"""Support for Rituals Perfume Genie switches."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
from pyrituals import Diffuser
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.core import callback
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import ATTRIBUTES, COORDINATORS, DEVICES, DOMAIN, HUB
|
from .const import ATTRIBUTES, COORDINATORS, DEVICES, DOMAIN, HUB
|
||||||
from .entity import DiffuserEntity
|
from .entity import DiffuserEntity
|
||||||
|
|
||||||
STATUS = "status"
|
|
||||||
FAN = "fanc"
|
FAN = "fanc"
|
||||||
SPEED = "speedc"
|
SPEED = "speedc"
|
||||||
ROOM = "roomc"
|
ROOM = "roomc"
|
||||||
|
|
||||||
ON_STATE = "1"
|
ON_STATE = "1"
|
||||||
AVAILABLE_STATE = 1
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: Callable
|
||||||
|
) -> None:
|
||||||
"""Set up the diffuser switch."""
|
"""Set up the diffuser switch."""
|
||||||
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES]
|
||||||
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
||||||
@ -29,23 +37,18 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
||||||
"""Representation of a diffuser switch."""
|
"""Representation of a diffuser switch."""
|
||||||
|
|
||||||
def __init__(self, diffuser, coordinator):
|
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
||||||
"""Initialize the diffuser switch."""
|
"""Initialize the diffuser switch."""
|
||||||
super().__init__(diffuser, coordinator, "")
|
super().__init__(diffuser, coordinator, "")
|
||||||
self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE
|
self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self):
|
def icon(self) -> str:
|
||||||
"""Return if the device is available."""
|
|
||||||
return self.coordinator.data[HUB][STATUS] == AVAILABLE_STATE
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Return the icon of the device."""
|
"""Return the icon of the device."""
|
||||||
return "mdi:fan"
|
return "mdi:fan"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return the device state attributes."""
|
"""Return the device state attributes."""
|
||||||
attributes = {
|
attributes = {
|
||||||
"fan_speed": self.coordinator.data[HUB][ATTRIBUTES][SPEED],
|
"fan_speed": self.coordinator.data[HUB][ATTRIBUTES][SPEED],
|
||||||
@ -54,24 +57,24 @@ class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
|||||||
return attributes
|
return attributes
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self) -> bool:
|
||||||
"""If the device is currently on or off."""
|
"""If the device is currently on or off."""
|
||||||
return self._is_on
|
return self._is_on
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
await self._diffuser.turn_on()
|
await self._diffuser.turn_on()
|
||||||
self._is_on = True
|
self._is_on = True
|
||||||
self.schedule_update_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
await self._diffuser.turn_off()
|
await self._diffuser.turn_off()
|
||||||
self._is_on = False
|
self._is_on = False
|
||||||
self.schedule_update_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _handle_coordinator_update(self):
|
def _handle_coordinator_update(self) -> None:
|
||||||
"""Handle updated data from the coordinator."""
|
"""Handle updated data from the coordinator."""
|
||||||
self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE
|
self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user