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."""
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):

View file

@ -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(

View file

@ -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