mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Abstract Rituals API data processing to PyPI (#49872)
This commit is contained in:
parent
26fd7fc15b
commit
6967fd184b
@ -11,7 +11,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
|
|||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
from .const import ACCOUNT_HASH, COORDINATORS, DEVICES, DOMAIN, HUB, HUBLOT
|
from .const import ACCOUNT_HASH, COORDINATORS, DEVICES, DOMAIN, HUBLOT
|
||||||
|
|
||||||
PLATFORMS = ["binary_sensor", "sensor", "switch"]
|
PLATFORMS = ["binary_sensor", "sensor", "switch"]
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
}
|
}
|
||||||
|
|
||||||
for device in account_devices:
|
for device in account_devices:
|
||||||
hublot = device.data[HUB][HUBLOT]
|
hublot = device.hub_data[HUBLOT]
|
||||||
|
|
||||||
coordinator = RitualsPerufmeGenieDataUpdateCoordinator(hass, device)
|
coordinator = RitualsPerufmeGenieDataUpdateCoordinator(hass, device)
|
||||||
await coordinator.async_refresh()
|
await coordinator.async_refresh()
|
||||||
@ -70,11 +70,10 @@ class RitualsPerufmeGenieDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
name=f"{DOMAIN}-{device.data[HUB][HUBLOT]}",
|
name=f"{DOMAIN}-{device.hub_data[HUBLOT]}",
|
||||||
update_interval=UPDATE_INTERVAL,
|
update_interval=UPDATE_INTERVAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict:
|
async def _async_update_data(self) -> None:
|
||||||
"""Fetch data from Rituals."""
|
"""Fetch data from Rituals."""
|
||||||
await self._device.update_data()
|
await self._device.update_data()
|
||||||
return self._device.data
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Support for Rituals Perfume Genie binary sensors."""
|
"""Support for Rituals Perfume Genie binary sensors."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from pyrituals import Diffuser
|
from pyrituals import Diffuser
|
||||||
@ -11,8 +13,8 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID
|
from .const import COORDINATORS, DEVICES, DOMAIN
|
||||||
from .entity import SENSORS, DiffuserEntity
|
from .entity import DiffuserEntity
|
||||||
|
|
||||||
CHARGING_SUFFIX = " Battery Charging"
|
CHARGING_SUFFIX = " Battery Charging"
|
||||||
BATTERY_CHARGING_ID = 21
|
BATTERY_CHARGING_ID = 21
|
||||||
@ -26,7 +28,7 @@ async def async_setup_entry(
|
|||||||
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]
|
||||||
entities = []
|
entities = []
|
||||||
for hublot, diffuser in diffusers.items():
|
for hublot, diffuser in diffusers.items():
|
||||||
if BATTERY in diffuser.data[HUB][SENSORS]:
|
if diffuser.has_battery:
|
||||||
coordinator = coordinators[hublot]
|
coordinator = coordinators[hublot]
|
||||||
entities.append(DiffuserBatteryChargingBinarySensor(diffuser, coordinator))
|
entities.append(DiffuserBatteryChargingBinarySensor(diffuser, coordinator))
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ class DiffuserBatteryChargingBinarySensor(DiffuserEntity, BinarySensorEntity):
|
|||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return the state of the battery charging binary sensor."""
|
"""Return the state of the battery charging binary sensor."""
|
||||||
return self.coordinator.data[HUB][SENSORS][BATTERY][ID] == BATTERY_CHARGING_ID
|
return self._diffuser.charging
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self) -> str:
|
def device_class(self) -> str:
|
||||||
|
@ -6,8 +6,6 @@ DEVICES = "devices"
|
|||||||
|
|
||||||
ACCOUNT_HASH = "account_hash"
|
ACCOUNT_HASH = "account_hash"
|
||||||
ATTRIBUTES = "attributes"
|
ATTRIBUTES = "attributes"
|
||||||
BATTERY = "battc"
|
|
||||||
HUB = "hub"
|
|
||||||
HUBLOT = "hublot"
|
HUBLOT = "hublot"
|
||||||
ID = "id"
|
ID = "id"
|
||||||
SENSORS = "sensors"
|
SENSORS = "sensors"
|
||||||
|
@ -7,7 +7,7 @@ from pyrituals import Diffuser
|
|||||||
|
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import ATTRIBUTES, BATTERY, DOMAIN, HUB, HUBLOT, SENSORS
|
from .const import ATTRIBUTES, DOMAIN, HUBLOT, SENSORS
|
||||||
|
|
||||||
MANUFACTURER = "Rituals Cosmetics"
|
MANUFACTURER = "Rituals Cosmetics"
|
||||||
MODEL = "The Perfume Genie"
|
MODEL = "The Perfume Genie"
|
||||||
@ -30,8 +30,8 @@ class DiffuserEntity(CoordinatorEntity):
|
|||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._diffuser = diffuser
|
self._diffuser = diffuser
|
||||||
self._entity_suffix = entity_suffix
|
self._entity_suffix = entity_suffix
|
||||||
self._hublot = self.coordinator.data[HUB][HUBLOT]
|
self._hublot = self._diffuser.hub_data[HUBLOT]
|
||||||
self._hubname = self.coordinator.data[HUB][ATTRIBUTES][ROOMNAME]
|
self._hubname = self._diffuser.hub_data[ATTRIBUTES][ROOMNAME]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
@ -46,9 +46,7 @@ class DiffuserEntity(CoordinatorEntity):
|
|||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return if the entity is available."""
|
"""Return if the entity is available."""
|
||||||
return (
|
return super().available and self._diffuser.hub_data[STATUS] == AVAILABLE_STATE
|
||||||
super().available and self.coordinator.data[HUB][STATUS] == AVAILABLE_STATE
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> dict[str, Any]:
|
def device_info(self) -> dict[str, Any]:
|
||||||
@ -57,6 +55,6 @@ class DiffuserEntity(CoordinatorEntity):
|
|||||||
"name": self._hubname,
|
"name": self._hubname,
|
||||||
"identifiers": {(DOMAIN, self._hublot)},
|
"identifiers": {(DOMAIN, self._hublot)},
|
||||||
"manufacturer": MANUFACTURER,
|
"manufacturer": MANUFACTURER,
|
||||||
"model": MODEL if BATTERY in self._diffuser.data[HUB][SENSORS] else MODEL2,
|
"model": MODEL if self._diffuser.has_battery else MODEL2,
|
||||||
"sw_version": self.coordinator.data[HUB][SENSORS][VERSION],
|
"sw_version": self._diffuser.hub_data[SENSORS][VERSION],
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Rituals Perfume Genie",
|
"name": "Rituals Perfume Genie",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/rituals_perfume_genie",
|
"documentation": "https://www.home-assistant.io/integrations/rituals_perfume_genie",
|
||||||
"requirements": ["pyrituals==0.0.2"],
|
"requirements": ["pyrituals==0.0.3"],
|
||||||
"codeowners": ["@milanmeu"],
|
"codeowners": ["@milanmeu"],
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import BATTERY, COORDINATORS, DEVICES, DOMAIN, HUB, ID, SENSORS
|
from .const import COORDINATORS, DEVICES, DOMAIN, ID, SENSORS
|
||||||
from .entity import DiffuserEntity
|
from .entity import DiffuserEntity
|
||||||
|
|
||||||
TITLE = "title"
|
TITLE = "title"
|
||||||
@ -44,7 +44,7 @@ async def async_setup_entry(
|
|||||||
entities.append(DiffuserPerfumeSensor(diffuser, coordinator))
|
entities.append(DiffuserPerfumeSensor(diffuser, coordinator))
|
||||||
entities.append(DiffuserFillSensor(diffuser, coordinator))
|
entities.append(DiffuserFillSensor(diffuser, coordinator))
|
||||||
entities.append(DiffuserWifiSensor(diffuser, coordinator))
|
entities.append(DiffuserWifiSensor(diffuser, coordinator))
|
||||||
if BATTERY in diffuser.data[HUB][SENSORS]:
|
if diffuser.has_battery:
|
||||||
entities.append(DiffuserBatterySensor(diffuser, coordinator))
|
entities.append(DiffuserBatterySensor(diffuser, coordinator))
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
@ -60,14 +60,14 @@ class DiffuserPerfumeSensor(DiffuserEntity):
|
|||||||
@property
|
@property
|
||||||
def icon(self) -> str:
|
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._diffuser.hub_data[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) -> str:
|
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._diffuser.hub_data[SENSORS][PERFUME][TITLE]
|
||||||
|
|
||||||
|
|
||||||
class DiffuserFillSensor(DiffuserEntity):
|
class DiffuserFillSensor(DiffuserEntity):
|
||||||
@ -80,14 +80,14 @@ class DiffuserFillSensor(DiffuserEntity):
|
|||||||
@property
|
@property
|
||||||
def icon(self) -> str:
|
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._diffuser.hub_data[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) -> str:
|
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._diffuser.hub_data[SENSORS][FILL][TITLE]
|
||||||
|
|
||||||
|
|
||||||
class DiffuserBatterySensor(DiffuserEntity):
|
class DiffuserBatterySensor(DiffuserEntity):
|
||||||
@ -100,15 +100,7 @@ class DiffuserBatterySensor(DiffuserEntity):
|
|||||||
@property
|
@property
|
||||||
def state(self) -> int:
|
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.
|
return self._diffuser.battery_percentage
|
||||||
# ICON filename does not match the image.
|
|
||||||
return {
|
|
||||||
"battery-charge.png": 100,
|
|
||||||
"battery-full.png": 100,
|
|
||||||
"Battery-75.png": 50,
|
|
||||||
"battery-50.png": 25,
|
|
||||||
"battery-low.png": 10,
|
|
||||||
}[self.coordinator.data[HUB][SENSORS][BATTERY][ICON]]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self) -> str:
|
def device_class(self) -> str:
|
||||||
@ -131,13 +123,7 @@ class DiffuserWifiSensor(DiffuserEntity):
|
|||||||
@property
|
@property
|
||||||
def state(self) -> int:
|
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.
|
return self._diffuser.wifi_percentage
|
||||||
return {
|
|
||||||
"icon-signal.png": 100,
|
|
||||||
"icon-signal-75.png": 70,
|
|
||||||
"icon-signal-low.png": 25,
|
|
||||||
"icon-signal-0.png": 0,
|
|
||||||
}[self.coordinator.data[HUB][SENSORS][WIFI][ICON]]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self) -> str:
|
def device_class(self) -> str:
|
||||||
|
@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import ATTRIBUTES, COORDINATORS, DEVICES, DOMAIN, HUB
|
from .const import ATTRIBUTES, COORDINATORS, DEVICES, DOMAIN
|
||||||
from .entity import DiffuserEntity
|
from .entity import DiffuserEntity
|
||||||
|
|
||||||
FAN = "fanc"
|
FAN = "fanc"
|
||||||
@ -40,7 +40,7 @@ class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
|||||||
def __init__(self, diffuser: Diffuser, coordinator: CoordinatorEntity) -> None:
|
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._diffuser.is_on
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> str:
|
def icon(self) -> str:
|
||||||
@ -51,8 +51,8 @@ class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
|||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
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._diffuser.hub_data[ATTRIBUTES][SPEED],
|
||||||
"room_size": self.coordinator.data[HUB][ATTRIBUTES][ROOM],
|
"room_size": self._diffuser.hub_data[ATTRIBUTES][ROOM],
|
||||||
}
|
}
|
||||||
return attributes
|
return attributes
|
||||||
|
|
||||||
@ -76,5 +76,5 @@ class DiffuserSwitch(SwitchEntity, DiffuserEntity):
|
|||||||
@callback
|
@callback
|
||||||
def _handle_coordinator_update(self) -> None:
|
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._diffuser.is_on
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -1676,7 +1676,7 @@ pyrepetier==3.0.5
|
|||||||
pyrisco==0.3.1
|
pyrisco==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.rituals_perfume_genie
|
# homeassistant.components.rituals_perfume_genie
|
||||||
pyrituals==0.0.2
|
pyrituals==0.0.3
|
||||||
|
|
||||||
# homeassistant.components.zeroconf
|
# homeassistant.components.zeroconf
|
||||||
pyroute2==0.5.18
|
pyroute2==0.5.18
|
||||||
|
@ -924,7 +924,7 @@ pyqwikswitch==0.93
|
|||||||
pyrisco==0.3.1
|
pyrisco==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.rituals_perfume_genie
|
# homeassistant.components.rituals_perfume_genie
|
||||||
pyrituals==0.0.2
|
pyrituals==0.0.3
|
||||||
|
|
||||||
# homeassistant.components.zeroconf
|
# homeassistant.components.zeroconf
|
||||||
pyroute2==0.5.18
|
pyroute2==0.5.18
|
||||||
|
Loading…
x
Reference in New Issue
Block a user