From 347ef9cb4c7ed6c540944dc5f2f34898239a713d Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 14 Jun 2021 18:05:01 +0200 Subject: [PATCH] Define NumberEntity entity attributes as class variables (#51842) --- homeassistant/components/demo/number.py | 87 ++++++--------------- homeassistant/components/number/__init__.py | 18 +++-- 2 files changed, 38 insertions(+), 67 deletions(-) diff --git a/homeassistant/components/demo/number.py b/homeassistant/components/demo/number.py index f3fd815f621..a6842d2ca43 100644 --- a/homeassistant/components/demo/number.py +++ b/homeassistant/components/demo/number.py @@ -1,4 +1,6 @@ """Demo platform that offers a fake Number entity.""" +from __future__ import annotations + import voluptuous as vol from homeassistant.components.number import NumberEntity @@ -40,26 +42,32 @@ async def async_setup_entry(hass, config_entry, async_add_entities): class DemoNumber(NumberEntity): """Representation of a demo Number entity.""" + _attr_should_poll = False + def __init__( self, - unique_id, - name, - state, - icon, - assumed, - min_value=None, - max_value=None, + unique_id: str, + name: str, + state: float, + icon: str, + assumed: bool, + min_value: float | None = None, + max_value: float | None = None, step=None, - ): + ) -> None: """Initialize the Demo Number entity.""" - self._unique_id = unique_id - self._name = name or DEVICE_DEFAULT_NAME - self._state = state - self._icon = icon - self._assumed = assumed - self._min_value = min_value - self._max_value = max_value - self._step = step + self._attr_assumed_state = assumed + self._attr_icon = icon + self._attr_name = name or DEVICE_DEFAULT_NAME + self._attr_unique_id = unique_id + self._attr_value = state + + if min_value is not None: + self._attr_min_value = min_value + if max_value is not None: + self._attr_max_value = max_value + if step is not None: + self._attr_step = step @property def device_info(self): @@ -72,51 +80,6 @@ class DemoNumber(NumberEntity): "name": self.name, } - @property - def unique_id(self): - """Return the unique id.""" - return self._unique_id - - @property - def should_poll(self): - """No polling needed for a demo Number entity.""" - return False - - @property - def name(self): - """Return the name of the device if any.""" - return self._name - - @property - def icon(self): - """Return the icon to use for device if any.""" - return self._icon - - @property - def assumed_state(self): - """Return if the state is based on assumptions.""" - return self._assumed - - @property - def value(self): - """Return the current value.""" - return self._state - - @property - def min_value(self): - """Return the minimum value.""" - return self._min_value or super().min_value - - @property - def max_value(self): - """Return the maximum value.""" - return self._max_value or super().max_value - - @property - def step(self): - """Return the value step.""" - return self._step or super().step - async def async_set_value(self, value): """Update the current value.""" num_value = float(value) @@ -126,5 +89,5 @@ class DemoNumber(NumberEntity): f"Invalid value for {self.entity_id}: {value} (range {self.min_value} - {self.max_value})" ) - self._state = num_value + self._attr_value = num_value self.async_write_ha_state() diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 046895ac29c..897186dce7b 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -1,10 +1,9 @@ """Component to allow numeric input for platforms.""" from __future__ import annotations -from abc import abstractmethod from datetime import timedelta import logging -from typing import Any +from typing import Any, final import voluptuous as vol @@ -68,6 +67,12 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: class NumberEntity(Entity): """Representation of a Number entity.""" + _attr_max_value: float = DEFAULT_MAX_VALUE + _attr_min_value: float = DEFAULT_MIN_VALUE + _attr_state: None = None + _attr_step: float + _attr_value: float + @property def capability_attributes(self) -> dict[str, Any]: """Return capability attributes.""" @@ -80,16 +85,18 @@ class NumberEntity(Entity): @property def min_value(self) -> float: """Return the minimum value.""" - return DEFAULT_MIN_VALUE + return self._attr_min_value @property def max_value(self) -> float: """Return the maximum value.""" - return DEFAULT_MAX_VALUE + return self._attr_max_value @property def step(self) -> float: """Return the increment/decrement step.""" + if hasattr(self, "_attr_step"): + return self._attr_step step = DEFAULT_STEP value_range = abs(self.max_value - self.min_value) if value_range != 0: @@ -98,14 +105,15 @@ class NumberEntity(Entity): return step @property + @final def state(self) -> float: """Return the entity state.""" return self.value @property - @abstractmethod def value(self) -> float: """Return the entity value to represent the entity state.""" + return self._attr_value def set_value(self, value: float) -> None: """Set new value."""