Cleanup and naming schema fixes for Shelly (#42987)

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
Shay Levy 2020-11-11 10:05:08 +02:00 committed by GitHub
parent 94bf55e29b
commit 0ddf14a98a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 57 deletions

View File

@ -1,63 +1,15 @@
"""Shelly entity helper.""" """Shelly entity helper."""
from collections import Counter
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Callable, Optional, Union from typing import Any, Callable, Optional, Union
import aioshelly import aioshelly
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers import device_registry, entity from homeassistant.helpers import device_registry, entity
from . import ShellyDeviceWrapper from . import ShellyDeviceWrapper
from .const import DATA_CONFIG_ENTRY, DOMAIN from .const import DATA_CONFIG_ENTRY, DOMAIN
from .utils import get_entity_name
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
async def async_setup_entry_attribute_entities( async def async_setup_entry_attribute_entities(
@ -84,11 +36,9 @@ async def async_setup_entry_attribute_entities(
if not blocks: if not blocks:
return return
counts = Counter([item[1] for item in blocks])
async_add_entities( 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 for block, sensor_id, description in blocks
] ]
) )
@ -117,7 +67,7 @@ class ShellyBlockEntity(entity.Entity):
"""Initialize Shelly entity.""" """Initialize Shelly entity."""
self.wrapper = wrapper self.wrapper = wrapper
self.block = block self.block = block
self._name = shelly_naming(self, block, "switch") self._name = get_entity_name(wrapper, block)
@property @property
def name(self): def name(self):
@ -169,7 +119,6 @@ class ShellyBlockAttributeEntity(ShellyBlockEntity, entity.Entity):
block: aioshelly.Block, block: aioshelly.Block,
attribute: str, attribute: str,
description: BlockAttributeDescription, description: BlockAttributeDescription,
same_type_count: int,
) -> None: ) -> None:
"""Initialize sensor.""" """Initialize sensor."""
super().__init__(wrapper, block) super().__init__(wrapper, block)
@ -184,7 +133,7 @@ class ShellyBlockAttributeEntity(ShellyBlockEntity, entity.Entity):
self._unit = unit self._unit = unit
self._unique_id = f"{super().unique_id}-{self.attribute}" 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 @property
def unique_id(self): def unique_id(self):

View File

@ -15,8 +15,8 @@ from .entity import (
BlockAttributeDescription, BlockAttributeDescription,
ShellyBlockAttributeEntity, ShellyBlockAttributeEntity,
async_setup_entry_attribute_entities, async_setup_entry_attribute_entities,
temperature_unit,
) )
from .utils import temperature_unit
SENSORS = { SENSORS = {
("device", "battery"): BlockAttributeDescription( ("device", "battery"): BlockAttributeDescription(

View File

@ -1,9 +1,14 @@
"""Shelly helpers functions.""" """Shelly helpers functions."""
import logging import logging
from typing import Optional
import aioshelly
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
from homeassistant.helpers import entity_registry from homeassistant.helpers import entity_registry
from . import ShellyDeviceWrapper
_LOGGER = logging.getLogger(__name__) _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) entity_reg.async_remove(entry.entity_id)
_LOGGER.debug("Removed %s domain for %s", domain, entry.original_name) _LOGGER.debug("Removed %s domain for %s", domain, entry.original_name)
break 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