mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Fix inputs to correctly handle Fahrenheit in IronOS (#135421)
* Fix inputs to correctly handle Fahrenheit in IronOS * some refactoring * add boost switch entity * Revert switch entity * refactor * remove commented code * some changes
This commit is contained in:
parent
c17ee0d123
commit
c7603b39ec
@ -10,4 +10,8 @@ OHM = "Ω"
|
|||||||
DISCOVERY_SVC_UUID = "9eae1000-9d0d-48c5-aa55-33e27f9bc533"
|
DISCOVERY_SVC_UUID = "9eae1000-9d0d-48c5-aa55-33e27f9bc533"
|
||||||
|
|
||||||
MAX_TEMP: int = 450
|
MAX_TEMP: int = 450
|
||||||
|
MAX_TEMP_F: int = 850
|
||||||
MIN_TEMP: int = 10
|
MIN_TEMP: int = 10
|
||||||
|
MIN_TEMP_F: int = 50
|
||||||
|
MIN_BOOST_TEMP: int = 250
|
||||||
|
MIN_BOOST_TEMP_F: int = 480
|
||||||
|
@ -168,7 +168,9 @@ class IronOSSettingsCoordinator(IronOSBaseCoordinator[SettingsDataResponse]):
|
|||||||
|
|
||||||
if self.device.is_connected and characteristics:
|
if self.device.is_connected and characteristics:
|
||||||
try:
|
try:
|
||||||
return await self.device.get_settings(list(characteristics))
|
return await self.device.get_settings(
|
||||||
|
list(characteristics | {CharSetting.TEMP_UNIT})
|
||||||
|
)
|
||||||
except CommunicationError as e:
|
except CommunicationError as e:
|
||||||
_LOGGER.debug("Failed to fetch settings", exc_info=e)
|
_LOGGER.debug("Failed to fetch settings", exc_info=e)
|
||||||
|
|
||||||
|
@ -6,10 +6,9 @@ from collections.abc import Callable
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
|
|
||||||
from pynecil import CharSetting, LiveDataResponse, SettingsDataResponse
|
from pynecil import CharSetting, LiveDataResponse, SettingsDataResponse, TempUnit
|
||||||
|
|
||||||
from homeassistant.components.number import (
|
from homeassistant.components.number import (
|
||||||
DEFAULT_MAX_VALUE,
|
|
||||||
NumberDeviceClass,
|
NumberDeviceClass,
|
||||||
NumberEntity,
|
NumberEntity,
|
||||||
NumberEntityDescription,
|
NumberEntityDescription,
|
||||||
@ -24,9 +23,17 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||||
|
|
||||||
from . import IronOSConfigEntry
|
from . import IronOSConfigEntry
|
||||||
from .const import MAX_TEMP, MIN_TEMP
|
from .const import (
|
||||||
|
MAX_TEMP,
|
||||||
|
MAX_TEMP_F,
|
||||||
|
MIN_BOOST_TEMP,
|
||||||
|
MIN_BOOST_TEMP_F,
|
||||||
|
MIN_TEMP,
|
||||||
|
MIN_TEMP_F,
|
||||||
|
)
|
||||||
from .coordinator import IronOSCoordinators
|
from .coordinator import IronOSCoordinators
|
||||||
from .entity import IronOSBaseEntity
|
from .entity import IronOSBaseEntity
|
||||||
|
|
||||||
@ -38,9 +45,10 @@ class IronOSNumberEntityDescription(NumberEntityDescription):
|
|||||||
"""Describes IronOS number entity."""
|
"""Describes IronOS number entity."""
|
||||||
|
|
||||||
value_fn: Callable[[LiveDataResponse, SettingsDataResponse], float | int | None]
|
value_fn: Callable[[LiveDataResponse, SettingsDataResponse], float | int | None]
|
||||||
max_value_fn: Callable[[LiveDataResponse], float | int] | None = None
|
|
||||||
characteristic: CharSetting
|
characteristic: CharSetting
|
||||||
raw_value_fn: Callable[[float], float | int] | None = None
|
raw_value_fn: Callable[[float], float | int] | None = None
|
||||||
|
native_max_value_f: float | None = None
|
||||||
|
native_min_value_f: float | None = None
|
||||||
|
|
||||||
|
|
||||||
class PinecilNumber(StrEnum):
|
class PinecilNumber(StrEnum):
|
||||||
@ -74,44 +82,6 @@ def multiply(value: float | None, multiplier: float) -> float | None:
|
|||||||
|
|
||||||
|
|
||||||
PINECIL_NUMBER_DESCRIPTIONS: tuple[IronOSNumberEntityDescription, ...] = (
|
PINECIL_NUMBER_DESCRIPTIONS: tuple[IronOSNumberEntityDescription, ...] = (
|
||||||
IronOSNumberEntityDescription(
|
|
||||||
key=PinecilNumber.SETPOINT_TEMP,
|
|
||||||
translation_key=PinecilNumber.SETPOINT_TEMP,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
device_class=NumberDeviceClass.TEMPERATURE,
|
|
||||||
value_fn=lambda data, _: data.setpoint_temp,
|
|
||||||
characteristic=CharSetting.SETPOINT_TEMP,
|
|
||||||
mode=NumberMode.BOX,
|
|
||||||
native_min_value=MIN_TEMP,
|
|
||||||
native_step=5,
|
|
||||||
max_value_fn=lambda data: min(data.max_tip_temp_ability or MAX_TEMP, MAX_TEMP),
|
|
||||||
),
|
|
||||||
IronOSNumberEntityDescription(
|
|
||||||
key=PinecilNumber.SLEEP_TEMP,
|
|
||||||
translation_key=PinecilNumber.SLEEP_TEMP,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
device_class=NumberDeviceClass.TEMPERATURE,
|
|
||||||
value_fn=lambda _, settings: settings.get("sleep_temp"),
|
|
||||||
characteristic=CharSetting.SLEEP_TEMP,
|
|
||||||
mode=NumberMode.BOX,
|
|
||||||
native_min_value=MIN_TEMP,
|
|
||||||
native_max_value=MAX_TEMP,
|
|
||||||
native_step=10,
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
),
|
|
||||||
IronOSNumberEntityDescription(
|
|
||||||
key=PinecilNumber.BOOST_TEMP,
|
|
||||||
translation_key=PinecilNumber.BOOST_TEMP,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
device_class=NumberDeviceClass.TEMPERATURE,
|
|
||||||
value_fn=lambda _, settings: settings.get("boost_temp"),
|
|
||||||
characteristic=CharSetting.BOOST_TEMP,
|
|
||||||
mode=NumberMode.BOX,
|
|
||||||
native_min_value=0,
|
|
||||||
native_max_value=MAX_TEMP,
|
|
||||||
native_step=10,
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
),
|
|
||||||
IronOSNumberEntityDescription(
|
IronOSNumberEntityDescription(
|
||||||
key=PinecilNumber.QC_MAX_VOLTAGE,
|
key=PinecilNumber.QC_MAX_VOLTAGE,
|
||||||
translation_key=PinecilNumber.QC_MAX_VOLTAGE,
|
translation_key=PinecilNumber.QC_MAX_VOLTAGE,
|
||||||
@ -296,32 +266,6 @@ PINECIL_NUMBER_DESCRIPTIONS: tuple[IronOSNumberEntityDescription, ...] = (
|
|||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
IronOSNumberEntityDescription(
|
|
||||||
key=PinecilNumber.TEMP_INCREMENT_SHORT,
|
|
||||||
translation_key=PinecilNumber.TEMP_INCREMENT_SHORT,
|
|
||||||
value_fn=(lambda _, settings: settings.get("temp_increment_short")),
|
|
||||||
characteristic=CharSetting.TEMP_INCREMENT_SHORT,
|
|
||||||
raw_value_fn=lambda value: value,
|
|
||||||
mode=NumberMode.BOX,
|
|
||||||
native_min_value=1,
|
|
||||||
native_max_value=50,
|
|
||||||
native_step=1,
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
),
|
|
||||||
IronOSNumberEntityDescription(
|
|
||||||
key=PinecilNumber.TEMP_INCREMENT_LONG,
|
|
||||||
translation_key=PinecilNumber.TEMP_INCREMENT_LONG,
|
|
||||||
value_fn=(lambda _, settings: settings.get("temp_increment_long")),
|
|
||||||
characteristic=CharSetting.TEMP_INCREMENT_LONG,
|
|
||||||
raw_value_fn=lambda value: value,
|
|
||||||
mode=NumberMode.BOX,
|
|
||||||
native_min_value=5,
|
|
||||||
native_max_value=90,
|
|
||||||
native_step=5,
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
PINECIL_NUMBER_DESCRIPTIONS_V223: tuple[IronOSNumberEntityDescription, ...] = (
|
PINECIL_NUMBER_DESCRIPTIONS_V223: tuple[IronOSNumberEntityDescription, ...] = (
|
||||||
@ -341,6 +285,82 @@ PINECIL_NUMBER_DESCRIPTIONS_V223: tuple[IronOSNumberEntityDescription, ...] = (
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
"""
|
||||||
|
The `device_class` attribute was removed from the `setpoint_temperature`, `sleep_temperature`, and `boost_temp` entities.
|
||||||
|
These entities represent user-defined input values, not measured temperatures, and their
|
||||||
|
interpretation depends on the device's current unit configuration. Applying a device_class
|
||||||
|
results in automatic unit conversions, which introduce rounding errors due to the use of integers.
|
||||||
|
This can prevent the correct value from being set, as the input is modified during synchronization with the device.
|
||||||
|
"""
|
||||||
|
PINECIL_TEMP_NUMBER_DESCRIPTIONS: tuple[IronOSNumberEntityDescription, ...] = (
|
||||||
|
IronOSNumberEntityDescription(
|
||||||
|
key=PinecilNumber.SLEEP_TEMP,
|
||||||
|
translation_key=PinecilNumber.SLEEP_TEMP,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
value_fn=lambda _, settings: settings.get("sleep_temp"),
|
||||||
|
characteristic=CharSetting.SLEEP_TEMP,
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
native_min_value=MIN_TEMP,
|
||||||
|
native_max_value=MAX_TEMP,
|
||||||
|
native_min_value_f=MIN_TEMP_F,
|
||||||
|
native_max_value_f=MAX_TEMP_F,
|
||||||
|
native_step=10,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
),
|
||||||
|
IronOSNumberEntityDescription(
|
||||||
|
key=PinecilNumber.BOOST_TEMP,
|
||||||
|
translation_key=PinecilNumber.BOOST_TEMP,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
value_fn=lambda _, settings: settings.get("boost_temp"),
|
||||||
|
characteristic=CharSetting.BOOST_TEMP,
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
native_min_value=MIN_BOOST_TEMP,
|
||||||
|
native_min_value_f=MIN_BOOST_TEMP_F,
|
||||||
|
native_max_value=MAX_TEMP,
|
||||||
|
native_max_value_f=MAX_TEMP_F,
|
||||||
|
native_step=10,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
),
|
||||||
|
IronOSNumberEntityDescription(
|
||||||
|
key=PinecilNumber.TEMP_INCREMENT_SHORT,
|
||||||
|
translation_key=PinecilNumber.TEMP_INCREMENT_SHORT,
|
||||||
|
value_fn=(lambda _, settings: settings.get("temp_increment_short")),
|
||||||
|
characteristic=CharSetting.TEMP_INCREMENT_SHORT,
|
||||||
|
raw_value_fn=lambda value: value,
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
native_min_value=1,
|
||||||
|
native_max_value=50,
|
||||||
|
native_step=1,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
),
|
||||||
|
IronOSNumberEntityDescription(
|
||||||
|
key=PinecilNumber.TEMP_INCREMENT_LONG,
|
||||||
|
translation_key=PinecilNumber.TEMP_INCREMENT_LONG,
|
||||||
|
value_fn=(lambda _, settings: settings.get("temp_increment_long")),
|
||||||
|
characteristic=CharSetting.TEMP_INCREMENT_LONG,
|
||||||
|
raw_value_fn=lambda value: value,
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
native_min_value=5,
|
||||||
|
native_max_value=90,
|
||||||
|
native_step=5,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
PINECIL_SETPOINT_NUMBER_DESCRIPTION = IronOSNumberEntityDescription(
|
||||||
|
key=PinecilNumber.SETPOINT_TEMP,
|
||||||
|
translation_key=PinecilNumber.SETPOINT_TEMP,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
value_fn=lambda data, _: data.setpoint_temp,
|
||||||
|
characteristic=CharSetting.SETPOINT_TEMP,
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
native_min_value=MIN_TEMP,
|
||||||
|
native_max_value=MAX_TEMP,
|
||||||
|
native_min_value_f=MIN_TEMP_F,
|
||||||
|
native_max_value_f=MAX_TEMP_F,
|
||||||
|
native_step=5,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -354,9 +374,18 @@ async def async_setup_entry(
|
|||||||
if coordinators.live_data.v223_features:
|
if coordinators.live_data.v223_features:
|
||||||
descriptions += PINECIL_NUMBER_DESCRIPTIONS_V223
|
descriptions += PINECIL_NUMBER_DESCRIPTIONS_V223
|
||||||
|
|
||||||
async_add_entities(
|
entities = [
|
||||||
IronOSNumberEntity(coordinators, description) for description in descriptions
|
IronOSNumberEntity(coordinators, description) for description in descriptions
|
||||||
|
]
|
||||||
|
|
||||||
|
entities.extend(
|
||||||
|
IronOSTemperatureNumberEntity(coordinators, description)
|
||||||
|
for description in PINECIL_TEMP_NUMBER_DESCRIPTIONS
|
||||||
)
|
)
|
||||||
|
entities.append(
|
||||||
|
IronOSSetpointNumberEntity(coordinators, PINECIL_SETPOINT_NUMBER_DESCRIPTION)
|
||||||
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class IronOSNumberEntity(IronOSBaseEntity, NumberEntity):
|
class IronOSNumberEntity(IronOSBaseEntity, NumberEntity):
|
||||||
@ -388,15 +417,6 @@ class IronOSNumberEntity(IronOSBaseEntity, NumberEntity):
|
|||||||
self.coordinator.data, self.settings.data
|
self.coordinator.data, self.settings.data
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def native_max_value(self) -> float:
|
|
||||||
"""Return sensor state."""
|
|
||||||
|
|
||||||
if self.entity_description.max_value_fn is not None:
|
|
||||||
return self.entity_description.max_value_fn(self.coordinator.data)
|
|
||||||
|
|
||||||
return self.entity_description.native_max_value or DEFAULT_MAX_VALUE
|
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
|
|
||||||
@ -407,3 +427,60 @@ class IronOSNumberEntity(IronOSBaseEntity, NumberEntity):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
await self.settings.async_request_refresh()
|
await self.settings.async_request_refresh()
|
||||||
|
|
||||||
|
|
||||||
|
class IronOSTemperatureNumberEntity(IronOSNumberEntity):
|
||||||
|
"""Implementation of a IronOS temperature number entity."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
|
"""Return the unit of measurement of the sensor, if any."""
|
||||||
|
|
||||||
|
return (
|
||||||
|
UnitOfTemperature.FAHRENHEIT
|
||||||
|
if self.settings.data.get("temp_unit") is TempUnit.FAHRENHEIT
|
||||||
|
else UnitOfTemperature.CELSIUS
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_min_value(self) -> float:
|
||||||
|
"""Return the minimum value."""
|
||||||
|
|
||||||
|
return (
|
||||||
|
self.entity_description.native_min_value_f
|
||||||
|
if self.entity_description.native_min_value_f
|
||||||
|
and self.native_unit_of_measurement is UnitOfTemperature.FAHRENHEIT
|
||||||
|
else super().native_min_value
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_max_value(self) -> float:
|
||||||
|
"""Return the maximum value."""
|
||||||
|
|
||||||
|
return (
|
||||||
|
self.entity_description.native_max_value_f
|
||||||
|
if self.entity_description.native_max_value_f
|
||||||
|
and self.native_unit_of_measurement is UnitOfTemperature.FAHRENHEIT
|
||||||
|
else super().native_max_value
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IronOSSetpointNumberEntity(IronOSTemperatureNumberEntity):
|
||||||
|
"""IronOS setpoint temperature entity."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_max_value(self) -> float:
|
||||||
|
"""Return the maximum value."""
|
||||||
|
|
||||||
|
return (
|
||||||
|
min(
|
||||||
|
TemperatureConverter.convert(
|
||||||
|
float(max_tip_c),
|
||||||
|
UnitOfTemperature.CELSIUS,
|
||||||
|
self.native_unit_of_measurement,
|
||||||
|
),
|
||||||
|
super().native_max_value,
|
||||||
|
)
|
||||||
|
if (max_tip_c := self.coordinator.data.max_tip_temp_ability) is not None
|
||||||
|
else super().native_max_value
|
||||||
|
)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'max': 450,
|
'max': 450,
|
||||||
'min': 0,
|
'min': 250,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 10,
|
'step': 10,
|
||||||
}),
|
}),
|
||||||
@ -27,7 +27,7 @@
|
|||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
}),
|
}),
|
||||||
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
|
'original_device_class': None,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Boost temperature',
|
'original_name': 'Boost temperature',
|
||||||
'platform': 'iron_os',
|
'platform': 'iron_os',
|
||||||
@ -42,10 +42,9 @@
|
|||||||
# name: test_state[number.pinecil_boost_temperature-state]
|
# name: test_state[number.pinecil_boost_temperature-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'temperature',
|
|
||||||
'friendly_name': 'Pinecil Boost temperature',
|
'friendly_name': 'Pinecil Boost temperature',
|
||||||
'max': 450,
|
'max': 450,
|
||||||
'min': 0,
|
'min': 250,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 10,
|
'step': 10,
|
||||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||||
@ -839,7 +838,7 @@
|
|||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
}),
|
}),
|
||||||
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
|
'original_device_class': None,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Setpoint temperature',
|
'original_name': 'Setpoint temperature',
|
||||||
'platform': 'iron_os',
|
'platform': 'iron_os',
|
||||||
@ -854,7 +853,6 @@
|
|||||||
# name: test_state[number.pinecil_setpoint_temperature-state]
|
# name: test_state[number.pinecil_setpoint_temperature-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'temperature',
|
|
||||||
'friendly_name': 'Pinecil Setpoint temperature',
|
'friendly_name': 'Pinecil Setpoint temperature',
|
||||||
'max': 450,
|
'max': 450,
|
||||||
'min': 10,
|
'min': 10,
|
||||||
@ -1015,7 +1013,7 @@
|
|||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
}),
|
}),
|
||||||
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
|
'original_device_class': None,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Sleep temperature',
|
'original_name': 'Sleep temperature',
|
||||||
'platform': 'iron_os',
|
'platform': 'iron_os',
|
||||||
@ -1030,7 +1028,6 @@
|
|||||||
# name: test_state[number.pinecil_sleep_temperature-state]
|
# name: test_state[number.pinecil_sleep_temperature-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'temperature',
|
|
||||||
'friendly_name': 'Pinecil Sleep temperature',
|
'friendly_name': 'Pinecil Sleep temperature',
|
||||||
'max': 450,
|
'max': 450,
|
||||||
'min': 10,
|
'min': 10,
|
||||||
|
@ -5,10 +5,15 @@ from datetime import timedelta
|
|||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from pynecil import CharSetting, CommunicationError
|
from pynecil import CharSetting, CommunicationError, TempUnit
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.components.iron_os.const import (
|
||||||
|
MAX_TEMP_F,
|
||||||
|
MIN_BOOST_TEMP_F,
|
||||||
|
MIN_TEMP_F,
|
||||||
|
)
|
||||||
from homeassistant.components.number import (
|
from homeassistant.components.number import (
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
DOMAIN as NUMBER_DOMAIN,
|
DOMAIN as NUMBER_DOMAIN,
|
||||||
@ -56,6 +61,47 @@ async def test_state(
|
|||||||
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("entity_id", "min_value", "max_value"),
|
||||||
|
[
|
||||||
|
("number.pinecil_setpoint_temperature", MIN_TEMP_F, MAX_TEMP_F),
|
||||||
|
("number.pinecil_boost_temperature", MIN_BOOST_TEMP_F, MAX_TEMP_F),
|
||||||
|
("number.pinecil_long_press_temperature_step", 5, 90),
|
||||||
|
("number.pinecil_short_press_temperature_step", 1, 50),
|
||||||
|
("number.pinecil_sleep_temperature", MIN_TEMP_F, MAX_TEMP_F),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "ble_device")
|
||||||
|
async def test_state_fahrenheit(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
mock_pynecil: AsyncMock,
|
||||||
|
entity_id: str,
|
||||||
|
min_value: int,
|
||||||
|
max_value: int,
|
||||||
|
) -> None:
|
||||||
|
"""Test with temp unit set to fahrenheit."""
|
||||||
|
|
||||||
|
mock_pynecil.get_settings.return_value["temp_unit"] = TempUnit.FAHRENHEIT
|
||||||
|
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
freezer.tick(timedelta(seconds=3))
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state is not None
|
||||||
|
|
||||||
|
assert state.attributes["min"] == min_value
|
||||||
|
assert state.attributes["max"] == max_value
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("entity_id", "characteristic", "value", "expected_value"),
|
("entity_id", "characteristic", "value", "expected_value"),
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user