1
mirror of https://github.com/home-assistant/core synced 2024-09-06 10:29:55 +02: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:
Maciej Bieniek 2022-12-07 08:11:18 +01:00 committed by GitHub
parent fa98685b1e
commit e11917b7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 3 deletions

View File

@ -24,6 +24,8 @@ from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
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 .coordinator import ShellyBlockCoordinator, get_entry_data
@ -126,7 +128,14 @@ class BlockSleepingClimate(
self.last_state: State | None = None
self.last_state_attributes: Mapping[str, Any]
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:
self._unique_id = f"{self.coordinator.mac}-{self.block.description}"
@ -157,14 +166,32 @@ class BlockSleepingClimate(
"""Set target temperature."""
if self.block is not None:
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
def current_temperature(self) -> float | None:
"""Return current temperature."""
if self.block is not None:
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
def available(self) -> bool:

View File

@ -147,6 +147,7 @@ SHTRV_01_TEMPERATURE_SETTINGS: Final = {
"min": 4,
"max": 31,
"step": 0.5,
"default": 20.0,
}
# Kelvin value for colorTemp

View File

@ -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.core import State
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
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
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(
hass, mock_block_device, device_reg, monkeypatch
):