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
parent
d62bac9c59
commit
df7000f96d
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"])
|
||||||
|
|
Loading…
Reference in New Issue