Migrate number mode to StrEnum (#60614)

This commit is contained in:
Franck Nijhof 2021-11-30 12:54:06 +01:00 committed by GitHub
parent 1b8eba0afd
commit 7469f083fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 29 deletions

View file

@ -1,10 +1,7 @@
"""Demo platform that offers a fake Number entity.""" """Demo platform that offers a fake Number entity."""
from __future__ import annotations from __future__ import annotations
from typing import Literal from homeassistant.components.number import NumberEntity, NumberMode
from homeassistant.components.number import NumberEntity
from homeassistant.components.number.const import MODE_AUTO, MODE_BOX, MODE_SLIDER
from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.const import DEVICE_DEFAULT_NAME
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
@ -21,7 +18,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
42.0, 42.0,
"mdi:volume-high", "mdi:volume-high",
False, False,
mode=MODE_SLIDER, mode=NumberMode.SLIDER,
), ),
DemoNumber( DemoNumber(
"pwm1", "pwm1",
@ -32,7 +29,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
0.0, 0.0,
1.0, 1.0,
0.01, 0.01,
MODE_BOX, NumberMode.BOX,
), ),
DemoNumber( DemoNumber(
"large_range", "large_range",
@ -78,7 +75,7 @@ class DemoNumber(NumberEntity):
min_value: float | None = None, min_value: float | None = None,
max_value: float | None = None, max_value: float | None = None,
step: float | None = None, step: float | None = None,
mode: Literal["auto", "box", "slider"] = MODE_AUTO, mode: NumberMode = NumberMode.AUTO,
) -> None: ) -> None:
"""Initialize the Demo Number entity.""" """Initialize the Demo Number entity."""
self._attr_assumed_state = assumed self._attr_assumed_state = assumed

View file

@ -4,8 +4,7 @@ from __future__ import annotations
from typing import cast from typing import cast
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.number import NumberEntity from homeassistant.components.number import NumberEntity, NumberMode
from homeassistant.components.number.const import MODE_SLIDER
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -47,7 +46,7 @@ class FluxNumber(FluxEntity, CoordinatorEntity, NumberEntity):
_attr_min_value = 1 _attr_min_value = 1
_attr_max_value = 100 _attr_max_value = 100
_attr_step = 1 _attr_step = 1
_attr_mode = MODE_SLIDER _attr_mode = NumberMode.SLIDER
_attr_icon = "mdi:speedometer" _attr_icon = "mdi:speedometer"
def __init__( def __init__(

View file

@ -18,7 +18,7 @@ from homeassistant.components.binary_sensor import (
) )
from homeassistant.components.climate.const import HVAC_MODE_HEAT, HVAC_MODES from homeassistant.components.climate.const import HVAC_MODE_HEAT, HVAC_MODES
from homeassistant.components.cover import DEVICE_CLASSES as COVER_DEVICE_CLASSES from homeassistant.components.cover import DEVICE_CLASSES as COVER_DEVICE_CLASSES
from homeassistant.components.number.const import MODE_AUTO, MODE_BOX, MODE_SLIDER from homeassistant.components.number import NumberMode
from homeassistant.components.sensor import CONF_STATE_CLASS, STATE_CLASSES_SCHEMA from homeassistant.components.sensor import CONF_STATE_CLASS, STATE_CLASSES_SCHEMA
from homeassistant.const import ( from homeassistant.const import (
CONF_DEVICE_CLASS, CONF_DEVICE_CLASS,
@ -786,14 +786,14 @@ class NumberSchema(KNXPlatformSchema):
CONF_STEP = "step" CONF_STEP = "step"
DEFAULT_NAME = "KNX Number" DEFAULT_NAME = "KNX Number"
NUMBER_MODES: Final = [MODE_AUTO, MODE_BOX, MODE_SLIDER]
ENTITY_SCHEMA = vol.All( ENTITY_SCHEMA = vol.All(
vol.Schema( vol.Schema(
{ {
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_RESPOND_TO_READ, default=False): cv.boolean, vol.Optional(CONF_RESPOND_TO_READ, default=False): cv.boolean,
vol.Optional(CONF_MODE, default=MODE_AUTO): vol.In(NUMBER_MODES), vol.Optional(CONF_MODE, default=NumberMode.AUTO): vol.Coerce(
NumberMode
),
vol.Required(CONF_TYPE): numeric_type_validator, vol.Required(CONF_TYPE): numeric_type_validator,
vol.Required(KNX_ADDRESS): ga_list_validator, vol.Required(KNX_ADDRESS): ga_list_validator,
vol.Optional(CONF_STATE_ADDRESS): ga_list_validator, vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any, Literal, final from typing import Any, final
import voluptuous as vol import voluptuous as vol
@ -18,6 +18,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.util.enum import StrEnum
from .const import ( from .const import (
ATTR_MAX, ATTR_MAX,
@ -28,7 +29,6 @@ from .const import (
DEFAULT_MIN_VALUE, DEFAULT_MIN_VALUE,
DEFAULT_STEP, DEFAULT_STEP,
DOMAIN, DOMAIN,
MODE_AUTO,
SERVICE_SET_VALUE, SERVICE_SET_VALUE,
) )
@ -41,6 +41,14 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class NumberMode(StrEnum):
"""Modes for number entities."""
AUTO = "auto"
BOX = "box"
SLIDER = "slider"
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Number entities.""" """Set up Number entities."""
component = hass.data[DOMAIN] = EntityComponent( component = hass.data[DOMAIN] = EntityComponent(
@ -92,7 +100,7 @@ class NumberEntity(Entity):
_attr_min_value: float = DEFAULT_MIN_VALUE _attr_min_value: float = DEFAULT_MIN_VALUE
_attr_state: None = None _attr_state: None = None
_attr_step: float _attr_step: float
_attr_mode: Literal["auto", "slider", "box"] = MODE_AUTO _attr_mode: NumberMode = NumberMode.AUTO
_attr_value: float _attr_value: float
@property @property
@ -128,7 +136,7 @@ class NumberEntity(Entity):
return step return step
@property @property
def mode(self) -> Literal["auto", "slider", "box"]: def mode(self) -> NumberMode:
"""Return the mode of the entity.""" """Return the mode of the entity."""
return self._attr_mode return self._attr_mode

View file

@ -7,10 +7,6 @@ ATTR_MIN = "min"
ATTR_MAX = "max" ATTR_MAX = "max"
ATTR_STEP = "step" ATTR_STEP = "step"
MODE_AUTO: Final = "auto"
MODE_BOX: Final = "box"
MODE_SLIDER: Final = "slider"
DEFAULT_MIN_VALUE = 0.0 DEFAULT_MIN_VALUE = 0.0
DEFAULT_MAX_VALUE = 100.0 DEFAULT_MAX_VALUE = 100.0
DEFAULT_STEP = 1.0 DEFAULT_STEP = 1.0
@ -18,3 +14,8 @@ DEFAULT_STEP = 1.0
DOMAIN = "number" DOMAIN = "number"
SERVICE_SET_VALUE = "set_value" SERVICE_SET_VALUE = "set_value"
# MODE_* are deprecated as of 2021.12, use the NumberMode enum instead.
MODE_AUTO: Final = "auto"
MODE_BOX: Final = "box"
MODE_SLIDER: Final = "slider"

View file

@ -3,15 +3,13 @@
import pytest import pytest
import voluptuous as vol import voluptuous as vol
from homeassistant.components.number import NumberMode
from homeassistant.components.number.const import ( from homeassistant.components.number.const import (
ATTR_MAX, ATTR_MAX,
ATTR_MIN, ATTR_MIN,
ATTR_STEP, ATTR_STEP,
ATTR_VALUE, ATTR_VALUE,
DOMAIN, DOMAIN,
MODE_AUTO,
MODE_BOX,
MODE_SLIDER,
SERVICE_SET_VALUE, SERVICE_SET_VALUE,
) )
from homeassistant.const import ATTR_ENTITY_ID, ATTR_MODE from homeassistant.const import ATTR_ENTITY_ID, ATTR_MODE
@ -42,25 +40,25 @@ def test_default_setup_params(hass):
assert state.attributes.get(ATTR_MIN) == 0.0 assert state.attributes.get(ATTR_MIN) == 0.0
assert state.attributes.get(ATTR_MAX) == 100.0 assert state.attributes.get(ATTR_MAX) == 100.0
assert state.attributes.get(ATTR_STEP) == 1.0 assert state.attributes.get(ATTR_STEP) == 1.0
assert state.attributes.get(ATTR_MODE) == MODE_SLIDER assert state.attributes.get(ATTR_MODE) == NumberMode.SLIDER
state = hass.states.get(ENTITY_PWM) state = hass.states.get(ENTITY_PWM)
assert state.attributes.get(ATTR_MIN) == 0.0 assert state.attributes.get(ATTR_MIN) == 0.0
assert state.attributes.get(ATTR_MAX) == 1.0 assert state.attributes.get(ATTR_MAX) == 1.0
assert state.attributes.get(ATTR_STEP) == 0.01 assert state.attributes.get(ATTR_STEP) == 0.01
assert state.attributes.get(ATTR_MODE) == MODE_BOX assert state.attributes.get(ATTR_MODE) == NumberMode.BOX
state = hass.states.get(ENTITY_LARGE_RANGE) state = hass.states.get(ENTITY_LARGE_RANGE)
assert state.attributes.get(ATTR_MIN) == 1.0 assert state.attributes.get(ATTR_MIN) == 1.0
assert state.attributes.get(ATTR_MAX) == 1000.0 assert state.attributes.get(ATTR_MAX) == 1000.0
assert state.attributes.get(ATTR_STEP) == 1.0 assert state.attributes.get(ATTR_STEP) == 1.0
assert state.attributes.get(ATTR_MODE) == MODE_AUTO assert state.attributes.get(ATTR_MODE) == NumberMode.AUTO
state = hass.states.get(ENTITY_SMALL_RANGE) state = hass.states.get(ENTITY_SMALL_RANGE)
assert state.attributes.get(ATTR_MIN) == 1.0 assert state.attributes.get(ATTR_MIN) == 1.0
assert state.attributes.get(ATTR_MAX) == 255.0 assert state.attributes.get(ATTR_MAX) == 255.0
assert state.attributes.get(ATTR_STEP) == 1.0 assert state.attributes.get(ATTR_STEP) == 1.0
assert state.attributes.get(ATTR_MODE) == MODE_AUTO assert state.attributes.get(ATTR_MODE) == NumberMode.AUTO
async def test_set_value_bad_attr(hass): async def test_set_value_bad_attr(hass):