From 7f093077e6269a19f06f7319765efe6b63969f9c Mon Sep 17 00:00:00 2001 From: milanmeu Date: Tue, 23 Mar 2021 20:26:09 +0000 Subject: [PATCH 01/11] Add Rituals Perfume Genie sensor platform --- .coveragerc | 2 + .../rituals_perfume_genie/__init__.py | 42 ++++- .../components/rituals_perfume_genie/const.py | 7 +- .../rituals_perfume_genie/entity.py | 44 ++++++ .../rituals_perfume_genie/sensor.py | 147 ++++++++++++++++++ .../rituals_perfume_genie/switch.py | 81 ++++------ 6 files changed, 269 insertions(+), 54 deletions(-) create mode 100644 homeassistant/components/rituals_perfume_genie/entity.py create mode 100644 homeassistant/components/rituals_perfume_genie/sensor.py diff --git a/.coveragerc b/.coveragerc index b7458cdff1da1..f76cf26ae9389 100644 --- a/.coveragerc +++ b/.coveragerc @@ -809,6 +809,8 @@ omit = homeassistant/components/rest/switch.py homeassistant/components/ring/camera.py homeassistant/components/ripple/sensor.py + homeassistant/components/rituals_perfume_genie/entity.py + homeassistant/components/rituals_perfume_genie/sensor.py homeassistant/components/rituals_perfume_genie/switch.py homeassistant/components/rituals_perfume_genie/__init__.py homeassistant/components/rocketchat/notify.py diff --git a/homeassistant/components/rituals_perfume_genie/__init__.py b/homeassistant/components/rituals_perfume_genie/__init__.py index f2fd13a9ef451..316be041ae70b 100644 --- a/homeassistant/components/rituals_perfume_genie/__init__.py +++ b/homeassistant/components/rituals_perfume_genie/__init__.py @@ -1,5 +1,6 @@ """The Rituals Perfume Genie integration.""" import asyncio +from datetime import timedelta import logging from aiohttp.client_exceptions import ClientConnectorError @@ -9,14 +10,16 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from .const import ACCOUNT_HASH, DOMAIN +from .const import ACCOUNT_HASH, COORDINATORS, DEVICES, DOMAIN, HUB, HUBLOT -_LOGGER = logging.getLogger(__name__) +PLATFORMS = ["switch", "sensor"] EMPTY_CREDENTIALS = "" -PLATFORMS = ["switch"] +_LOGGER = logging.getLogger(__name__) +UPDATE_INTERVAL = timedelta(seconds=30) async def async_setup(hass: HomeAssistant, config: dict): @@ -31,11 +34,40 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): account.data = {ACCOUNT_HASH: entry.data.get(ACCOUNT_HASH)} try: - await account.get_devices() + account_devices = await account.get_devices() except ClientConnectorError as ex: raise ConfigEntryNotReady from ex - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = account + 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] = { + COORDINATORS: {}, + DEVICES: devices, + } + + for hublot in hublots: + device = hass.data[DOMAIN][entry.entry_id][DEVICES][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, + ) + + await coordinator.async_refresh() + + hass.data[DOMAIN][entry.entry_id][COORDINATORS][hublot] = coordinator for platform in PLATFORMS: hass.async_create_task( diff --git a/homeassistant/components/rituals_perfume_genie/const.py b/homeassistant/components/rituals_perfume_genie/const.py index 075d79ec8de9e..16189c8335eda 100644 --- a/homeassistant/components/rituals_perfume_genie/const.py +++ b/homeassistant/components/rituals_perfume_genie/const.py @@ -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" diff --git a/homeassistant/components/rituals_perfume_genie/entity.py b/homeassistant/components/rituals_perfume_genie/entity.py new file mode 100644 index 0000000000000..2f47024b08b5a --- /dev/null +++ b/homeassistant/components/rituals_perfume_genie/entity.py @@ -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 self._hublot + self._entity_suffix + + @property + def name(self): + """Return the name of the entity.""" + return 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], + } diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py new file mode 100644 index 0000000000000..1b0333c90ae40 --- /dev/null +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -0,0 +1,147 @@ +"""Support for Rituals Perfume Genie sensors.""" +from homeassistant.const import ( + ATTR_BATTERY_CHARGING, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_SIGNAL_STRENGTH, +) + +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" + + +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 + def icon(self): + """Return the battery sensor icon.""" + return { + "battery-charge.png": "mdi:battery-charging", + "battery-full.png": "mdi:battery", + "battery-75.png": "mdi:battery-50", + "battery-50.png": "mdi:battery-20", + "battery-low.png": "mdi:battery-alert", + }[self.coordinator.data[HUB][SENSORS][BATTERY][ICON]] + + @property + def state(self): + """Return the state of the battery sensor.""" + return self.coordinator.data[HUB][SENSORS][BATTERY][TITLE] + + @property + def device_class(self): + """Return the class of the battery sensor.""" + return DEVICE_CLASS_BATTERY + + @property + def device_state_attributes(self): + """Return the battery state attributes.""" + return { + ATTR_BATTERY_CHARGING: self.coordinator.data[HUB][SENSORS][BATTERY][ID] + == BATTERY_CHARGING_ID + } + + +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 icon(self): + """Return the wifi sensor icon.""" + return { + "icon-signal.png": "mdi:wifi-strength-4", + "icon-signal-75.png": "mdi:wifi-strength-3", + "icon-signal-low.png": "mdi:wifi-strength-1", + "icon-signal-0.png": "mdi:wifi-strength-outline", + }[self.coordinator.data[HUB][SENSORS][WIFI][ICON]] + + @property + def state(self): + """Return the state of the wifi sensor.""" + return self.coordinator.data[HUB][SENSORS][WIFI][TITLE] + + @property + def device_class(self): + """Return the class of the wifi sensor.""" + return DEVICE_CLASS_SIGNAL_STRENGTH diff --git a/homeassistant/components/rituals_perfume_genie/switch.py b/homeassistant/components/rituals_perfume_genie/switch.py index 471be52b054af..d1fff166f6e0c 100644 --- a/homeassistant/components/rituals_perfume_genie/switch.py +++ b/homeassistant/components/rituals_perfume_genie/switch.py @@ -1,92 +1,77 @@ """Support for Rituals Perfume Genie switches.""" -from datetime import timedelta - from homeassistant.components.switch import SwitchEntity +from homeassistant.core import callback -from .const import DOMAIN +from .const import ATTRIBUTES, COORDINATORS, DEVICES, DOMAIN, HUB +from .entity import DiffuserEntity -SCAN_INTERVAL = timedelta(seconds=30) +STATUS = "status" +FAN = "fanc" +SPEED = "speedc" +ROOM = "roomc" ON_STATE = "1" AVAILABLE_STATE = 1 -MANUFACTURER = "Rituals Cosmetics" -MODEL = "Diffuser" -ICON = "mdi:fan" - async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the diffuser switch.""" - account = hass.data[DOMAIN][config_entry.entry_id] - diffusers = await account.get_devices() - + diffusers = hass.data[DOMAIN][config_entry.entry_id][DEVICES] + coordinators = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS] entities = [] - for diffuser in diffusers: - entities.append(DiffuserSwitch(diffuser)) + for hublot, diffuser in diffusers.items(): + coordinator = coordinators[hublot] + entities.append(DiffuserSwitch(diffuser, coordinator)) - async_add_entities(entities, True) + async_add_entities(entities) -class DiffuserSwitch(SwitchEntity): +class DiffuserSwitch(SwitchEntity, DiffuserEntity): """Representation of a diffuser switch.""" - def __init__(self, diffuser): - """Initialize the switch.""" - self._diffuser = diffuser - - @property - def device_info(self): - """Return information about the device.""" - return { - "name": self._diffuser.data["hub"]["attributes"]["roomnamec"], - "identifiers": {(DOMAIN, self._diffuser.data["hub"]["hublot"])}, - "manufacturer": MANUFACTURER, - "model": MODEL, - "sw_version": self._diffuser.data["hub"]["sensors"]["versionc"], - } - - @property - def unique_id(self): - """Return the unique ID of the device.""" - return self._diffuser.data["hub"]["hublot"] + def __init__(self, diffuser, coordinator): + """Initialize the diffuser switch.""" + super().__init__(diffuser, coordinator, "") + self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE @property def available(self): """Return if the device is available.""" - return self._diffuser.data["hub"]["status"] == AVAILABLE_STATE - - @property - def name(self): - """Return the name of the device.""" - return self._diffuser.data["hub"]["attributes"]["roomnamec"] + return self.coordinator.data[HUB][STATUS] == AVAILABLE_STATE @property def icon(self): """Return the icon of the device.""" - return ICON + return "mdi:fan" @property def extra_state_attributes(self): """Return the device state attributes.""" attributes = { - "fan_speed": self._diffuser.data["hub"]["attributes"]["speedc"], - "room_size": self._diffuser.data["hub"]["attributes"]["roomc"], + "fan_speed": self.coordinator.data[HUB][ATTRIBUTES][SPEED], + "room_size": self.coordinator.data[HUB][ATTRIBUTES][ROOM], } return attributes @property def is_on(self): """If the device is currently on or off.""" - return self._diffuser.data["hub"]["attributes"]["fanc"] == ON_STATE + return self._is_on async def async_turn_on(self, **kwargs): """Turn the device on.""" await self._diffuser.turn_on() + self._is_on = True + self.schedule_update_ha_state() async def async_turn_off(self, **kwargs): """Turn the device off.""" await self._diffuser.turn_off() - - async def async_update(self): - """Update the data of the device.""" - await self._diffuser.update_data() + self._is_on = False + self.schedule_update_ha_state() + + @callback + def _handle_coordinator_update(self): + """Handle updated data from the coordinator.""" + self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE + self.async_write_ha_state() From b808af0b5a9e0c5ca70d1a59ac0c1d724da2daf5 Mon Sep 17 00:00:00 2001 From: Milan Meulemans Date: Wed, 31 Mar 2021 09:02:31 +0200 Subject: [PATCH 02/11] Rename to extra_state_attributes --- homeassistant/components/rituals_perfume_genie/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index 1b0333c90ae40..25b991c874fd5 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -111,7 +111,7 @@ def device_class(self): return DEVICE_CLASS_BATTERY @property - def device_state_attributes(self): + def extra_state_attributes(self): """Return the battery state attributes.""" return { ATTR_BATTERY_CHARGING: self.coordinator.data[HUB][SENSORS][BATTERY][ID] From ddafa58db099fbbded8951e232b5cc8a7f24c618 Mon Sep 17 00:00:00 2001 From: milanmeu Date: Sun, 4 Apr 2021 21:11:14 +0000 Subject: [PATCH 03/11] Use f-strings --- homeassistant/components/rituals_perfume_genie/entity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/entity.py b/homeassistant/components/rituals_perfume_genie/entity.py index 2f47024b08b5a..ba8f583d04217 100644 --- a/homeassistant/components/rituals_perfume_genie/entity.py +++ b/homeassistant/components/rituals_perfume_genie/entity.py @@ -25,12 +25,12 @@ def __init__(self, diffuser, coordinator, entity_suffix): @property def unique_id(self): """Return the unique ID of the entity.""" - return self._hublot + self._entity_suffix + return f"{self._hublot}{self._entity_suffix}" @property def name(self): """Return the name of the entity.""" - return self._hubname + self._entity_suffix + return f"{self._hubname}{self._entity_suffix}" @property def device_info(self): From d7c96cabfb621a3e6bca53c2e6f277e646d12936 Mon Sep 17 00:00:00 2001 From: milanmeu Date: Sun, 4 Apr 2021 21:15:05 +0000 Subject: [PATCH 04/11] Drop async_setup since it does nothing --- homeassistant/components/rituals_perfume_genie/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/__init__.py b/homeassistant/components/rituals_perfume_genie/__init__.py index 316be041ae70b..610700e8fe5af 100644 --- a/homeassistant/components/rituals_perfume_genie/__init__.py +++ b/homeassistant/components/rituals_perfume_genie/__init__.py @@ -22,11 +22,6 @@ UPDATE_INTERVAL = timedelta(seconds=30) -async def async_setup(hass: HomeAssistant, config: dict): - """Set up the Rituals Perfume Genie component.""" - return True - - async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): """Set up Rituals Perfume Genie from a config entry.""" session = async_get_clientsession(hass) From 25f7d60b7fd3fc17d1f39f47ff9601132679d1aa Mon Sep 17 00:00:00 2001 From: milanmeu Date: Sun, 4 Apr 2021 21:52:35 +0000 Subject: [PATCH 05/11] Remove async_setup test --- tests/components/rituals_perfume_genie/test_config_flow.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/components/rituals_perfume_genie/test_config_flow.py b/tests/components/rituals_perfume_genie/test_config_flow.py index 92c3e15c2478c..e5c64dd54c91c 100644 --- a/tests/components/rituals_perfume_genie/test_config_flow.py +++ b/tests/components/rituals_perfume_genie/test_config_flow.py @@ -32,8 +32,6 @@ async def test_form(hass): "homeassistant.components.rituals_perfume_genie.config_flow.Account", side_effect=_mock_account, ), patch( - "homeassistant.components.rituals_perfume_genie.async_setup", return_value=True - ) as mock_setup, patch( "homeassistant.components.rituals_perfume_genie.async_setup_entry", return_value=True, ) as mock_setup_entry: @@ -49,7 +47,6 @@ async def test_form(hass): assert result2["type"] == "create_entry" assert result2["title"] == TEST_EMAIL assert isinstance(result2["data"][ACCOUNT_HASH], str) - assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 From 68488b70e5ba54876be735a9f0dc0d28ed66b4ee Mon Sep 17 00:00:00 2001 From: milanmeu Date: Mon, 5 Apr 2021 12:33:43 +0000 Subject: [PATCH 06/11] Change DiffuserBatterySensor --- .../rituals_perfume_genie/sensor.py | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index 25b991c874fd5..e41dd079702e3 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -1,9 +1,12 @@ """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 homeassistant.helpers.icon import icon_for_battery_level from .const import COORDINATORS, DEVICES, DOMAIN, HUB from .entity import SENSORS, DiffuserEntity @@ -92,18 +95,27 @@ def __init__(self, diffuser, coordinator): @property def icon(self): """Return the battery sensor icon.""" - return { - "battery-charge.png": "mdi:battery-charging", - "battery-full.png": "mdi:battery", - "battery-75.png": "mdi:battery-50", - "battery-50.png": "mdi:battery-20", - "battery-low.png": "mdi:battery-alert", - }[self.coordinator.data[HUB][SENSORS][BATTERY][ICON]] + return icon_for_battery_level(battery_level=self.state, charging=self._charging) @property def state(self): """Return the state of the battery sensor.""" - return self.coordinator.data[HUB][SENSORS][BATTERY][TITLE] + # 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): @@ -114,10 +126,15 @@ def device_class(self): def extra_state_attributes(self): """Return the battery state attributes.""" return { - ATTR_BATTERY_CHARGING: self.coordinator.data[HUB][SENSORS][BATTERY][ID] - == BATTERY_CHARGING_ID + ATTR_BATTERY_LEVEL: self.coordinator.data[HUB][SENSORS][BATTERY][TITLE], + ATTR_BATTERY_CHARGING: self._charging, } + @property + def unit_of_measurement(self): + """Return the battery unit of measurement.""" + return PERCENTAGE + class DiffuserWifiSensor(DiffuserEntity): """Representation of a diffuser wifi sensor.""" From 6f8eeb426ab1234b95f5a764e16e4c25dd8e9c52 Mon Sep 17 00:00:00 2001 From: milanmeu Date: Mon, 5 Apr 2021 12:56:07 +0000 Subject: [PATCH 07/11] Change DiffuserWifiSensor --- .../rituals_perfume_genie/sensor.py | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index e41dd079702e3..1cf2f0061faa4 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -6,7 +6,7 @@ DEVICE_CLASS_SIGNAL_STRENGTH, PERCENTAGE, ) -from homeassistant.helpers.icon import icon_for_battery_level +from homeassistant.helpers.icon import icon_for_battery_level, icon_for_signal_level from .const import COORDINATORS, DEVICES, DOMAIN, HUB from .entity import SENSORS, DiffuserEntity @@ -28,6 +28,8 @@ 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.""" @@ -146,19 +148,32 @@ def __init__(self, diffuser, coordinator): @property def icon(self): """Return the wifi sensor icon.""" - return { - "icon-signal.png": "mdi:wifi-strength-4", - "icon-signal-75.png": "mdi:wifi-strength-3", - "icon-signal-low.png": "mdi:wifi-strength-1", - "icon-signal-0.png": "mdi:wifi-strength-outline", - }[self.coordinator.data[HUB][SENSORS][WIFI][ICON]] + return icon_for_signal_level(self.state) @property def state(self): """Return the state of the wifi sensor.""" - return self.coordinator.data[HUB][SENSORS][WIFI][TITLE] + # 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], + } + + @property + def unit_of_measurement(self): + """Return the wifi unit of measurement.""" + return PERCENTAGE From 9fc54226e0a63f3cb2b3216d45413f1195526420 Mon Sep 17 00:00:00 2001 From: Milan Meulemans Date: Sun, 11 Apr 2021 00:52:06 +0200 Subject: [PATCH 08/11] Fix W292 no newline at end of file --- homeassistant/components/rituals_perfume_genie/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rituals_perfume_genie/switch.py b/homeassistant/components/rituals_perfume_genie/switch.py index eb74a1402c434..d1fff166f6e0c 100644 --- a/homeassistant/components/rituals_perfume_genie/switch.py +++ b/homeassistant/components/rituals_perfume_genie/switch.py @@ -74,4 +74,4 @@ async def async_turn_off(self, **kwargs): def _handle_coordinator_update(self): """Handle updated data from the coordinator.""" self._is_on = self.coordinator.data[HUB][ATTRIBUTES][FAN] == ON_STATE - self.async_write_ha_state() \ No newline at end of file + self.async_write_ha_state() From 86b1a753b75d72c7c0cfaa3bc89f2b948c4877a4 Mon Sep 17 00:00:00 2001 From: Milan Meulemans Date: Sun, 11 Apr 2021 13:29:15 +0200 Subject: [PATCH 09/11] Remove battery icon Co-authored-by: J. Nick Koston --- homeassistant/components/rituals_perfume_genie/sensor.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index 1cf2f0061faa4..c31735207d392 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -94,11 +94,6 @@ def __init__(self, diffuser, coordinator): """Initialize the battery sensor.""" super().__init__(diffuser, coordinator, BATTERY_SUFFIX) - @property - def icon(self): - """Return the battery sensor icon.""" - return icon_for_battery_level(battery_level=self.state, charging=self._charging) - @property def state(self): """Return the state of the battery sensor.""" From f72b70bd94eadf53b8a59cc9de573a2b5d665810 Mon Sep 17 00:00:00 2001 From: Milan Meulemans Date: Sun, 11 Apr 2021 13:29:38 +0200 Subject: [PATCH 10/11] Remove wifi icon Co-authored-by: J. Nick Koston --- homeassistant/components/rituals_perfume_genie/sensor.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index c31735207d392..e7f8e6ff0b84f 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -140,11 +140,6 @@ def __init__(self, diffuser, coordinator): """Initialize the wifi sensor.""" super().__init__(diffuser, coordinator, WIFI_SUFFIX) - @property - def icon(self): - """Return the wifi sensor icon.""" - return icon_for_signal_level(self.state) - @property def state(self): """Return the state of the wifi sensor.""" From d88271013a19243bf6aaf4ec998a4398c4052e29 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 11 Apr 2021 06:59:17 -1000 Subject: [PATCH 11/11] Update homeassistant/components/rituals_perfume_genie/sensor.py --- homeassistant/components/rituals_perfume_genie/sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/rituals_perfume_genie/sensor.py b/homeassistant/components/rituals_perfume_genie/sensor.py index e7f8e6ff0b84f..4a3ac34cc5872 100644 --- a/homeassistant/components/rituals_perfume_genie/sensor.py +++ b/homeassistant/components/rituals_perfume_genie/sensor.py @@ -6,7 +6,6 @@ DEVICE_CLASS_SIGNAL_STRENGTH, PERCENTAGE, ) -from homeassistant.helpers.icon import icon_for_battery_level, icon_for_signal_level from .const import COORDINATORS, DEVICES, DOMAIN, HUB from .entity import SENSORS, DiffuserEntity