Schedule coroutines with eager_task from async_track_state_change_event (#112807)

This commit is contained in:
J. Nick Koston 2024-03-09 11:24:54 -10:00 committed by GitHub
parent 4882fed939
commit 23ebd80285
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 1 deletions

View File

@ -328,7 +328,7 @@ def _async_dispatch_entity_id_event(
return return
for job in callbacks_list.copy(): for job in callbacks_list.copy():
try: try:
hass.async_run_hass_job(job, event) hass.async_run_hass_job(job, event, eager_start=True)
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.exception( _LOGGER.exception(
"Error while dispatching event for %s to %s", "Error while dispatching event for %s to %s",

View File

@ -32,14 +32,17 @@ async def test_binary_expose(hass: HomeAssistant, knx: KNXTestKit) -> None:
# Change state to on # Change state to on
hass.states.async_set(entity_id, "on", {}) hass.states.async_set(entity_id, "on", {})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", True) await knx.assert_write("1/1/8", True)
# Change attribute; keep state # Change attribute; keep state
hass.states.async_set(entity_id, "on", {"brightness": 180}) hass.states.async_set(entity_id, "on", {"brightness": 180})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# Change attribute and state # Change attribute and state
hass.states.async_set(entity_id, "off", {"brightness": 0}) hass.states.async_set(entity_id, "off", {"brightness": 0})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", False) await knx.assert_write("1/1/8", False)
@ -64,10 +67,12 @@ async def test_expose_attribute(hass: HomeAssistant, knx: KNXTestKit) -> None:
# Change state to "on"; no attribute # Change state to "on"; no attribute
hass.states.async_set(entity_id, "on", {}) hass.states.async_set(entity_id, "on", {})
await hass.async_block_till_done()
await knx.assert_telegram_count(0) await knx.assert_telegram_count(0)
# Change attribute; keep state # Change attribute; keep state
hass.states.async_set(entity_id, "on", {attribute: 1}) hass.states.async_set(entity_id, "on", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (1,)) await knx.assert_write("1/1/8", (1,))
# Read in between # Read in between
@ -76,22 +81,27 @@ async def test_expose_attribute(hass: HomeAssistant, knx: KNXTestKit) -> None:
# Change state keep attribute # Change state keep attribute
hass.states.async_set(entity_id, "off", {attribute: 1}) hass.states.async_set(entity_id, "off", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_telegram_count(0) await knx.assert_telegram_count(0)
# Change state and attribute # Change state and attribute
hass.states.async_set(entity_id, "on", {attribute: 0}) hass.states.async_set(entity_id, "on", {attribute: 0})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (0,)) await knx.assert_write("1/1/8", (0,))
# Change state to "off"; no attribute # Change state to "off"; no attribute
hass.states.async_set(entity_id, "off", {}) hass.states.async_set(entity_id, "off", {})
await hass.async_block_till_done()
await knx.assert_telegram_count(0) await knx.assert_telegram_count(0)
# Change attribute; keep state # Change attribute; keep state
hass.states.async_set(entity_id, "on", {attribute: 1}) hass.states.async_set(entity_id, "on", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (1,)) await knx.assert_write("1/1/8", (1,))
# Change state to "off"; null attribute # Change state to "off"; null attribute
hass.states.async_set(entity_id, "off", {attribute: None}) hass.states.async_set(entity_id, "off", {attribute: None})
await hass.async_block_till_done()
await knx.assert_telegram_count(0) await knx.assert_telegram_count(0)
@ -119,18 +129,22 @@ async def test_expose_attribute_with_default(
# Change state to "on"; no attribute # Change state to "on"; no attribute
hass.states.async_set(entity_id, "on", {}) hass.states.async_set(entity_id, "on", {})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (0,)) await knx.assert_write("1/1/8", (0,))
# Change attribute; keep state # Change attribute; keep state
hass.states.async_set(entity_id, "on", {attribute: 1}) hass.states.async_set(entity_id, "on", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (1,)) await knx.assert_write("1/1/8", (1,))
# Change state keep attribute # Change state keep attribute
hass.states.async_set(entity_id, "off", {attribute: 1}) hass.states.async_set(entity_id, "off", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# Change state and attribute # Change state and attribute
hass.states.async_set(entity_id, "on", {attribute: 3}) hass.states.async_set(entity_id, "on", {attribute: 3})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (3,)) await knx.assert_write("1/1/8", (3,))
# Read in between # Read in between
@ -139,14 +153,17 @@ async def test_expose_attribute_with_default(
# Change state to "off"; no attribute # Change state to "off"; no attribute
hass.states.async_set(entity_id, "off", {}) hass.states.async_set(entity_id, "off", {})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (0,)) await knx.assert_write("1/1/8", (0,))
# Change state and attribute # Change state and attribute
hass.states.async_set(entity_id, "on", {attribute: 1}) hass.states.async_set(entity_id, "on", {attribute: 1})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (1,)) await knx.assert_write("1/1/8", (1,))
# Change state to "off"; null attribute # Change state to "off"; null attribute
hass.states.async_set(entity_id, "off", {attribute: None}) hass.states.async_set(entity_id, "off", {attribute: None})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (0,)) await knx.assert_write("1/1/8", (0,))
@ -179,6 +196,7 @@ async def test_expose_string(hass: HomeAssistant, knx: KNXTestKit) -> None:
"on", "on",
{attribute: "This is a very long string that is larger than 14 bytes"}, {attribute: "This is a very long string that is larger than 14 bytes"},
) )
await hass.async_block_till_done()
await knx.assert_write( await knx.assert_write(
"1/1/8", (84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 118, 101, 114, 121) "1/1/8", (84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 118, 101, 114, 121)
) )
@ -200,13 +218,16 @@ async def test_expose_cooldown(hass: HomeAssistant, knx: KNXTestKit) -> None:
) )
# Change state to 1 # Change state to 1
hass.states.async_set(entity_id, "1", {}) hass.states.async_set(entity_id, "1", {})
await hass.async_block_till_done()
await knx.assert_write("1/1/8", (1,)) await knx.assert_write("1/1/8", (1,))
# Change state to 2 - skip because of cooldown # Change state to 2 - skip because of cooldown
hass.states.async_set(entity_id, "2", {}) hass.states.async_set(entity_id, "2", {})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# Change state to 3 # Change state to 3
hass.states.async_set(entity_id, "3", {}) hass.states.async_set(entity_id, "3", {})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# Wait for cooldown to pass # Wait for cooldown to pass
async_fire_time_changed_exact( async_fire_time_changed_exact(
@ -245,6 +266,7 @@ async def test_expose_conversion_exception(
"on", "on",
{attribute: 101}, {attribute: 101},
) )
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
assert ( assert (
'Could not expose fake.entity fake_attribute value "101.0" to KNX:' 'Could not expose fake.entity fake_attribute value "101.0" to KNX:'

View File

@ -208,6 +208,7 @@ async def test_exposure_register(hass: HomeAssistant, knx: KNXTestKit) -> None:
# no exposure registered # no exposure registered
hass.states.async_set(test_entity, STATE_ON, {}) hass.states.async_set(test_entity, STATE_ON, {})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# register exposure # register exposure
@ -218,6 +219,7 @@ async def test_exposure_register(hass: HomeAssistant, knx: KNXTestKit) -> None:
blocking=True, blocking=True,
) )
hass.states.async_set(test_entity, STATE_OFF, {}) hass.states.async_set(test_entity, STATE_OFF, {})
await hass.async_block_till_done()
await knx.assert_write(test_address, False) await knx.assert_write(test_address, False)
# register exposure # register exposure
@ -228,6 +230,7 @@ async def test_exposure_register(hass: HomeAssistant, knx: KNXTestKit) -> None:
blocking=True, blocking=True,
) )
hass.states.async_set(test_entity, STATE_ON, {}) hass.states.async_set(test_entity, STATE_ON, {})
await hass.async_block_till_done()
await knx.assert_no_telegram() await knx.assert_no_telegram()
# register exposure for attribute with default # register exposure for attribute with default
@ -245,8 +248,10 @@ async def test_exposure_register(hass: HomeAssistant, knx: KNXTestKit) -> None:
) )
# no attribute on first change wouldn't work because no attribute change since last test # no attribute on first change wouldn't work because no attribute change since last test
hass.states.async_set(test_entity, STATE_ON, {test_attribute: 30}) hass.states.async_set(test_entity, STATE_ON, {test_attribute: 30})
await hass.async_block_till_done()
await knx.assert_write(test_address, (30,)) await knx.assert_write(test_address, (30,))
hass.states.async_set(test_entity, STATE_OFF, {}) hass.states.async_set(test_entity, STATE_OFF, {})
await hass.async_block_till_done()
await knx.assert_write(test_address, (0,)) await knx.assert_write(test_address, (0,))
# don't send same value sequentially # don't send same value sequentially
hass.states.async_set(test_entity, STATE_ON, {test_attribute: 25}) hass.states.async_set(test_entity, STATE_ON, {test_attribute: 25})
@ -254,6 +259,7 @@ async def test_exposure_register(hass: HomeAssistant, knx: KNXTestKit) -> None:
hass.states.async_set(test_entity, STATE_ON, {test_attribute: 25, "unrelated": 2}) hass.states.async_set(test_entity, STATE_ON, {test_attribute: 25, "unrelated": 2})
hass.states.async_set(test_entity, STATE_OFF, {test_attribute: 25}) hass.states.async_set(test_entity, STATE_OFF, {test_attribute: 25})
await hass.async_block_till_done() await hass.async_block_till_done()
await hass.async_block_till_done()
await knx.assert_telegram_count(1) await knx.assert_telegram_count(1)
await knx.assert_write(test_address, (25,)) await knx.assert_write(test_address, (25,))