From 72d546d6c23a8bca9aec91085220abca3a2b7cb7 Mon Sep 17 00:00:00 2001 From: Adam Goode Date: Tue, 10 Sep 2024 11:51:23 -0400 Subject: [PATCH] Move constants in Threshold (#125683) --- .../components/threshold/binary_sensor.py | 41 ++-- homeassistant/components/threshold/const.py | 28 ++- .../threshold/test_binary_sensor.py | 203 ++++++++++-------- 3 files changed, 152 insertions(+), 120 deletions(-) diff --git a/homeassistant/components/threshold/binary_sensor.py b/homeassistant/components/threshold/binary_sensor.py index a791658f049..9440e251586 100644 --- a/homeassistant/components/threshold/binary_sensor.py +++ b/homeassistant/components/threshold/binary_sensor.py @@ -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( { diff --git a/homeassistant/components/threshold/const.py b/homeassistant/components/threshold/const.py index 2cb9dc88f0f..7dd44a950ed 100644 --- a/homeassistant/components/threshold/const.py +++ b/homeassistant/components/threshold/const.py @@ -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" diff --git a/tests/components/threshold/test_binary_sensor.py b/tests/components/threshold/test_binary_sensor.py index 250abdb9baa..493d6b859c7 100644 --- a/tests/components/threshold/test_binary_sensor.py +++ b/tests/components/threshold/test_binary_sensor.py @@ -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