mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +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_INCREMENT = "increment"
|
||||||
SERVICE_RESET = "reset"
|
SERVICE_RESET = "reset"
|
||||||
SERVICE_CONFIGURE = "configure"
|
SERVICE_CONFIGURE = "configure"
|
||||||
|
SERVICE_SET_VALUE = "set_value"
|
||||||
|
|
||||||
STORAGE_KEY = DOMAIN
|
STORAGE_KEY = DOMAIN
|
||||||
STORAGE_VERSION = 1
|
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_INCREMENT, {}, "async_increment")
|
||||||
component.async_register_entity_service(SERVICE_DECREMENT, {}, "async_decrement")
|
component.async_register_entity_service(SERVICE_DECREMENT, {}, "async_decrement")
|
||||||
component.async_register_entity_service(SERVICE_RESET, {}, "async_reset")
|
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(
|
component.async_register_entity_service(
|
||||||
SERVICE_CONFIGURE,
|
SERVICE_CONFIGURE,
|
||||||
{
|
{
|
||||||
@ -261,6 +267,27 @@ class Counter(collection.CollectionEntity, RestoreEntity):
|
|||||||
self._state = self.compute_next_state(self._config[CONF_INITIAL])
|
self._state = self.compute_next_state(self._config[CONF_INITIAL])
|
||||||
self.async_write_ha_state()
|
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
|
@callback
|
||||||
def async_configure(self, **kwargs) -> None:
|
def async_configure(self, **kwargs) -> None:
|
||||||
"""Change the counter's settings with a service."""
|
"""Change the counter's settings with a service."""
|
||||||
|
@ -21,6 +21,23 @@ reset:
|
|||||||
entity:
|
entity:
|
||||||
domain: counter
|
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:
|
configure:
|
||||||
name: Configure
|
name: Configure
|
||||||
description: Change counter parameters.
|
description: Change counter parameters.
|
||||||
|
@ -11,14 +11,18 @@ from homeassistant.components.counter import (
|
|||||||
ATTR_STEP,
|
ATTR_STEP,
|
||||||
CONF_ICON,
|
CONF_ICON,
|
||||||
CONF_INITIAL,
|
CONF_INITIAL,
|
||||||
|
CONF_MAXIMUM,
|
||||||
|
CONF_MINIMUM,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_RESTORE,
|
CONF_RESTORE,
|
||||||
CONF_STEP,
|
CONF_STEP,
|
||||||
DEFAULT_INITIAL,
|
DEFAULT_INITIAL,
|
||||||
DEFAULT_STEP,
|
DEFAULT_STEP,
|
||||||
DOMAIN,
|
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.core import Context, CoreState, HomeAssistant, State
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.setup import async_setup_component
|
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:
|
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": {}}}
|
config = {DOMAIN: {"test_1": {}}}
|
||||||
|
|
||||||
assert await async_setup_component(hass, "counter", config)
|
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)
|
state = hass.states.get(entity_id)
|
||||||
assert int(state.state) == 0
|
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:
|
async def test_methods_with_config(hass: HomeAssistant) -> None:
|
||||||
"""Test increment, decrement, and reset methods with configuration."""
|
"""Test increment, decrement, and reset methods with configuration."""
|
||||||
config = {
|
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)
|
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)
|
state = hass.states.get(entity_id)
|
||||||
assert int(state.state) == 15
|
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:
|
async def test_initial_state_overrules_restore_state(hass: HomeAssistant) -> None:
|
||||||
"""Ensure states are restored on startup."""
|
"""Ensure states are restored on startup."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user