Move constants in Threshold (#125683)

This commit is contained in:
Adam Goode 2024-09-10 11:51:23 -04:00 committed by GitHub
parent dd08a6505e
commit 72d546d6c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 152 additions and 120 deletions

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from collections.abc import Callable, Mapping
import logging
from typing import Any
from typing import Any, Final
import voluptuous as vol
@ -37,28 +37,29 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import CONF_HYSTERESIS, CONF_LOWER, CONF_UPPER
from .const import (
ATTR_HYSTERESIS,
ATTR_LOWER,
ATTR_POSITION,
ATTR_SENSOR_VALUE,
ATTR_TYPE,
ATTR_UPPER,
CONF_HYSTERESIS,
CONF_LOWER,
CONF_UPPER,
DEFAULT_HYSTERESIS,
POSITION_ABOVE,
POSITION_BELOW,
POSITION_IN_RANGE,
POSITION_UNKNOWN,
TYPE_LOWER,
TYPE_RANGE,
TYPE_UPPER,
)
_LOGGER = logging.getLogger(__name__)
ATTR_HYSTERESIS = "hysteresis"
ATTR_LOWER = "lower"
ATTR_POSITION = "position"
ATTR_SENSOR_VALUE = "sensor_value"
ATTR_TYPE = "type"
ATTR_UPPER = "upper"
DEFAULT_NAME = "Threshold"
DEFAULT_HYSTERESIS = 0.0
POSITION_ABOVE = "above"
POSITION_BELOW = "below"
POSITION_IN_RANGE = "in_range"
POSITION_UNKNOWN = "unknown"
TYPE_LOWER = "lower"
TYPE_RANGE = "range"
TYPE_UPPER = "upper"
DEFAULT_NAME: Final = "Threshold"
PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
{

View File

@ -1,9 +1,27 @@
"""Constants for the Threshold integration."""
DOMAIN = "threshold"
from typing import Final
CONF_HYSTERESIS = "hysteresis"
CONF_LOWER = "lower"
CONF_UPPER = "upper"
DOMAIN: Final = "threshold"
DEFAULT_HYSTERESIS = 0.0
DEFAULT_HYSTERESIS: Final = 0.0
ATTR_HYSTERESIS: Final = "hysteresis"
ATTR_LOWER: Final = "lower"
ATTR_POSITION: Final = "position"
ATTR_SENSOR_VALUE: Final = "sensor_value"
ATTR_TYPE: Final = "type"
ATTR_UPPER: Final = "upper"
CONF_HYSTERESIS: Final = "hysteresis"
CONF_LOWER: Final = "lower"
CONF_UPPER: Final = "upper"
POSITION_ABOVE: Final = "above"
POSITION_BELOW: Final = "below"
POSITION_IN_RANGE: Final = "in_range"
POSITION_UNKNOWN: Final = "unknown"
TYPE_LOWER: Final = "lower"
TYPE_RANGE: Final = "range"
TYPE_UPPER: Final = "upper"

View File

@ -3,10 +3,23 @@
import pytest
from homeassistant.components.threshold.const import (
ATTR_HYSTERESIS,
ATTR_LOWER,
ATTR_POSITION,
ATTR_SENSOR_VALUE,
ATTR_TYPE,
ATTR_UPPER,
CONF_HYSTERESIS,
CONF_LOWER,
CONF_UPPER,
DOMAIN,
POSITION_ABOVE,
POSITION_BELOW,
POSITION_IN_RANGE,
POSITION_UNKNOWN,
TYPE_LOWER,
TYPE_RANGE,
TYPE_UPPER,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -31,13 +44,13 @@ from tests.common import MockConfigEntry
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 15, "below", STATE_OFF), # at threshold
(15, 16, "above", STATE_ON),
(16, 14, "below", STATE_OFF),
(14, 15, "below", STATE_OFF),
(15, "cat", "unknown", STATE_UNKNOWN),
("cat", 15, "below", STATE_OFF),
(15, None, "unknown", STATE_UNKNOWN),
(None, 15, POSITION_BELOW, STATE_OFF), # at threshold
(15, 16, POSITION_ABOVE, STATE_ON),
(16, 14, POSITION_BELOW, STATE_OFF),
(14, 15, POSITION_BELOW, STATE_OFF),
(15, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 15, POSITION_BELOW, STATE_OFF),
(15, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_upper(
@ -63,29 +76,29 @@ async def test_sensor_upper(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.attributes["hysteresis"] == 0.0
assert state.attributes["type"] == "upper"
assert state.attributes[ATTR_HYSTERESIS] == 0.0
assert state.attributes[ATTR_TYPE] == TYPE_UPPER
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 15, "above", STATE_OFF), # at threshold
(15, 16, "above", STATE_OFF),
(16, 14, "below", STATE_ON),
(14, 15, "below", STATE_ON),
(15, "cat", "unknown", STATE_UNKNOWN),
("cat", 15, "above", STATE_OFF),
(15, None, "unknown", STATE_UNKNOWN),
(None, 15, POSITION_ABOVE, STATE_OFF), # at threshold
(15, 16, POSITION_ABOVE, STATE_OFF),
(16, 14, POSITION_BELOW, STATE_ON),
(14, 15, POSITION_BELOW, STATE_ON),
(15, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 15, POSITION_ABOVE, STATE_OFF),
(15, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_lower(
@ -111,32 +124,32 @@ async def test_sensor_lower(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.attributes["hysteresis"] == 0.0
assert state.attributes["type"] == "lower"
assert state.attributes[ATTR_HYSTERESIS] == 0.0
assert state.attributes[ATTR_TYPE] == TYPE_LOWER
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 17.5, "below", STATE_OFF), # threshold + hysteresis
(17.5, 12.5, "below", STATE_OFF), # threshold - hysteresis
(12.5, 20, "above", STATE_ON),
(20, 13, "above", STATE_ON),
(13, 12, "below", STATE_OFF),
(12, 17, "below", STATE_OFF),
(17, 18, "above", STATE_ON),
(18, "cat", "unknown", STATE_UNKNOWN),
("cat", 18, "above", STATE_ON),
(18, None, "unknown", STATE_UNKNOWN),
(None, 17.5, POSITION_BELOW, STATE_OFF), # threshold + hysteresis
(17.5, 12.5, POSITION_BELOW, STATE_OFF), # threshold - hysteresis
(12.5, 20, POSITION_ABOVE, STATE_ON),
(20, 13, POSITION_ABOVE, STATE_ON),
(13, 12, POSITION_BELOW, STATE_OFF),
(12, 17, POSITION_BELOW, STATE_OFF),
(17, 18, POSITION_ABOVE, STATE_ON),
(18, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 18, POSITION_ABOVE, STATE_ON),
(18, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_upper_hysteresis(
@ -163,32 +176,32 @@ async def test_sensor_upper_hysteresis(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.attributes["hysteresis"] == 2.5
assert state.attributes["type"] == "upper"
assert state.attributes[ATTR_HYSTERESIS] == 2.5
assert state.attributes[ATTR_TYPE] == TYPE_UPPER
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 17.5, "above", STATE_OFF), # threshold + hysteresis
(17.5, 12.5, "above", STATE_OFF), # threshold - hysteresis
(12.5, 20, "above", STATE_OFF),
(20, 13, "above", STATE_OFF),
(13, 12, "below", STATE_ON),
(12, 17, "below", STATE_ON),
(17, 18, "above", STATE_OFF),
(18, "cat", "unknown", STATE_UNKNOWN),
("cat", 18, "above", STATE_OFF),
(18, None, "unknown", STATE_UNKNOWN),
(None, 17.5, POSITION_ABOVE, STATE_OFF), # threshold + hysteresis
(17.5, 12.5, POSITION_ABOVE, STATE_OFF), # threshold - hysteresis
(12.5, 20, POSITION_ABOVE, STATE_OFF),
(20, 13, POSITION_ABOVE, STATE_OFF),
(13, 12, POSITION_BELOW, STATE_ON),
(12, 17, POSITION_BELOW, STATE_ON),
(17, 18, POSITION_ABOVE, STATE_OFF),
(18, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 18, POSITION_ABOVE, STATE_OFF),
(18, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_lower_hysteresis(
@ -215,30 +228,30 @@ async def test_sensor_lower_hysteresis(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.attributes["hysteresis"] == 2.5
assert state.attributes["type"] == "lower"
assert state.attributes[ATTR_HYSTERESIS] == 2.5
assert state.attributes[ATTR_TYPE] == TYPE_LOWER
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 10, "in_range", STATE_ON), # at lower threshold
(10, 20, "in_range", STATE_ON), # at upper threshold
(20, 16, "in_range", STATE_ON),
(16, 9, "below", STATE_OFF),
(9, 21, "above", STATE_OFF),
(21, "cat", "unknown", STATE_UNKNOWN),
("cat", 21, "above", STATE_OFF),
(21, None, "unknown", STATE_UNKNOWN),
(None, 10, POSITION_IN_RANGE, STATE_ON), # at lower threshold
(10, 20, POSITION_IN_RANGE, STATE_ON), # at upper threshold
(20, 16, POSITION_IN_RANGE, STATE_ON),
(16, 9, POSITION_BELOW, STATE_OFF),
(9, 21, POSITION_ABOVE, STATE_OFF),
(21, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 21, POSITION_ABOVE, STATE_OFF),
(21, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_in_range_no_hysteresis(
@ -265,40 +278,40 @@ async def test_sensor_in_range_no_hysteresis(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.attributes["hysteresis"] == 0.0
assert state.attributes["type"] == "range"
assert state.attributes[ATTR_HYSTERESIS] == 0.0
assert state.attributes[ATTR_TYPE] == TYPE_RANGE
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@pytest.mark.parametrize(
("from_val", "to_val", "expected_position", "expected_state"),
[
(None, 12, "in_range", STATE_ON), # lower threshold + hysteresis
(12, 22, "in_range", STATE_ON), # upper threshold + hysteresis
(22, 18, "in_range", STATE_ON), # upper threshold - hysteresis
(18, 16, "in_range", STATE_ON),
(16, 8, "in_range", STATE_ON),
(8, 7, "below", STATE_OFF),
(7, 12, "below", STATE_OFF),
(12, 13, "in_range", STATE_ON),
(13, 22, "in_range", STATE_ON),
(22, 23, "above", STATE_OFF),
(23, 18, "above", STATE_OFF),
(18, 17, "in_range", STATE_ON),
(17, "cat", "unknown", STATE_UNKNOWN),
("cat", 17, "in_range", STATE_ON),
(17, None, "unknown", STATE_UNKNOWN),
(None, 12, POSITION_IN_RANGE, STATE_ON), # lower threshold + hysteresis
(12, 22, POSITION_IN_RANGE, STATE_ON), # upper threshold + hysteresis
(22, 18, POSITION_IN_RANGE, STATE_ON), # upper threshold - hysteresis
(18, 16, POSITION_IN_RANGE, STATE_ON),
(16, 8, POSITION_IN_RANGE, STATE_ON),
(8, 7, POSITION_BELOW, STATE_OFF),
(7, 12, POSITION_BELOW, STATE_OFF),
(12, 13, POSITION_IN_RANGE, STATE_ON),
(13, 22, POSITION_IN_RANGE, STATE_ON),
(22, 23, POSITION_ABOVE, STATE_OFF),
(23, 18, POSITION_ABOVE, STATE_OFF),
(18, 17, POSITION_IN_RANGE, STATE_ON),
(17, "cat", POSITION_UNKNOWN, STATE_UNKNOWN),
("cat", 17, POSITION_IN_RANGE, STATE_ON),
(17, None, POSITION_UNKNOWN, STATE_UNKNOWN),
],
)
async def test_sensor_in_range_with_hysteresis(
@ -326,19 +339,19 @@ async def test_sensor_in_range_with_hysteresis(
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.attributes["hysteresis"] == 2.0
assert state.attributes["type"] == "range"
assert state.attributes[ATTR_HYSTERESIS] == 2.0
assert state.attributes[ATTR_TYPE] == TYPE_RANGE
hass.states.async_set("sensor.test_monitored", to_val)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == expected_position
assert state.attributes[ATTR_POSITION] == expected_position
assert state.state == expected_state
@ -368,28 +381,28 @@ async def test_sensor_in_range_unknown_state(
state = hass.states.get("binary_sensor.threshold")
assert state.attributes[ATTR_ENTITY_ID] == "sensor.test_monitored"
assert state.attributes["sensor_value"] == 16
assert state.attributes["position"] == "in_range"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_SENSOR_VALUE] == 16
assert state.attributes[ATTR_POSITION] == POSITION_IN_RANGE
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.attributes["hysteresis"] == 0.0
assert state.attributes["type"] == "range"
assert state.attributes[ATTR_HYSTERESIS] == 0.0
assert state.attributes[ATTR_TYPE] == TYPE_RANGE
assert state.state == STATE_ON
hass.states.async_set("sensor.test_monitored", STATE_UNKNOWN)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == "unknown"
assert state.attributes[ATTR_POSITION] == POSITION_UNKNOWN
assert state.state == STATE_UNKNOWN
hass.states.async_set("sensor.test_monitored", STATE_UNAVAILABLE)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["position"] == "unknown"
assert state.attributes[ATTR_POSITION] == POSITION_UNKNOWN
assert state.state == STATE_UNKNOWN
assert "State is not numerical" not in caplog.text
@ -411,8 +424,8 @@ async def test_sensor_lower_zero_threshold(hass: HomeAssistant) -> None:
hass.states.async_set("sensor.test_monitored", 16)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["type"] == "lower"
assert state.attributes["lower"] == float(
assert state.attributes[ATTR_TYPE] == TYPE_LOWER
assert state.attributes[ATTR_LOWER] == float(
config[Platform.BINARY_SENSOR][CONF_LOWER]
)
assert state.state == STATE_OFF
@ -439,8 +452,8 @@ async def test_sensor_upper_zero_threshold(hass: HomeAssistant) -> None:
hass.states.async_set("sensor.test_monitored", -10)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.threshold")
assert state.attributes["type"] == "upper"
assert state.attributes["upper"] == float(
assert state.attributes[ATTR_TYPE] == TYPE_UPPER
assert state.attributes[ATTR_UPPER] == float(
config[Platform.BINARY_SENSOR][CONF_UPPER]
)
assert state.state == STATE_OFF