mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add counter.set_value service (#92863)
This commit is contained in:
parent
98b91bcad9
commit
97cac66195
@ -44,6 +44,7 @@ SERVICE_DECREMENT = "decrement"
|
||||
SERVICE_INCREMENT = "increment"
|
||||
SERVICE_RESET = "reset"
|
||||
SERVICE_CONFIGURE = "configure"
|
||||
SERVICE_SET_VALUE = "set_value"
|
||||
|
||||
STORAGE_KEY = DOMAIN
|
||||
STORAGE_VERSION = 1
|
||||
@ -124,6 +125,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
component.async_register_entity_service(SERVICE_INCREMENT, {}, "async_increment")
|
||||
component.async_register_entity_service(SERVICE_DECREMENT, {}, "async_decrement")
|
||||
component.async_register_entity_service(SERVICE_RESET, {}, "async_reset")
|
||||
component.async_register_entity_service(
|
||||
SERVICE_SET_VALUE,
|
||||
{vol.Required(VALUE): cv.positive_int},
|
||||
"async_set_value",
|
||||
)
|
||||
component.async_register_entity_service(
|
||||
SERVICE_CONFIGURE,
|
||||
{
|
||||
@ -261,6 +267,27 @@ class Counter(collection.CollectionEntity, RestoreEntity):
|
||||
self._state = self.compute_next_state(self._config[CONF_INITIAL])
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def async_set_value(self, value: int) -> None:
|
||||
"""Set counter to value."""
|
||||
if (maximum := self._config.get(CONF_MAXIMUM)) is not None and value > maximum:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} exceeding the maximum value of {maximum}"
|
||||
)
|
||||
|
||||
if (minimum := self._config.get(CONF_MINIMUM)) is not None and value < minimum:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} exceeding the minimum value of {minimum}"
|
||||
)
|
||||
|
||||
if (step := self._config.get(CONF_STEP)) is not None and value % step != 0:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} is not a multiple of the step size {step}"
|
||||
)
|
||||
|
||||
self._state = value
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def async_configure(self, **kwargs) -> None:
|
||||
"""Change the counter's settings with a service."""
|
||||
|
@ -21,6 +21,23 @@ reset:
|
||||
entity:
|
||||
domain: counter
|
||||
|
||||
set_value:
|
||||
name: Set
|
||||
description: Set the counter value
|
||||
target:
|
||||
entity:
|
||||
domain: counter
|
||||
fields:
|
||||
value:
|
||||
name: Value
|
||||
required: true
|
||||
description: The new counter value the entity should be set to.
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 9223372036854775807
|
||||
mode: box
|
||||
|
||||
configure:
|
||||
name: Configure
|
||||
description: Change counter parameters.
|
||||
|
@ -11,14 +11,18 @@ from homeassistant.components.counter import (
|
||||
ATTR_STEP,
|
||||
CONF_ICON,
|
||||
CONF_INITIAL,
|
||||
CONF_MAXIMUM,
|
||||
CONF_MINIMUM,
|
||||
CONF_NAME,
|
||||
CONF_RESTORE,
|
||||
CONF_STEP,
|
||||
DEFAULT_INITIAL,
|
||||
DEFAULT_STEP,
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
VALUE,
|
||||
)
|
||||
from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_ICON, ATTR_NAME
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, ATTR_ICON, ATTR_NAME
|
||||
from homeassistant.core import Context, CoreState, HomeAssistant, State
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
@ -124,7 +128,7 @@ async def test_config_options(hass: HomeAssistant) -> None:
|
||||
|
||||
|
||||
async def test_methods(hass: HomeAssistant) -> None:
|
||||
"""Test increment, decrement, and reset methods."""
|
||||
"""Test increment, decrement, set value, and reset methods."""
|
||||
config = {DOMAIN: {"test_1": {}}}
|
||||
|
||||
assert await async_setup_component(hass, "counter", config)
|
||||
@ -158,11 +162,31 @@ async def test_methods(hass: HomeAssistant) -> None:
|
||||
state = hass.states.get(entity_id)
|
||||
assert int(state.state) == 0
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
VALUE: 5,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "5"
|
||||
|
||||
|
||||
async def test_methods_with_config(hass: HomeAssistant) -> None:
|
||||
"""Test increment, decrement, and reset methods with configuration."""
|
||||
config = {
|
||||
DOMAIN: {"test": {CONF_NAME: "Hello World", CONF_INITIAL: 10, CONF_STEP: 5}}
|
||||
DOMAIN: {
|
||||
"test": {
|
||||
CONF_NAME: "Hello World",
|
||||
CONF_INITIAL: 10,
|
||||
CONF_STEP: 5,
|
||||
CONF_MINIMUM: 5,
|
||||
CONF_MAXIMUM: 20,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert await async_setup_component(hass, "counter", config)
|
||||
@ -190,6 +214,67 @@ async def test_methods_with_config(hass: HomeAssistant) -> None:
|
||||
state = hass.states.get(entity_id)
|
||||
assert int(state.state) == 15
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
VALUE: 5,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "5"
|
||||
|
||||
with pytest.raises(
|
||||
ValueError, match=r"Value 25 for counter.test exceeding the maximum value of 20"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
VALUE: 25,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "5"
|
||||
|
||||
with pytest.raises(
|
||||
ValueError, match=r"Value 0 for counter.test exceeding the minimum value of 5"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
VALUE: 0,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "5"
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=r"Value 6 for counter.test is not a multiple of the step size 5",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
VALUE: 6,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "5"
|
||||
|
||||
|
||||
async def test_initial_state_overrules_restore_state(hass: HomeAssistant) -> None:
|
||||
"""Ensure states are restored on startup."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user