[homeassistant] Use input_number.set_value for input_number entities (#19965)

This commit is contained in:
Jesse Hills
2026-10-05 08:56:34 +13:00
committed by GitHub
parent aad7907c37
commit 4f539d3391
9 changed files with 137 additions and 4 deletions
@@ -0,0 +1,32 @@
"""Tests for the homeassistant number platform."""
from collections.abc import Callable
from pathlib import Path
import pytest
from esphome.config import read_config
from esphome.core import CORE
VALID_CONFIG = "tests/component_tests/homeassistant/test_number.yaml"
INVALID_CONFIG = "tests/component_tests/homeassistant/test_number_invalid_domain.yaml"
def test_number_and_input_number_entities(
generate_main: Callable[[str | Path], str],
) -> None:
"""Both number and input_number entity IDs are accepted and passed to the C++ class."""
main_cpp = generate_main(VALID_CONFIG)
assert 'ha_number->set_entity_id("number.some_number");' in main_cpp
assert 'ha_input_number->set_entity_id("input_number.some_input");' in main_cpp
def test_number_rejects_unsupported_domain(
capsys: pytest.CaptureFixture[str],
) -> None:
"""An entity ID from another domain fails config validation."""
CORE.config_path = Path(INVALID_CONFIG)
assert read_config({}) is None
assert "is not supported by the number platform" in capsys.readouterr().out
@@ -0,0 +1,17 @@
---
esphome:
name: test
host:
logger:
api:
number:
- platform: homeassistant
entity_id: number.some_number
id: ha_number
- platform: homeassistant
entity_id: input_number.some_input
id: ha_input_number
@@ -0,0 +1,17 @@
---
esphome:
name: test
host:
logger:
api:
number:
- platform: homeassistant
entity_id: number.some_number
id: ha_number
- platform: homeassistant
entity_id: sensor.foo
id: ha_other_number
@@ -71,6 +71,9 @@ number:
- platform: homeassistant
entity_id: number.hello_world
id: ha_hello_world_number
- platform: homeassistant
entity_id: input_number.hello_world
id: ha_hello_world_input_number
sensor:
- platform: homeassistant
@@ -21,6 +21,12 @@ api:
- number.set:
id: ha_number
value: 42.5
- number.set:
id: ha_real_number
value: 12.5
- number.set:
id: ha_real_input_number
value: 7
- switch.turn_on: ha_switch
- switch.turn_off: ha_switch
- logger.log: "=== All tests completed ==="
@@ -129,6 +135,13 @@ text_sensor:
# Number component for testing HA number control
number:
# Real homeassistant numbers: the action used depends on the entity domain
- platform: homeassistant
id: ha_real_number
entity_id: number.test_real_number
- platform: homeassistant
id: ha_real_input_number
entity_id: input_number.test_real_input_number
- platform: template
name: "HA Controlled Number"
id: ha_number
@@ -86,6 +86,15 @@ async def test_api_homeassistant(
"nonexistent.action_for_error_test": loop.create_future(), # error_test_call
}
# Futures keyed by (service, entity_id) for the real homeassistant numbers
ha_real_number_futures = {
("number.set_value", "number.test_real_number"): loop.create_future(),
(
"input_number.set_value",
"input_number.test_real_input_number",
): loop.create_future(),
}
# Future for error message test
action_error_received_future = loop.create_future()
@@ -102,6 +111,10 @@ async def test_api_homeassistant(
if not future.done():
future.set_result(service_call)
key = (service_call.service, service_call.data.get("entity_id"))
if key in ha_real_number_futures and not ha_real_number_futures[key].done():
ha_real_number_futures[key].set_result(service_call)
# Immediately respond to the error test call so the test can proceed
# This needs to happen synchronously so ESPHome receives the response
# before logging "=== All tests completed ==="
@@ -201,6 +214,16 @@ async def test_api_homeassistant(
# Empty state with valid entity should work (use different entity to not interfere with test)
client.send_home_assistant_state("sensor.edge_case_empty_state", "", "")
# The real homeassistant numbers reject values outside min/max, which
# default to 0 until Home Assistant provides them
for entity in (
"number.test_real_number",
"input_number.test_real_input_number",
):
client.send_home_assistant_state(entity, "min", "0")
client.send_home_assistant_state(entity, "max", "100")
client.send_home_assistant_state(entity, "step", "0.5")
# List entities and services
_, services = await client.list_entities_services()
@@ -334,6 +357,21 @@ async def test_api_homeassistant(
# The value might be formatted with trailing zeros
assert float(number_call.data["value"]) == 42.5
# 7b. Real homeassistant numbers pick the action from the entity domain
real_number_call = await asyncio.wait_for(
ha_real_number_futures[("number.set_value", "number.test_real_number")],
timeout=2.0,
)
assert float(real_number_call.data["value"]) == 12.5
real_input_number_call = await asyncio.wait_for(
ha_real_number_futures[
("input_number.set_value", "input_number.test_real_input_number")
],
timeout=2.0,
)
assert float(real_input_number_call.data["value"]) == 7
# 8. HA Switch service calls
switch_on_call = await asyncio.wait_for(
service_call_futures["switch.turn_on"], timeout=2.0