Change valve state to an enum (#126428)

This commit is contained in:
G Johansson 2024-09-23 14:20:18 +02:00 committed by GitHub
parent 9c6f903178
commit 939f2e41e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 165 additions and 170 deletions

View file

@ -13,6 +13,7 @@ from homeassistant.components.valve import (
DEVICE_CLASSES_SCHEMA, DEVICE_CLASSES_SCHEMA,
ValveEntity, ValveEntity,
ValveEntityFeature, ValveEntityFeature,
ValveState,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
@ -20,10 +21,6 @@ from homeassistant.const import (
CONF_NAME, CONF_NAME,
CONF_OPTIMISTIC, CONF_OPTIMISTIC,
CONF_VALUE_TEMPLATE, CONF_VALUE_TEMPLATE,
STATE_CLOSED,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -86,8 +83,8 @@ NO_POSITION_KEYS = (
DEFAULTS = { DEFAULTS = {
CONF_PAYLOAD_CLOSE: DEFAULT_PAYLOAD_CLOSE, CONF_PAYLOAD_CLOSE: DEFAULT_PAYLOAD_CLOSE,
CONF_PAYLOAD_OPEN: DEFAULT_PAYLOAD_OPEN, CONF_PAYLOAD_OPEN: DEFAULT_PAYLOAD_OPEN,
CONF_STATE_OPEN: STATE_OPEN, CONF_STATE_OPEN: ValveState.OPEN,
CONF_STATE_CLOSED: STATE_CLOSED, CONF_STATE_CLOSED: ValveState.CLOSED,
} }
RESET_CLOSING_OPENING = "reset_opening_closing" RESET_CLOSING_OPENING = "reset_opening_closing"
@ -118,9 +115,9 @@ _PLATFORM_SCHEMA_BASE = MQTT_BASE_SCHEMA.extend(
vol.Optional(CONF_REPORTS_POSITION, default=False): cv.boolean, vol.Optional(CONF_REPORTS_POSITION, default=False): cv.boolean,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean, vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
vol.Optional(CONF_STATE_CLOSED): cv.string, vol.Optional(CONF_STATE_CLOSED): cv.string,
vol.Optional(CONF_STATE_CLOSING, default=STATE_CLOSING): cv.string, vol.Optional(CONF_STATE_CLOSING, default=ValveState.CLOSING): cv.string,
vol.Optional(CONF_STATE_OPEN): cv.string, vol.Optional(CONF_STATE_OPEN): cv.string,
vol.Optional(CONF_STATE_OPENING, default=STATE_OPENING): cv.string, vol.Optional(CONF_STATE_OPENING, default=ValveState.OPENING): cv.string,
vol.Optional(CONF_STATE_TOPIC): valid_subscribe_topic, vol.Optional(CONF_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
} }
@ -216,14 +213,14 @@ class MqttValve(MqttEntity, ValveEntity):
@callback @callback
def _update_state(self, state: str | None) -> None: def _update_state(self, state: str | None) -> None:
"""Update the valve state properties.""" """Update the valve state properties."""
self._attr_is_opening = state == STATE_OPENING self._attr_is_opening = state == ValveState.OPENING
self._attr_is_closing = state == STATE_CLOSING self._attr_is_closing = state == ValveState.CLOSING
if self.reports_position: if self.reports_position:
return return
if state is None: if state is None:
self._attr_is_closed = None self._attr_is_closed = None
else: else:
self._attr_is_closed = state == STATE_CLOSED self._attr_is_closed = state == ValveState.CLOSED
@callback @callback
def _process_binary_valve_update( def _process_binary_valve_update(
@ -232,13 +229,13 @@ class MqttValve(MqttEntity, ValveEntity):
"""Process an update for a valve that does not report the position.""" """Process an update for a valve that does not report the position."""
state: str | None = None state: str | None = None
if state_payload == self._config[CONF_STATE_OPENING]: if state_payload == self._config[CONF_STATE_OPENING]:
state = STATE_OPENING state = ValveState.OPENING
elif state_payload == self._config[CONF_STATE_CLOSING]: elif state_payload == self._config[CONF_STATE_CLOSING]:
state = STATE_CLOSING state = ValveState.CLOSING
elif state_payload == self._config[CONF_STATE_OPEN]: elif state_payload == self._config[CONF_STATE_OPEN]:
state = STATE_OPEN state = ValveState.OPEN
elif state_payload == self._config[CONF_STATE_CLOSED]: elif state_payload == self._config[CONF_STATE_CLOSED]:
state = STATE_CLOSED state = ValveState.CLOSED
elif state_payload == PAYLOAD_NONE: elif state_payload == PAYLOAD_NONE:
state = None state = None
else: else:
@ -259,9 +256,9 @@ class MqttValve(MqttEntity, ValveEntity):
state: str | None = None state: str | None = None
position_set: bool = False position_set: bool = False
if state_payload == self._config[CONF_STATE_OPENING]: if state_payload == self._config[CONF_STATE_OPENING]:
state = STATE_OPENING state = ValveState.OPENING
elif state_payload == self._config[CONF_STATE_CLOSING]: elif state_payload == self._config[CONF_STATE_CLOSING]:
state = STATE_CLOSING state = ValveState.CLOSING
elif state_payload == PAYLOAD_NONE: elif state_payload == PAYLOAD_NONE:
self._attr_current_valve_position = None self._attr_current_valve_position = None
return return
@ -363,7 +360,7 @@ class MqttValve(MqttEntity, ValveEntity):
await self.async_publish_with_config(self._config[CONF_COMMAND_TOPIC], payload) await self.async_publish_with_config(self._config[CONF_COMMAND_TOPIC], payload)
if self._optimistic: if self._optimistic:
# Optimistically assume that valve has changed state. # Optimistically assume that valve has changed state.
self._update_state(STATE_OPEN) self._update_state(ValveState.OPEN)
self.async_write_ha_state() self.async_write_ha_state()
async def async_close_valve(self) -> None: async def async_close_valve(self) -> None:
@ -377,7 +374,7 @@ class MqttValve(MqttEntity, ValveEntity):
await self.async_publish_with_config(self._config[CONF_COMMAND_TOPIC], payload) await self.async_publish_with_config(self._config[CONF_COMMAND_TOPIC], payload)
if self._optimistic: if self._optimistic:
# Optimistically assume that valve has changed state. # Optimistically assume that valve has changed state.
self._update_state(STATE_CLOSED) self._update_state(ValveState.CLOSED)
self.async_write_ha_state() self.async_write_ha_state()
async def async_stop_valve(self) -> None: async def async_stop_valve(self) -> None:
@ -405,9 +402,9 @@ class MqttValve(MqttEntity, ValveEntity):
) )
if self._optimistic: if self._optimistic:
self._update_state( self._update_state(
STATE_CLOSED ValveState.CLOSED
if percentage_position == self._config[CONF_POSITION_CLOSED] if percentage_position == self._config[CONF_POSITION_CLOSED]
else STATE_OPEN else ValveState.OPEN
) )
self._attr_current_valve_position = percentage_position self._attr_current_valve_position = percentage_position
self.async_write_ha_state() self.async_write_ha_state()

View file

@ -11,7 +11,7 @@ from typing import Any, final
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import ( # noqa: F401
SERVICE_CLOSE_VALVE, SERVICE_CLOSE_VALVE,
SERVICE_OPEN_VALVE, SERVICE_OPEN_VALVE,
SERVICE_SET_VALVE_POSITION, SERVICE_SET_VALVE_POSITION,
@ -29,9 +29,10 @@ from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey from homeassistant.util.hass_dict import HassKey
from .const import DOMAIN, ValveState
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DOMAIN = "valve"
DOMAIN_DATA: HassKey[EntityComponent[ValveEntity]] = HassKey(DOMAIN) DOMAIN_DATA: HassKey[EntityComponent[ValveEntity]] = HassKey(DOMAIN)
ENTITY_ID_FORMAT = DOMAIN + ".{}" ENTITY_ID_FORMAT = DOMAIN + ".{}"
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
@ -173,18 +174,18 @@ class ValveEntity(Entity):
reports_position = self.reports_position reports_position = self.reports_position
if self.is_opening: if self.is_opening:
self.__is_last_toggle_direction_open = True self.__is_last_toggle_direction_open = True
return STATE_OPENING return ValveState.OPENING
if self.is_closing: if self.is_closing:
self.__is_last_toggle_direction_open = False self.__is_last_toggle_direction_open = False
return STATE_CLOSING return ValveState.CLOSING
if reports_position is True: if reports_position is True:
if (current_valve_position := self.current_valve_position) is None: if (current_valve_position := self.current_valve_position) is None:
return None return None
position_zero = current_valve_position == 0 position_zero = current_valve_position == 0
return STATE_CLOSED if position_zero else STATE_OPEN return ValveState.CLOSED if position_zero else ValveState.OPEN
if (closed := self.is_closed) is None: if (closed := self.is_closed) is None:
return None return None
return STATE_CLOSED if closed else STATE_OPEN return ValveState.CLOSED if closed else ValveState.OPEN
@final @final
@property @property

View file

@ -0,0 +1,14 @@
"""Constants for the Valve entity platform."""
from enum import StrEnum
DOMAIN = "valve"
class ValveState(StrEnum):
"""State of Valve entities."""
OPENING = "opening"
CLOSING = "closing"
CLOSED = "closed"
OPEN = "open"

View file

@ -10,7 +10,7 @@ from aioesphomeapi import (
UserService, UserService,
ValveInfo, ValveInfo,
ValveOperation, ValveOperation,
ValveState, ValveState as ESPHomeValveState,
) )
from homeassistant.components.valve import ( from homeassistant.components.valve import (
@ -21,10 +21,7 @@ from homeassistant.components.valve import (
SERVICE_OPEN_VALVE, SERVICE_OPEN_VALVE,
SERVICE_SET_VALVE_POSITION, SERVICE_SET_VALVE_POSITION,
SERVICE_STOP_VALVE, SERVICE_STOP_VALVE,
STATE_CLOSED, ValveState,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
) )
from homeassistant.const import ATTR_ENTITY_ID from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -52,7 +49,7 @@ async def test_valve_entity(
) )
] ]
states = [ states = [
ValveState( ESPHomeValveState(
key=1, key=1,
position=0.5, position=0.5,
current_operation=ValveOperation.IS_OPENING, current_operation=ValveOperation.IS_OPENING,
@ -67,7 +64,7 @@ async def test_valve_entity(
) )
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_OPENING assert state.state == ValveState.OPENING
assert state.attributes[ATTR_CURRENT_POSITION] == 50 assert state.attributes[ATTR_CURRENT_POSITION] == 50
await hass.services.async_call( await hass.services.async_call(
@ -107,28 +104,30 @@ async def test_valve_entity(
mock_client.valve_command.reset_mock() mock_client.valve_command.reset_mock()
mock_device.set_state( mock_device.set_state(
ValveState(key=1, position=0.0, current_operation=ValveOperation.IDLE) ESPHomeValveState(key=1, position=0.0, current_operation=ValveOperation.IDLE)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_CLOSED assert state.state == ValveState.CLOSED
mock_device.set_state( mock_device.set_state(
ValveState(key=1, position=0.5, current_operation=ValveOperation.IS_CLOSING) ESPHomeValveState(
key=1, position=0.5, current_operation=ValveOperation.IS_CLOSING
)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_CLOSING assert state.state == ValveState.CLOSING
mock_device.set_state( mock_device.set_state(
ValveState(key=1, position=1.0, current_operation=ValveOperation.IDLE) ESPHomeValveState(key=1, position=1.0, current_operation=ValveOperation.IDLE)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_OPEN assert state.state == ValveState.OPEN
async def test_valve_entity_without_position( async def test_valve_entity_without_position(
@ -151,7 +150,7 @@ async def test_valve_entity_without_position(
) )
] ]
states = [ states = [
ValveState( ESPHomeValveState(
key=1, key=1,
position=0.5, position=0.5,
current_operation=ValveOperation.IS_OPENING, current_operation=ValveOperation.IS_OPENING,
@ -166,7 +165,7 @@ async def test_valve_entity_without_position(
) )
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_OPENING assert state.state == ValveState.OPENING
assert ATTR_CURRENT_POSITION not in state.attributes assert ATTR_CURRENT_POSITION not in state.attributes
await hass.services.async_call( await hass.services.async_call(
@ -188,9 +187,9 @@ async def test_valve_entity_without_position(
mock_client.valve_command.reset_mock() mock_client.valve_command.reset_mock()
mock_device.set_state( mock_device.set_state(
ValveState(key=1, position=0.0, current_operation=ValveOperation.IDLE) ESPHomeValveState(key=1, position=0.0, current_operation=ValveOperation.IDLE)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("valve.test_myvalve") state = hass.states.get("valve.test_myvalve")
assert state is not None assert state is not None
assert state.state == STATE_CLOSED assert state.state == ValveState.CLOSED

View file

@ -612,10 +612,10 @@ async def test_startstop_vacuum(hass: HomeAssistant) -> None:
), ),
( (
valve.DOMAIN, valve.DOMAIN,
valve.STATE_OPEN, valve.ValveState.OPEN,
valve.STATE_CLOSED, valve.ValveState.CLOSED,
valve.STATE_OPENING, valve.ValveState.OPENING,
valve.STATE_CLOSING, valve.ValveState.CLOSING,
ValveEntityFeature.STOP ValveEntityFeature.STOP
| ValveEntityFeature.OPEN | ValveEntityFeature.OPEN
| ValveEntityFeature.CLOSE, | ValveEntityFeature.CLOSE,
@ -736,10 +736,10 @@ async def test_startstop_cover_valve(
), ),
( (
valve.DOMAIN, valve.DOMAIN,
valve.STATE_OPEN, valve.ValveState.OPEN,
valve.STATE_CLOSED, valve.ValveState.CLOSED,
valve.STATE_OPENING, valve.ValveState.OPENING,
valve.STATE_CLOSING, valve.ValveState.CLOSING,
ValveEntityFeature.STOP ValveEntityFeature.STOP
| ValveEntityFeature.OPEN | ValveEntityFeature.OPEN
| ValveEntityFeature.CLOSE, | ValveEntityFeature.CLOSE,
@ -3144,7 +3144,7 @@ async def test_openclose_cover_valve_unknown_state(
valve.DOMAIN, valve.DOMAIN,
valve.SERVICE_SET_VALVE_POSITION, valve.SERVICE_SET_VALVE_POSITION,
ValveEntityFeature.SET_POSITION, ValveEntityFeature.SET_POSITION,
valve.STATE_OPEN, valve.ValveState.OPEN,
), ),
], ],
) )
@ -3191,7 +3191,7 @@ async def test_openclose_cover_valve_assumed_state(
), ),
( (
valve.DOMAIN, valve.DOMAIN,
valve.STATE_OPEN, valve.ValveState.OPEN,
), ),
], ],
) )
@ -3242,8 +3242,8 @@ async def test_openclose_cover_valve_query_only(
), ),
( (
valve.DOMAIN, valve.DOMAIN,
valve.STATE_OPEN, valve.ValveState.OPEN,
valve.STATE_CLOSED, valve.ValveState.CLOSED,
ValveEntityFeature.OPEN | ValveEntityFeature.CLOSE, ValveEntityFeature.OPEN | ValveEntityFeature.CLOSE,
valve.SERVICE_OPEN_VALVE, valve.SERVICE_OPEN_VALVE,
valve.SERVICE_CLOSE_VALVE, valve.SERVICE_CLOSE_VALVE,

View file

@ -14,6 +14,7 @@ from homeassistant.components.valve import (
ATTR_CURRENT_POSITION, ATTR_CURRENT_POSITION,
ATTR_POSITION, ATTR_POSITION,
SERVICE_SET_VALVE_POSITION, SERVICE_SET_VALVE_POSITION,
ValveState,
) )
from homeassistant.const import ( from homeassistant.const import (
ATTR_ASSUMED_STATE, ATTR_ASSUMED_STATE,
@ -22,10 +23,6 @@ from homeassistant.const import (
SERVICE_CLOSE_VALVE, SERVICE_CLOSE_VALVE,
SERVICE_OPEN_VALVE, SERVICE_OPEN_VALVE,
SERVICE_STOP_VALVE, SERVICE_STOP_VALVE,
STATE_CLOSED,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
STATE_UNKNOWN, STATE_UNKNOWN,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -103,14 +100,14 @@ DEFAULT_CONFIG_REPORTS_POSITION = {
@pytest.mark.parametrize( @pytest.mark.parametrize(
("message", "asserted_state"), ("message", "asserted_state"),
[ [
("open", STATE_OPEN), ("open", ValveState.OPEN),
("closed", STATE_CLOSED), ("closed", ValveState.CLOSED),
("closing", STATE_CLOSING), ("closing", ValveState.CLOSING),
("opening", STATE_OPENING), ("opening", ValveState.OPENING),
('{"state" : "open"}', STATE_OPEN), ('{"state" : "open"}', ValveState.OPEN),
('{"state" : "closed"}', STATE_CLOSED), ('{"state" : "closed"}', ValveState.CLOSED),
('{"state" : "closing"}', STATE_CLOSING), ('{"state" : "closing"}', ValveState.CLOSING),
('{"state" : "opening"}', STATE_OPENING), ('{"state" : "opening"}', ValveState.OPENING),
], ],
) )
async def test_state_via_state_topic_no_position( async def test_state_via_state_topic_no_position(
@ -155,10 +152,10 @@ async def test_state_via_state_topic_no_position(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("message", "asserted_state"), ("message", "asserted_state"),
[ [
('{"state":"open"}', STATE_OPEN), ('{"state":"open"}', ValveState.OPEN),
('{"state":"closed"}', STATE_CLOSED), ('{"state":"closed"}', ValveState.CLOSED),
('{"state":"closing"}', STATE_CLOSING), ('{"state":"closing"}', ValveState.CLOSING),
('{"state":"opening"}', STATE_OPENING), ('{"state":"opening"}', ValveState.OPENING),
], ],
) )
async def test_state_via_state_topic_with_template( async def test_state_via_state_topic_with_template(
@ -199,9 +196,9 @@ async def test_state_via_state_topic_with_template(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("message", "asserted_state"), ("message", "asserted_state"),
[ [
('{"position":100}', STATE_OPEN), ('{"position":100}', ValveState.OPEN),
('{"position":50.0}', STATE_OPEN), ('{"position":50.0}', ValveState.OPEN),
('{"position":0}', STATE_CLOSED), ('{"position":0}', ValveState.CLOSED),
('{"position":null}', STATE_UNKNOWN), ('{"position":null}', STATE_UNKNOWN),
('{"position":"non_numeric"}', STATE_UNKNOWN), ('{"position":"non_numeric"}', STATE_UNKNOWN),
('{"ignored":12}', STATE_UNKNOWN), ('{"ignored":12}', STATE_UNKNOWN),
@ -245,23 +242,23 @@ async def test_state_via_state_topic_with_position_template(
("message", "asserted_state", "valve_position"), ("message", "asserted_state", "valve_position"),
[ [
("invalid", STATE_UNKNOWN, None), ("invalid", STATE_UNKNOWN, None),
("0", STATE_CLOSED, 0), ("0", ValveState.CLOSED, 0),
("opening", STATE_OPENING, None), ("opening", ValveState.OPENING, None),
("50", STATE_OPEN, 50), ("50", ValveState.OPEN, 50),
("closing", STATE_CLOSING, None), ("closing", ValveState.CLOSING, None),
("100", STATE_OPEN, 100), ("100", ValveState.OPEN, 100),
("open", STATE_UNKNOWN, None), ("open", STATE_UNKNOWN, None),
("closed", STATE_UNKNOWN, None), ("closed", STATE_UNKNOWN, None),
("-10", STATE_CLOSED, 0), ("-10", ValveState.CLOSED, 0),
("110", STATE_OPEN, 100), ("110", ValveState.OPEN, 100),
('{"position": 0, "state": "opening"}', STATE_OPENING, 0), ('{"position": 0, "state": "opening"}', ValveState.OPENING, 0),
('{"position": 10, "state": "opening"}', STATE_OPENING, 10), ('{"position": 10, "state": "opening"}', ValveState.OPENING, 10),
('{"position": 50, "state": "open"}', STATE_OPEN, 50), ('{"position": 50, "state": "open"}', ValveState.OPEN, 50),
('{"position": 100, "state": "closing"}', STATE_CLOSING, 100), ('{"position": 100, "state": "closing"}', ValveState.CLOSING, 100),
('{"position": 90, "state": "closing"}', STATE_CLOSING, 90), ('{"position": 90, "state": "closing"}', ValveState.CLOSING, 90),
('{"position": 0, "state": "closed"}', STATE_CLOSED, 0), ('{"position": 0, "state": "closed"}', ValveState.CLOSED, 0),
('{"position": -10, "state": "closed"}', STATE_CLOSED, 0), ('{"position": -10, "state": "closed"}', ValveState.CLOSED, 0),
('{"position": 110, "state": "open"}', STATE_OPEN, 100), ('{"position": 110, "state": "open"}', ValveState.OPEN, 100),
], ],
) )
async def test_state_via_state_topic_through_position( async def test_state_via_state_topic_through_position(
@ -319,18 +316,18 @@ async def test_opening_closing_state_is_reset(
assert not state.attributes.get(ATTR_ASSUMED_STATE) assert not state.attributes.get(ATTR_ASSUMED_STATE)
messages = [ messages = [
('{"position": 0, "state": "opening"}', STATE_OPENING, 0), ('{"position": 0, "state": "opening"}', ValveState.OPENING, 0),
('{"position": 50, "state": "opening"}', STATE_OPENING, 50), ('{"position": 50, "state": "opening"}', ValveState.OPENING, 50),
('{"position": 60}', STATE_OPENING, 60), ('{"position": 60}', ValveState.OPENING, 60),
('{"position": 100, "state": "opening"}', STATE_OPENING, 100), ('{"position": 100, "state": "opening"}', ValveState.OPENING, 100),
('{"position": 100, "state": null}', STATE_OPEN, 100), ('{"position": 100, "state": null}', ValveState.OPEN, 100),
('{"position": 90, "state": "closing"}', STATE_CLOSING, 90), ('{"position": 90, "state": "closing"}', ValveState.CLOSING, 90),
('{"position": 40}', STATE_CLOSING, 40), ('{"position": 40}', ValveState.CLOSING, 40),
('{"position": 0}', STATE_CLOSED, 0), ('{"position": 0}', ValveState.CLOSED, 0),
('{"position": 10}', STATE_OPEN, 10), ('{"position": 10}', ValveState.OPEN, 10),
('{"position": 0, "state": "opening"}', STATE_OPENING, 0), ('{"position": 0, "state": "opening"}', ValveState.OPENING, 0),
('{"position": 0, "state": "closing"}', STATE_CLOSING, 0), ('{"position": 0, "state": "closing"}', ValveState.CLOSING, 0),
('{"position": 0}', STATE_CLOSED, 0), ('{"position": 0}', ValveState.CLOSED, 0),
] ]
for message, asserted_state, valve_position in messages: for message, asserted_state, valve_position in messages:
@ -416,19 +413,19 @@ async def test_invalid_state_updates(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("message", "asserted_state", "valve_position"), ("message", "asserted_state", "valve_position"),
[ [
("-128", STATE_CLOSED, 0), ("-128", ValveState.CLOSED, 0),
("0", STATE_OPEN, 50), ("0", ValveState.OPEN, 50),
("127", STATE_OPEN, 100), ("127", ValveState.OPEN, 100),
("-130", STATE_CLOSED, 0), ("-130", ValveState.CLOSED, 0),
("130", STATE_OPEN, 100), ("130", ValveState.OPEN, 100),
('{"position": -128, "state": "opening"}', STATE_OPENING, 0), ('{"position": -128, "state": "opening"}', ValveState.OPENING, 0),
('{"position": -30, "state": "opening"}', STATE_OPENING, 38), ('{"position": -30, "state": "opening"}', ValveState.OPENING, 38),
('{"position": 30, "state": "open"}', STATE_OPEN, 61), ('{"position": 30, "state": "open"}', ValveState.OPEN, 61),
('{"position": 127, "state": "closing"}', STATE_CLOSING, 100), ('{"position": 127, "state": "closing"}', ValveState.CLOSING, 100),
('{"position": 100, "state": "closing"}', STATE_CLOSING, 89), ('{"position": 100, "state": "closing"}', ValveState.CLOSING, 89),
('{"position": -128, "state": "closed"}', STATE_CLOSED, 0), ('{"position": -128, "state": "closed"}', ValveState.CLOSED, 0),
('{"position": -130, "state": "closed"}', STATE_CLOSED, 0), ('{"position": -130, "state": "closed"}', ValveState.CLOSED, 0),
('{"position": 130, "state": "open"}', STATE_OPEN, 100), ('{"position": 130, "state": "open"}', ValveState.OPEN, 100),
], ],
) )
async def test_state_via_state_trough_position_with_alt_range( async def test_state_via_state_trough_position_with_alt_range(
@ -632,8 +629,8 @@ async def test_open_close_payload_config_not_allowed(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("service", "asserted_message", "asserted_state"), ("service", "asserted_message", "asserted_state"),
[ [
(SERVICE_CLOSE_VALVE, "CLOSE", STATE_CLOSED), (SERVICE_CLOSE_VALVE, "CLOSE", ValveState.CLOSED),
(SERVICE_OPEN_VALVE, "OPEN", STATE_OPEN), (SERVICE_OPEN_VALVE, "OPEN", ValveState.OPEN),
], ],
) )
async def test_controlling_valve_by_state_optimistic( async def test_controlling_valve_by_state_optimistic(
@ -782,9 +779,9 @@ async def test_controlling_valve_by_set_valve_position(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("position", "asserted_message", "asserted_position", "asserted_state"), ("position", "asserted_message", "asserted_position", "asserted_state"),
[ [
(0, "0", 0, STATE_CLOSED), (0, "0", 0, ValveState.CLOSED),
(30, "30", 30, STATE_OPEN), (30, "30", 30, ValveState.OPEN),
(100, "100", 100, STATE_OPEN), (100, "100", 100, ValveState.OPEN),
], ],
) )
async def test_controlling_valve_optimistic_by_set_valve_position( async def test_controlling_valve_optimistic_by_set_valve_position(
@ -947,8 +944,8 @@ async def test_controlling_valve_with_alt_range_by_position(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("service", "asserted_message", "asserted_state", "asserted_position"), ("service", "asserted_message", "asserted_state", "asserted_position"),
[ [
(SERVICE_CLOSE_VALVE, "0", STATE_CLOSED, 0), (SERVICE_CLOSE_VALVE, "0", ValveState.CLOSED, 0),
(SERVICE_OPEN_VALVE, "100", STATE_OPEN, 100), (SERVICE_OPEN_VALVE, "100", ValveState.OPEN, 100),
], ],
) )
async def test_controlling_valve_by_position_optimistic( async def test_controlling_valve_by_position_optimistic(
@ -1004,10 +1001,10 @@ async def test_controlling_valve_by_position_optimistic(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("position", "asserted_message", "asserted_position", "asserted_state"), ("position", "asserted_message", "asserted_position", "asserted_state"),
[ [
(0, "-128", 0, STATE_CLOSED), (0, "-128", 0, ValveState.CLOSED),
(30, "-52", 30, STATE_OPEN), (30, "-52", 30, ValveState.OPEN),
(50, "0", 50, STATE_OPEN), (50, "0", 50, ValveState.OPEN),
(100, "127", 100, STATE_OPEN), (100, "127", 100, ValveState.OPEN),
], ],
) )
async def test_controlling_valve_optimistic_alt_range_by_set_valve_position( async def test_controlling_valve_optimistic_alt_range_by_set_valve_position(

View file

@ -5,16 +5,8 @@ from unittest.mock import Mock
from aioshelly.const import MODEL_GAS from aioshelly.const import MODEL_GAS
import pytest import pytest
from homeassistant.components.valve import DOMAIN as VALVE_DOMAIN from homeassistant.components.valve import DOMAIN as VALVE_DOMAIN, ValveState
from homeassistant.const import ( from homeassistant.const import ATTR_ENTITY_ID, SERVICE_CLOSE_VALVE, SERVICE_OPEN_VALVE
ATTR_ENTITY_ID,
SERVICE_CLOSE_VALVE,
SERVICE_OPEN_VALVE,
STATE_CLOSED,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
@ -37,7 +29,7 @@ async def test_block_device_gas_valve(
assert entry assert entry
assert entry.unique_id == "123456789ABC-valve_0-valve" assert entry.unique_id == "123456789ABC-valve_0-valve"
assert hass.states.get(entity_id).state == STATE_CLOSED assert hass.states.get(entity_id).state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -48,7 +40,7 @@ async def test_block_device_gas_valve(
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state assert state
assert state.state == STATE_OPENING assert state.state == ValveState.OPENING
monkeypatch.setattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "valve", "opened") monkeypatch.setattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "valve", "opened")
mock_block_device.mock_update() mock_block_device.mock_update()
@ -56,7 +48,7 @@ async def test_block_device_gas_valve(
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state assert state
assert state.state == STATE_OPEN assert state.state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -67,7 +59,7 @@ async def test_block_device_gas_valve(
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state assert state
assert state.state == STATE_CLOSING assert state.state == ValveState.CLOSING
monkeypatch.setattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "valve", "closed") monkeypatch.setattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "valve", "closed")
mock_block_device.mock_update() mock_block_device.mock_update()
@ -75,4 +67,4 @@ async def test_block_device_gas_valve(
state = hass.states.get(entity_id) state = hass.states.get(entity_id)
assert state assert state
assert state.state == STATE_CLOSED assert state.state == ValveState.CLOSED

View file

@ -7,7 +7,7 @@ from homeassistant.components.switch_as_x.const import (
CONF_TARGET_DOMAIN, CONF_TARGET_DOMAIN,
DOMAIN, DOMAIN,
) )
from homeassistant.components.valve import DOMAIN as VALVE_DOMAIN from homeassistant.components.valve import DOMAIN as VALVE_DOMAIN, ValveState
from homeassistant.const import ( from homeassistant.const import (
CONF_ENTITY_ID, CONF_ENTITY_ID,
SERVICE_CLOSE_VALVE, SERVICE_CLOSE_VALVE,
@ -15,10 +15,8 @@ from homeassistant.const import (
SERVICE_TOGGLE, SERVICE_TOGGLE,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
SERVICE_TURN_ON, SERVICE_TURN_ON,
STATE_CLOSED,
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_OPEN,
Platform, Platform,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -71,7 +69,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -81,7 +79,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -91,7 +89,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -101,7 +99,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -111,7 +109,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -121,7 +119,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -131,7 +129,7 @@ async def test_service_calls(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
async def test_service_calls_inverted(hass: HomeAssistant) -> None: async def test_service_calls_inverted(hass: HomeAssistant) -> None:
@ -154,7 +152,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -164,7 +162,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -174,7 +172,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
VALVE_DOMAIN, VALVE_DOMAIN,
@ -184,7 +182,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -194,7 +192,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -204,7 +202,7 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_OFF assert hass.states.get("switch.decorative_lights").state == STATE_OFF
assert hass.states.get("valve.decorative_lights").state == STATE_OPEN assert hass.states.get("valve.decorative_lights").state == ValveState.OPEN
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
@ -214,4 +212,4 @@ async def test_service_calls_inverted(hass: HomeAssistant) -> None:
) )
assert hass.states.get("switch.decorative_lights").state == STATE_ON assert hass.states.get("switch.decorative_lights").state == STATE_ON
assert hass.states.get("valve.decorative_lights").state == STATE_CLOSED assert hass.states.get("valve.decorative_lights").state == ValveState.CLOSED

View file

@ -11,16 +11,13 @@ from homeassistant.components.valve import (
ValveEntity, ValveEntity,
ValveEntityDescription, ValveEntityDescription,
ValveEntityFeature, ValveEntityFeature,
ValveState,
) )
from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
SERVICE_SET_VALVE_POSITION, SERVICE_SET_VALVE_POSITION,
SERVICE_TOGGLE, SERVICE_TOGGLE,
STATE_CLOSED,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
Platform, Platform,
) )
@ -349,19 +346,19 @@ def set_valve_position(ent, position) -> None:
def is_open(hass: HomeAssistant, ent: ValveEntity) -> bool: def is_open(hass: HomeAssistant, ent: ValveEntity) -> bool:
"""Return if the valve is closed based on the statemachine.""" """Return if the valve is closed based on the statemachine."""
return hass.states.is_state(ent.entity_id, STATE_OPEN) return hass.states.is_state(ent.entity_id, ValveState.OPEN)
def is_opening(hass: HomeAssistant, ent: ValveEntity) -> bool: def is_opening(hass: HomeAssistant, ent: ValveEntity) -> bool:
"""Return if the valve is closed based on the statemachine.""" """Return if the valve is closed based on the statemachine."""
return hass.states.is_state(ent.entity_id, STATE_OPENING) return hass.states.is_state(ent.entity_id, ValveState.OPENING)
def is_closed(hass: HomeAssistant, ent: ValveEntity) -> bool: def is_closed(hass: HomeAssistant, ent: ValveEntity) -> bool:
"""Return if the valve is closed based on the statemachine.""" """Return if the valve is closed based on the statemachine."""
return hass.states.is_state(ent.entity_id, STATE_CLOSED) return hass.states.is_state(ent.entity_id, ValveState.CLOSED)
def is_closing(hass: HomeAssistant, ent: ValveEntity) -> bool: def is_closing(hass: HomeAssistant, ent: ValveEntity) -> bool:
"""Return if the valve is closed based on the statemachine.""" """Return if the valve is closed based on the statemachine."""
return hass.states.is_state(ent.entity_id, STATE_CLOSING) return hass.states.is_state(ent.entity_id, ValveState.CLOSING)

View file

@ -6,8 +6,8 @@ from homeassistant.components.valve import (
SERVICE_CLOSE_VALVE, SERVICE_CLOSE_VALVE,
SERVICE_OPEN_VALVE, SERVICE_OPEN_VALVE,
SERVICE_SET_VALVE_POSITION, SERVICE_SET_VALVE_POSITION,
ValveState,
) )
from homeassistant.const import STATE_CLOSED, STATE_OPEN
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import intent from homeassistant.helpers import intent
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -20,7 +20,7 @@ async def test_open_valve_intent(hass: HomeAssistant) -> None:
assert await async_setup_component(hass, "intent", {}) assert await async_setup_component(hass, "intent", {})
entity_id = f"{DOMAIN}.test_valve" entity_id = f"{DOMAIN}.test_valve"
hass.states.async_set(entity_id, STATE_CLOSED) hass.states.async_set(entity_id, ValveState.CLOSED)
calls = async_mock_service(hass, DOMAIN, SERVICE_OPEN_VALVE) calls = async_mock_service(hass, DOMAIN, SERVICE_OPEN_VALVE)
response = await intent.async_handle( response = await intent.async_handle(
@ -41,7 +41,7 @@ async def test_close_valve_intent(hass: HomeAssistant) -> None:
assert await async_setup_component(hass, "intent", {}) assert await async_setup_component(hass, "intent", {})
entity_id = f"{DOMAIN}.test_valve" entity_id = f"{DOMAIN}.test_valve"
hass.states.async_set(entity_id, STATE_OPEN) hass.states.async_set(entity_id, ValveState.OPEN)
calls = async_mock_service(hass, DOMAIN, SERVICE_CLOSE_VALVE) calls = async_mock_service(hass, DOMAIN, SERVICE_CLOSE_VALVE)
response = await intent.async_handle( response = await intent.async_handle(
@ -63,7 +63,7 @@ async def test_set_valve_position(hass: HomeAssistant) -> None:
entity_id = f"{DOMAIN}.test_valve" entity_id = f"{DOMAIN}.test_valve"
hass.states.async_set( hass.states.async_set(
entity_id, STATE_CLOSED, attributes={ATTR_CURRENT_POSITION: 0} entity_id, ValveState.CLOSED, attributes={ATTR_CURRENT_POSITION: 0}
) )
calls = async_mock_service(hass, DOMAIN, SERVICE_SET_VALVE_POSITION) calls = async_mock_service(hass, DOMAIN, SERVICE_SET_VALVE_POSITION)