diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 8af95c0fb33..314ee48cf7e 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -1,63 +1,15 @@ """Shelly entity helper.""" -from collections import Counter from dataclasses import dataclass from typing import Any, Callable, Optional, Union import aioshelly -from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.core import callback from homeassistant.helpers import device_registry, entity from . import ShellyDeviceWrapper from .const import DATA_CONFIG_ENTRY, DOMAIN - - -def temperature_unit(block_info: dict) -> str: - """Detect temperature unit.""" - if block_info[aioshelly.BLOCK_VALUE_UNIT] == "F": - return TEMP_FAHRENHEIT - return TEMP_CELSIUS - - -def shelly_naming(self, block, entity_type: str): - """Naming for switch and sensors.""" - - entity_name = self.wrapper.name - if not block: - return f"{entity_name} {self.description.name}" - - channels = 0 - mode = block.type + "s" - if "num_outputs" in self.wrapper.device.shelly: - channels = self.wrapper.device.shelly["num_outputs"] - if ( - self.wrapper.model in ["SHSW-21", "SHSW-25"] - and self.wrapper.device.settings["mode"] == "roller" - ): - channels = 1 - if block.type == "emeter" and "num_emeters" in self.wrapper.device.shelly: - channels = self.wrapper.device.shelly["num_emeters"] - if channels > 1 and block.type != "device": - # Shelly EM (SHEM) with firmware v1.8.1 doesn't have "name" key; will be fixed in next firmware release - if "name" in self.wrapper.device.settings[mode][int(block.channel)]: - entity_name = self.wrapper.device.settings[mode][int(block.channel)]["name"] - else: - entity_name = None - if not entity_name: - if self.wrapper.model == "SHEM-3": - base = ord("A") - else: - base = ord("1") - entity_name = f"{self.wrapper.name} channel {chr(int(block.channel)+base)}" - - if entity_type == "switch": - return entity_name - - if entity_type == "sensor": - return f"{entity_name} {self.description.name}" - - raise ValueError +from .utils import get_entity_name async def async_setup_entry_attribute_entities( @@ -84,11 +36,9 @@ async def async_setup_entry_attribute_entities( if not blocks: return - counts = Counter([item[1] for item in blocks]) - async_add_entities( [ - sensor_class(wrapper, block, sensor_id, description, counts[sensor_id]) + sensor_class(wrapper, block, sensor_id, description) for block, sensor_id, description in blocks ] ) @@ -117,7 +67,7 @@ class ShellyBlockEntity(entity.Entity): """Initialize Shelly entity.""" self.wrapper = wrapper self.block = block - self._name = shelly_naming(self, block, "switch") + self._name = get_entity_name(wrapper, block) @property def name(self): @@ -169,7 +119,6 @@ class ShellyBlockAttributeEntity(ShellyBlockEntity, entity.Entity): block: aioshelly.Block, attribute: str, description: BlockAttributeDescription, - same_type_count: int, ) -> None: """Initialize sensor.""" super().__init__(wrapper, block) @@ -184,7 +133,7 @@ class ShellyBlockAttributeEntity(ShellyBlockEntity, entity.Entity): self._unit = unit self._unique_id = f"{super().unique_id}-{self.attribute}" - self._name = shelly_naming(self, block, "sensor") + self._name = get_entity_name(wrapper, block, self.description.name) @property def unique_id(self): diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index e82f167ca60..ddd61b6b613 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -15,8 +15,8 @@ from .entity import ( BlockAttributeDescription, ShellyBlockAttributeEntity, async_setup_entry_attribute_entities, - temperature_unit, ) +from .utils import temperature_unit SENSORS = { ("device", "battery"): BlockAttributeDescription( diff --git a/homeassistant/components/shelly/utils.py b/homeassistant/components/shelly/utils.py index 72ba4dbd3cc..36ce48b5421 100644 --- a/homeassistant/components/shelly/utils.py +++ b/homeassistant/components/shelly/utils.py @@ -1,9 +1,14 @@ """Shelly helpers functions.""" - import logging +from typing import Optional +import aioshelly + +from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.helpers import entity_registry +from . import ShellyDeviceWrapper + _LOGGER = logging.getLogger(__name__) @@ -18,3 +23,53 @@ async def async_remove_entity_by_domain(hass, domain, unique_id, config_entry_id entity_reg.async_remove(entry.entity_id) _LOGGER.debug("Removed %s domain for %s", domain, entry.original_name) break + + +def temperature_unit(block_info: dict) -> str: + """Detect temperature unit.""" + if block_info[aioshelly.BLOCK_VALUE_UNIT] == "F": + return TEMP_FAHRENHEIT + return TEMP_CELSIUS + + +def get_entity_name( + wrapper: ShellyDeviceWrapper, + block: aioshelly.Block, + description: Optional[str] = None, +): + """Naming for switch and sensors.""" + entity_name = wrapper.name + + channels = None + if block.type == "input": + channels = wrapper.device.shelly.get("num_inputs") + elif block.type == "emeter": + channels = wrapper.device.shelly.get("num_emeters") + elif block.type in ["relay", "light"]: + channels = wrapper.device.shelly.get("num_outputs") + elif block.type in ["roller", "device"]: + channels = 1 + + channels = channels or 1 + + if channels > 1 and block.type != "device": + entity_name = None + mode = block.type + "s" + if mode in wrapper.device.settings: + entity_name = wrapper.device.settings[mode][int(block.channel)].get("name") + + if not entity_name: + if wrapper.model == "SHEM-3": + base = ord("A") + else: + base = ord("1") + entity_name = f"{wrapper.name} channel {chr(int(block.channel)+base)}" + + # Shelly Dimmer has two input channels and missing "num_inputs" + if wrapper.model in ["SHDM-1", "SHDM-2"] and block.type == "input": + entity_name = f"{entity_name} channel {int(block.channel)+1}" + + if description: + entity_name = f"{entity_name} {description}" + + return entity_name