mirror of
https://github.com/home-assistant/core.git
synced 2026-04-17 23:53:49 +01:00
Adjust light triggers (#166263)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
@@ -30,10 +30,10 @@ BRIGHTNESS_DOMAIN_SPECS = {
|
||||
|
||||
TRIGGERS: dict[str, type[Trigger]] = {
|
||||
"brightness_changed": make_entity_numerical_state_changed_trigger(
|
||||
BRIGHTNESS_DOMAIN_SPECS
|
||||
BRIGHTNESS_DOMAIN_SPECS, valid_unit="%"
|
||||
),
|
||||
"brightness_crossed_threshold": make_entity_numerical_state_crossed_threshold_trigger(
|
||||
BRIGHTNESS_DOMAIN_SPECS
|
||||
BRIGHTNESS_DOMAIN_SPECS, valid_unit="%"
|
||||
),
|
||||
"turned_off": make_entity_target_state_trigger(DOMAIN, STATE_OFF),
|
||||
"turned_on": make_entity_target_state_trigger(DOMAIN, STATE_ON),
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
domain:
|
||||
- input_number
|
||||
- number
|
||||
- sensor
|
||||
- domain: input_number
|
||||
unit_of_measurement: "%"
|
||||
- domain: number
|
||||
unit_of_measurement: "%"
|
||||
- domain: sensor
|
||||
unit_of_measurement: "%"
|
||||
translation_key: number_or_entity
|
||||
|
||||
turned_on: *trigger_common
|
||||
|
||||
@@ -12,6 +12,7 @@ from homeassistant.const import (
|
||||
ATTR_DEVICE_ID,
|
||||
ATTR_FLOOR_ID,
|
||||
ATTR_LABEL_ID,
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
CONF_ABOVE,
|
||||
CONF_BELOW,
|
||||
CONF_CONDITION,
|
||||
@@ -1160,3 +1161,78 @@ async def assert_trigger_behavior_last(
|
||||
set_or_remove_state(hass, excluded_entity_id, excluded_state)
|
||||
await hass.async_block_till_done()
|
||||
assert len(service_calls) == 0
|
||||
|
||||
|
||||
async def assert_trigger_ignores_limit_entities_with_wrong_unit(
|
||||
hass: HomeAssistant,
|
||||
*,
|
||||
service_calls: list[ServiceCall],
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
entity_id: str,
|
||||
entity_state: str,
|
||||
reset_attributes: dict[str, Any],
|
||||
trigger_attributes: dict[str, Any],
|
||||
limit_entities: list[tuple[str, str]],
|
||||
correct_unit: str,
|
||||
wrong_unit: str,
|
||||
) -> None:
|
||||
"""Test that a trigger does not fire when limit entities have the wrong unit.
|
||||
|
||||
Verifies that ALL limit entities must have the correct unit_of_measurement
|
||||
for the trigger to fire. Limit entities are fixed one at a time; the trigger
|
||||
should only fire once all of them have the correct unit.
|
||||
|
||||
Args:
|
||||
trigger: The trigger key (e.g. "light.brightness_crossed_threshold").
|
||||
trigger_options: Trigger options dict (must already contain the limit
|
||||
entity IDs as values).
|
||||
entity_id: The entity being observed by the trigger.
|
||||
entity_state: The state string for the observed entity (e.g. STATE_ON).
|
||||
reset_attributes: Attributes to set on the entity before re-triggering.
|
||||
trigger_attributes: Attributes that should cause the trigger to fire.
|
||||
limit_entities: List of (entity_id, value) tuples for the limit entities.
|
||||
correct_unit: The unit that the trigger expects (e.g. "%").
|
||||
wrong_unit: A unit that the trigger should reject (e.g. "lx").
|
||||
|
||||
"""
|
||||
# Set up entity in triggering state
|
||||
hass.states.async_set(entity_id, entity_state, trigger_attributes)
|
||||
# Set up all limit entities with the wrong unit
|
||||
for limit_entity_id, limit_value in limit_entities:
|
||||
hass.states.async_set(
|
||||
limit_entity_id,
|
||||
limit_value,
|
||||
{ATTR_UNIT_OF_MEASUREMENT: wrong_unit},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
await arm_trigger(hass, trigger, trigger_options, {CONF_ENTITY_ID: [entity_id]})
|
||||
|
||||
# Cycle entity state - should NOT fire (all limit entities have wrong unit)
|
||||
hass.states.async_set(entity_id, entity_state, reset_attributes)
|
||||
await hass.async_block_till_done()
|
||||
hass.states.async_set(entity_id, entity_state, trigger_attributes)
|
||||
await hass.async_block_till_done()
|
||||
assert len(service_calls) == 0
|
||||
|
||||
# Fix limit entities one at a time; trigger should not fire until all are fixed
|
||||
for i, (limit_entity_id, limit_value) in enumerate(limit_entities):
|
||||
hass.states.async_set(
|
||||
limit_entity_id,
|
||||
limit_value,
|
||||
{ATTR_UNIT_OF_MEASUREMENT: correct_unit},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hass.states.async_set(entity_id, entity_state, reset_attributes)
|
||||
await hass.async_block_till_done()
|
||||
hass.states.async_set(entity_id, entity_state, trigger_attributes)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
if i < len(limit_entities) - 1:
|
||||
# Not all limits fixed yet - should not fire
|
||||
assert len(service_calls) == 0
|
||||
else:
|
||||
# All limits fixed - should fire
|
||||
assert len(service_calls) == 1
|
||||
|
||||
@@ -20,6 +20,7 @@ from tests.components.common import (
|
||||
assert_trigger_behavior_first,
|
||||
assert_trigger_behavior_last,
|
||||
assert_trigger_gated_by_labs_flag,
|
||||
assert_trigger_ignores_limit_entities_with_wrong_unit,
|
||||
parametrize_target_entities,
|
||||
parametrize_trigger_states,
|
||||
target_entities,
|
||||
@@ -423,3 +424,52 @@ async def test_light_state_attribute_trigger_behavior_last(
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "limit_entities"),
|
||||
[
|
||||
(
|
||||
"light.brightness_changed",
|
||||
{
|
||||
CONF_ABOVE: "sensor.brightness_above",
|
||||
CONF_BELOW: "sensor.brightness_below",
|
||||
},
|
||||
["sensor.brightness_above", "sensor.brightness_below"],
|
||||
),
|
||||
(
|
||||
"light.brightness_crossed_threshold",
|
||||
{
|
||||
CONF_THRESHOLD_TYPE: ThresholdType.BETWEEN,
|
||||
CONF_LOWER_LIMIT: "sensor.brightness_lower",
|
||||
CONF_UPPER_LIMIT: "sensor.brightness_upper",
|
||||
},
|
||||
["sensor.brightness_lower", "sensor.brightness_upper"],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_light_trigger_ignores_limit_entity_with_wrong_unit(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
limit_entities: list[str],
|
||||
) -> None:
|
||||
"""Test numerical triggers do not fire if limit entities have the wrong unit."""
|
||||
await assert_trigger_ignores_limit_entities_with_wrong_unit(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
entity_id="light.test_light",
|
||||
entity_state=STATE_ON,
|
||||
reset_attributes={ATTR_BRIGHTNESS: 0},
|
||||
trigger_attributes={ATTR_BRIGHTNESS: 128},
|
||||
limit_entities=[
|
||||
(limit_entities[0], "10"),
|
||||
(limit_entities[1], "90"),
|
||||
],
|
||||
correct_unit="%",
|
||||
wrong_unit="lx",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user