-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
Add Rituals Perfume Genie sensor platform #48270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7f09307
b808af0
ddafa58
d7c96ca
25f7d60
68488b7
6f8eeb4
3c94da6
9fc5422
86b1a75
f72b70b
d882710
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
"""Constants for the Rituals Perfume Genie integration.""" | ||
|
||
DOMAIN = "rituals_perfume_genie" | ||
|
||
COORDINATORS = "coordinators" | ||
DEVICES = "devices" | ||
|
||
ACCOUNT_HASH = "account_hash" | ||
ATTRIBUTES = "attributes" | ||
HUB = "hub" | ||
HUBLOT = "hublot" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Base class for Rituals Perfume Genie diffuser entity.""" | ||
from homeassistant.helpers.update_coordinator import CoordinatorEntity | ||
|
||
from .const import ATTRIBUTES, DOMAIN, HUB, HUBLOT | ||
|
||
MANUFACTURER = "Rituals Cosmetics" | ||
MODEL = "Diffuser" | ||
|
||
SENSORS = "sensors" | ||
ROOMNAME = "roomnamec" | ||
VERSION = "versionc" | ||
|
||
|
||
class DiffuserEntity(CoordinatorEntity): | ||
"""Representation of a diffuser entity.""" | ||
|
||
def __init__(self, diffuser, coordinator, entity_suffix): | ||
"""Init from config, hookup diffuser and coordinator.""" | ||
super().__init__(coordinator) | ||
self._diffuser = diffuser | ||
self._entity_suffix = entity_suffix | ||
self._hublot = self.coordinator.data[HUB][HUBLOT] | ||
self._hubname = self.coordinator.data[HUB][ATTRIBUTES][ROOMNAME] | ||
|
||
@property | ||
def unique_id(self): | ||
"""Return the unique ID of the entity.""" | ||
return f"{self._hublot}{self._entity_suffix}" | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the entity.""" | ||
return f"{self._hubname}{self._entity_suffix}" | ||
|
||
@property | ||
def device_info(self): | ||
"""Return information about the device.""" | ||
return { | ||
"name": self._hubname, | ||
"identifiers": {(DOMAIN, self._hublot)}, | ||
"manufacturer": MANUFACTURER, | ||
"model": MODEL, | ||
"sw_version": self.coordinator.data[HUB][SENSORS][VERSION], | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
"""Support for Rituals Perfume Genie sensors.""" | ||
from homeassistant.const import ( | ||
ATTR_BATTERY_CHARGING, | ||
ATTR_BATTERY_LEVEL, | ||
DEVICE_CLASS_BATTERY, | ||
DEVICE_CLASS_SIGNAL_STRENGTH, | ||
PERCENTAGE, | ||
) | ||
|
||
from .const import COORDINATORS, DEVICES, DOMAIN, HUB | ||
from .entity import SENSORS, DiffuserEntity | ||
|
||
ID = "id" | ||
TITLE = "title" | ||
ICON = "icon" | ||
WIFI = "wific" | ||
BATTERY = "battc" | ||
PERFUME = "rfidc" | ||
FILL = "fillc" | ||
|
||
BATTERY_CHARGING_ID = 21 | ||
PERFUME_NO_CARTRIDGE_ID = 19 | ||
FILL_NO_CARTRIDGE_ID = 12 | ||
|
||
BATTERY_SUFFIX = " Battery" | ||
PERFUME_SUFFIX = " Perfume" | ||
FILL_SUFFIX = " Fill" | ||
WIFI_SUFFIX = " Wifi" | ||
|
||
ATTR_SIGNAL_STRENGTH = "signal_strength" | ||
|
||
|
||
async def async_setup_entry(hass, config_entry, async_add_entities): | ||
"""Set up the diffuser sensors.""" | ||
diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES] | ||
coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS] | ||
entities = [] | ||
for hublot, diffuser in diffusers.items(): | ||
coordinator = coordinators[hublot] | ||
entities.append(DiffuserPerfumeSensor(diffuser, coordinator)) | ||
entities.append(DiffuserFillSensor(diffuser, coordinator)) | ||
entities.append(DiffuserWifiSensor(diffuser, coordinator)) | ||
if BATTERY in diffuser.data[HUB][SENSORS]: | ||
entities.append(DiffuserBatterySensor(diffuser, coordinator)) | ||
|
||
async_add_entities(entities) | ||
|
||
|
||
class DiffuserPerfumeSensor(DiffuserEntity): | ||
"""Representation of a diffuser perfume sensor.""" | ||
|
||
def __init__(self, diffuser, coordinator): | ||
"""Initialize the perfume sensor.""" | ||
super().__init__(diffuser, coordinator, PERFUME_SUFFIX) | ||
|
||
@property | ||
def icon(self): | ||
"""Return the perfume sensor icon.""" | ||
if self.coordinator.data[HUB][SENSORS][PERFUME][ID] == PERFUME_NO_CARTRIDGE_ID: | ||
return "mdi:tag-remove" | ||
return "mdi:tag-text" | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the perfume sensor.""" | ||
return self.coordinator.data[HUB][SENSORS][PERFUME][TITLE] | ||
|
||
|
||
class DiffuserFillSensor(DiffuserEntity): | ||
"""Representation of a diffuser fill sensor.""" | ||
|
||
def __init__(self, diffuser, coordinator): | ||
"""Initialize the fill sensor.""" | ||
super().__init__(diffuser, coordinator, FILL_SUFFIX) | ||
|
||
@property | ||
def icon(self): | ||
"""Return the fill sensor icon.""" | ||
if self.coordinator.data[HUB][SENSORS][FILL][ID] == FILL_NO_CARTRIDGE_ID: | ||
return "mdi:beaker-question" | ||
return "mdi:beaker" | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the fill sensor.""" | ||
return self.coordinator.data[HUB][SENSORS][FILL][TITLE] | ||
|
||
|
||
class DiffuserBatterySensor(DiffuserEntity): | ||
"""Representation of a diffuser battery sensor.""" | ||
|
||
def __init__(self, diffuser, coordinator): | ||
"""Initialize the battery sensor.""" | ||
super().__init__(diffuser, coordinator, BATTERY_SUFFIX) | ||
|
||
@property | ||
milanmeu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def state(self): | ||
"""Return the state of the battery sensor.""" | ||
# Use ICON because TITLE may change in the future. | ||
# 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 | ||
def _charging(self): | ||
"""Return battery charging state.""" | ||
return bool( | ||
self.coordinator.data[HUB][SENSORS][BATTERY][ID] == BATTERY_CHARGING_ID | ||
) | ||
|
||
@property | ||
def device_class(self): | ||
"""Return the class of the battery sensor.""" | ||
return DEVICE_CLASS_BATTERY | ||
|
||
@property | ||
def extra_state_attributes(self): | ||
"""Return the battery state attributes.""" | ||
return { | ||
ATTR_BATTERY_LEVEL: self.coordinator.data[HUB][SENSORS][BATTERY][TITLE], | ||
milanmeu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ATTR_BATTERY_CHARGING: self._charging, | ||
milanmeu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@property | ||
def unit_of_measurement(self): | ||
"""Return the battery unit of measurement.""" | ||
return PERCENTAGE | ||
|
||
|
||
class DiffuserWifiSensor(DiffuserEntity): | ||
"""Representation of a diffuser wifi sensor.""" | ||
|
||
def __init__(self, diffuser, coordinator): | ||
"""Initialize the wifi sensor.""" | ||
super().__init__(diffuser, coordinator, WIFI_SUFFIX) | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the wifi sensor.""" | ||
# Use ICON because TITLE may change in the future. | ||
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 | ||
def device_class(self): | ||
"""Return the class of the wifi sensor.""" | ||
return DEVICE_CLASS_SIGNAL_STRENGTH | ||
|
||
@property | ||
def extra_state_attributes(self): | ||
"""Return the wifi state attributes.""" | ||
return { | ||
ATTR_SIGNAL_STRENGTH: self.coordinator.data[HUB][SENSORS][WIFI][TITLE], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What measurement is this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as the battery. The description of the state as shown in the app: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it completely or make it a separate sensor entity. |
||
} | ||
|
||
@property | ||
def unit_of_measurement(self): | ||
"""Return the wifi unit of measurement.""" | ||
return PERCENTAGE |
Uh oh!
There was an error while loading. Please reload this page.