mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Fix restored temperature values in Shelly climate platform (#83428)
* Set last_target_temp value according the unit system * Convert restored temperature values * Add test * Improve comments * Move _last_target_temp value to constants
This commit is contained in:
parent
fa98685b1e
commit
e11917b7cb
@ -24,6 +24,8 @@ from homeassistant.helpers.entity import DeviceInfo
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||||
|
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||||
|
|
||||||
from .const import LOGGER, SHTRV_01_TEMPERATURE_SETTINGS
|
from .const import LOGGER, SHTRV_01_TEMPERATURE_SETTINGS
|
||||||
from .coordinator import ShellyBlockCoordinator, get_entry_data
|
from .coordinator import ShellyBlockCoordinator, get_entry_data
|
||||||
@ -126,7 +128,14 @@ class BlockSleepingClimate(
|
|||||||
self.last_state: State | None = None
|
self.last_state: State | None = None
|
||||||
self.last_state_attributes: Mapping[str, Any]
|
self.last_state_attributes: Mapping[str, Any]
|
||||||
self._preset_modes: list[str] = []
|
self._preset_modes: list[str] = []
|
||||||
self._last_target_temp = 20.0
|
if coordinator.hass.config.units is US_CUSTOMARY_SYSTEM:
|
||||||
|
self._last_target_temp = TemperatureConverter.convert(
|
||||||
|
SHTRV_01_TEMPERATURE_SETTINGS["default"],
|
||||||
|
UnitOfTemperature.CELSIUS,
|
||||||
|
UnitOfTemperature.FAHRENHEIT,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self._last_target_temp = SHTRV_01_TEMPERATURE_SETTINGS["default"]
|
||||||
|
|
||||||
if self.block is not None and self.device_block is not None:
|
if self.block is not None and self.device_block is not None:
|
||||||
self._unique_id = f"{self.coordinator.mac}-{self.block.description}"
|
self._unique_id = f"{self.coordinator.mac}-{self.block.description}"
|
||||||
@ -157,14 +166,32 @@ class BlockSleepingClimate(
|
|||||||
"""Set target temperature."""
|
"""Set target temperature."""
|
||||||
if self.block is not None:
|
if self.block is not None:
|
||||||
return cast(float, self.block.targetTemp)
|
return cast(float, self.block.targetTemp)
|
||||||
return self.last_state_attributes.get("temperature")
|
# The restored value can be in Fahrenheit so we have to convert it to Celsius
|
||||||
|
# because we use this unit internally in integration.
|
||||||
|
target_temp = self.last_state_attributes.get("temperature")
|
||||||
|
if self.hass.config.units is US_CUSTOMARY_SYSTEM and target_temp:
|
||||||
|
return TemperatureConverter.convert(
|
||||||
|
cast(float, target_temp),
|
||||||
|
UnitOfTemperature.FAHRENHEIT,
|
||||||
|
UnitOfTemperature.CELSIUS,
|
||||||
|
)
|
||||||
|
return target_temp
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_temperature(self) -> float | None:
|
def current_temperature(self) -> float | None:
|
||||||
"""Return current temperature."""
|
"""Return current temperature."""
|
||||||
if self.block is not None:
|
if self.block is not None:
|
||||||
return cast(float, self.block.temp)
|
return cast(float, self.block.temp)
|
||||||
return self.last_state_attributes.get("current_temperature")
|
# The restored value can be in Fahrenheit so we have to convert it to Celsius
|
||||||
|
# because we use this unit internally in integration.
|
||||||
|
current_temp = self.last_state_attributes.get("current_temperature")
|
||||||
|
if self.hass.config.units is US_CUSTOMARY_SYSTEM and current_temp:
|
||||||
|
return TemperatureConverter.convert(
|
||||||
|
cast(float, current_temp),
|
||||||
|
UnitOfTemperature.FAHRENHEIT,
|
||||||
|
UnitOfTemperature.CELSIUS,
|
||||||
|
)
|
||||||
|
return current_temp
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
|
@ -147,6 +147,7 @@ SHTRV_01_TEMPERATURE_SETTINGS: Final = {
|
|||||||
"min": 4,
|
"min": 4,
|
||||||
"max": 31,
|
"max": 31,
|
||||||
"step": 0.5,
|
"step": 0.5,
|
||||||
|
"default": 20.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kelvin value for colorTemp
|
# Kelvin value for colorTemp
|
||||||
|
@ -21,6 +21,7 @@ from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
|||||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_UNAVAILABLE
|
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_UNAVAILABLE
|
||||||
from homeassistant.core import State
|
from homeassistant.core import State
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||||
|
|
||||||
from . import init_integration, register_device, register_entity
|
from . import init_integration, register_device, register_entity
|
||||||
|
|
||||||
@ -212,6 +213,53 @@ async def test_block_restored_climate(hass, mock_block_device, device_reg, monke
|
|||||||
assert hass.states.get(entity_id).state == HVACMode.OFF
|
assert hass.states.get(entity_id).state == HVACMode.OFF
|
||||||
|
|
||||||
|
|
||||||
|
async def test_block_restored_climate_us_customery(
|
||||||
|
hass, mock_block_device, device_reg, monkeypatch
|
||||||
|
):
|
||||||
|
"""Test block restored climate with US CUSTOMATY unit system."""
|
||||||
|
hass.config.units = US_CUSTOMARY_SYSTEM
|
||||||
|
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
|
||||||
|
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||||
|
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||||
|
register_device(device_reg, entry)
|
||||||
|
entity_id = register_entity(
|
||||||
|
hass,
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
"test_name",
|
||||||
|
"sensor_0",
|
||||||
|
entry,
|
||||||
|
)
|
||||||
|
attrs = {"current_temperature": 67, "temperature": 68}
|
||||||
|
mock_restore_cache(hass, [State(entity_id, HVACMode.HEAT, attributes=attrs)])
|
||||||
|
|
||||||
|
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == HVACMode.HEAT
|
||||||
|
assert hass.states.get(entity_id).attributes.get("temperature") == 68
|
||||||
|
assert hass.states.get(entity_id).attributes.get("current_temperature") == 67
|
||||||
|
|
||||||
|
# Partial update, should not change state
|
||||||
|
mock_block_device.mock_update()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == HVACMode.HEAT
|
||||||
|
assert hass.states.get(entity_id).attributes.get("temperature") == 68
|
||||||
|
assert hass.states.get(entity_id).attributes.get("current_temperature") == 67
|
||||||
|
|
||||||
|
# Make device online
|
||||||
|
monkeypatch.setattr(mock_block_device, "initialized", True)
|
||||||
|
monkeypatch.setattr(mock_block_device.blocks[SENSOR_BLOCK_ID], "targetTemp", 19.7)
|
||||||
|
monkeypatch.setattr(mock_block_device.blocks[SENSOR_BLOCK_ID], "temp", 18.2)
|
||||||
|
mock_block_device.mock_update()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == HVACMode.HEAT
|
||||||
|
assert hass.states.get(entity_id).attributes.get("temperature") == 67
|
||||||
|
assert hass.states.get(entity_id).attributes.get("current_temperature") == 65
|
||||||
|
|
||||||
|
|
||||||
async def test_block_restored_climate_unavailable(
|
async def test_block_restored_climate_unavailable(
|
||||||
hass, mock_block_device, device_reg, monkeypatch
|
hass, mock_block_device, device_reg, monkeypatch
|
||||||
):
|
):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user