Always use Celsius in Shelly integration, part 2 (#81602)

* Always use Celsius in Shelly integration

* Update homeassistant/components/shelly/sensor.py

Co-authored-by: Aarni Koskela <akx@iki.fi>

* Restore unit from the registry during HA startup

Co-authored-by: Aarni Koskela <akx@iki.fi>
pull/65000/head^2
Maciej Bieniek 2022-11-06 21:23:48 +01:00 committed by GitHub
parent d62bac9c59
commit df7000f96d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 19 deletions

View File

@ -9,6 +9,7 @@ from aioshelly.block_device import Block
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry, entity, entity_registry from homeassistant.helpers import device_registry, entity, entity_registry
@ -615,6 +616,7 @@ class ShellySleepingBlockAttributeEntity(ShellyBlockAttributeEntity, RestoreEnti
"""Initialize the sleeping sensor.""" """Initialize the sleeping sensor."""
self.sensors = sensors self.sensors = sensors
self.last_state: StateType = None self.last_state: StateType = None
self.last_unit: str | None = None
self.coordinator = coordinator self.coordinator = coordinator
self.attribute = attribute self.attribute = attribute
self.block: Block | None = block # type: ignore[assignment] self.block: Block | None = block # type: ignore[assignment]
@ -644,6 +646,7 @@ class ShellySleepingBlockAttributeEntity(ShellyBlockAttributeEntity, RestoreEnti
if last_state is not None: if last_state is not None:
self.last_state = last_state.state self.last_state = last_state.state
self.last_unit = last_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
@callback @callback
def _update_callback(self) -> None: def _update_callback(self) -> None:
@ -696,6 +699,7 @@ class ShellySleepingRpcAttributeEntity(ShellyRpcAttributeEntity, RestoreEntity):
) -> None: ) -> None:
"""Initialize the sleeping sensor.""" """Initialize the sleeping sensor."""
self.last_state: StateType = None self.last_state: StateType = None
self.last_unit: str | None = None
self.coordinator = coordinator self.coordinator = coordinator
self.key = key self.key = key
self.attribute = attribute self.attribute = attribute
@ -725,3 +729,4 @@ class ShellySleepingRpcAttributeEntity(ShellyRpcAttributeEntity, RestoreEntity):
if last_state is not None: if last_state is not None:
self.last_state = last_state.state self.last_state = last_state.state
self.last_unit = last_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)

View File

@ -47,7 +47,7 @@ from .entity import (
async_setup_entry_rest, async_setup_entry_rest,
async_setup_entry_rpc, async_setup_entry_rpc,
) )
from .utils import get_device_entry_gen, get_device_uptime, temperature_unit from .utils import get_device_entry_gen, get_device_uptime
@dataclass @dataclass
@ -79,7 +79,7 @@ SENSORS: Final = {
("device", "deviceTemp"): BlockSensorDescription( ("device", "deviceTemp"): BlockSensorDescription(
key="device|deviceTemp", key="device|deviceTemp",
name="Device Temperature", name="Device Temperature",
unit_fn=temperature_unit, native_unit_of_measurement=TEMP_CELSIUS,
value=lambda value: round(value, 1), value=lambda value: round(value, 1),
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -221,7 +221,7 @@ SENSORS: Final = {
("sensor", "temp"): BlockSensorDescription( ("sensor", "temp"): BlockSensorDescription(
key="sensor|temp", key="sensor|temp",
name="Temperature", name="Temperature",
unit_fn=temperature_unit, native_unit_of_measurement=TEMP_CELSIUS,
value=lambda value: round(value, 1), value=lambda value: round(value, 1),
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -230,7 +230,7 @@ SENSORS: Final = {
("sensor", "extTemp"): BlockSensorDescription( ("sensor", "extTemp"): BlockSensorDescription(
key="sensor|extTemp", key="sensor|extTemp",
name="Temperature", name="Temperature",
unit_fn=temperature_unit, native_unit_of_measurement=TEMP_CELSIUS,
value=lambda value: round(value, 1), value=lambda value: round(value, 1),
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
@ -499,8 +499,6 @@ class BlockSensor(ShellyBlockAttributeEntity, SensorEntity):
super().__init__(coordinator, block, attribute, description) super().__init__(coordinator, block, attribute, description)
self._attr_native_unit_of_measurement = description.native_unit_of_measurement self._attr_native_unit_of_measurement = description.native_unit_of_measurement
if unit_fn := description.unit_fn:
self._attr_native_unit_of_measurement = unit_fn(block.info(attribute))
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType:
@ -547,10 +545,6 @@ class BlockSleepingSensor(ShellySleepingBlockAttributeEntity, SensorEntity):
"""Initialize the sleeping sensor.""" """Initialize the sleeping sensor."""
super().__init__(coordinator, block, attribute, description, entry, sensors) super().__init__(coordinator, block, attribute, description, entry, sensors)
self._attr_native_unit_of_measurement = description.native_unit_of_measurement
if block and (unit_fn := description.unit_fn):
self._attr_native_unit_of_measurement = unit_fn(block.info(attribute))
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType:
"""Return value of sensor.""" """Return value of sensor."""
@ -559,6 +553,14 @@ class BlockSleepingSensor(ShellySleepingBlockAttributeEntity, SensorEntity):
return self.last_state return self.last_state
@property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of the sensor, if any."""
if self.block is not None:
return self.entity_description.native_unit_of_measurement
return self.last_unit
class RpcSleepingSensor(ShellySleepingRpcAttributeEntity, SensorEntity): class RpcSleepingSensor(ShellySleepingRpcAttributeEntity, SensorEntity):
"""Represent a RPC sleeping sensor.""" """Represent a RPC sleeping sensor."""
@ -572,3 +574,11 @@ class RpcSleepingSensor(ShellySleepingRpcAttributeEntity, SensorEntity):
return self.attribute_value return self.attribute_value
return self.last_state return self.last_state
@property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of the sensor, if any."""
if self.coordinator.device.initialized:
return self.entity_description.native_unit_of_measurement
return self.last_unit

View File

@ -5,13 +5,13 @@ from datetime import datetime, timedelta
from typing import Any, cast from typing import Any, cast
from aiohttp.web import Request, WebSocketResponse from aiohttp.web import Request, WebSocketResponse
from aioshelly.block_device import BLOCK_VALUE_UNIT, COAP, Block, BlockDevice from aioshelly.block_device import COAP, Block, BlockDevice
from aioshelly.const import MODEL_NAMES from aioshelly.const import MODEL_NAMES
from aioshelly.rpc_device import RpcDevice, WsServer from aioshelly.rpc_device import RpcDevice, WsServer
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry, entity_registry, singleton from homeassistant.helpers import device_registry, entity_registry, singleton
from homeassistant.helpers.typing import EventType from homeassistant.helpers.typing import EventType
@ -43,13 +43,6 @@ def async_remove_shelly_entity(
entity_reg.async_remove(entity_id) entity_reg.async_remove(entity_id)
def temperature_unit(block_info: dict[str, Any]) -> str:
"""Detect temperature unit."""
if block_info[BLOCK_VALUE_UNIT] == "F":
return TEMP_FAHRENHEIT
return TEMP_CELSIUS
def get_block_device_name(device: BlockDevice) -> str: def get_block_device_name(device: BlockDevice) -> str:
"""Naming for device.""" """Naming for device."""
return cast(str, device.settings["name"] or device.settings["device"]["hostname"]) return cast(str, device.settings["name"] or device.settings["device"]["hostname"])