Allow device conditions and triggers for unitless sensors (#70337)
parent
4d09078114
commit
7b1e0e42f7
|
@ -16,14 +16,18 @@ from homeassistant.const import (
|
|||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import condition, config_validation as cv
|
||||
from homeassistant.helpers.entity import get_device_class, get_unit_of_measurement
|
||||
from homeassistant.helpers.entity import (
|
||||
get_capability,
|
||||
get_device_class,
|
||||
get_unit_of_measurement,
|
||||
)
|
||||
from homeassistant.helpers.entity_registry import (
|
||||
async_entries_for_device,
|
||||
async_get_registry,
|
||||
)
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from . import DOMAIN, SensorDeviceClass
|
||||
from . import ATTR_STATE_CLASS, DOMAIN, SensorDeviceClass
|
||||
|
||||
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||
|
||||
|
@ -146,9 +150,10 @@ async def async_get_conditions(
|
|||
|
||||
for entry in entries:
|
||||
device_class = get_device_class(hass, entry.entity_id) or DEVICE_CLASS_NONE
|
||||
state_class = get_capability(hass, entry.entity_id, ATTR_STATE_CLASS)
|
||||
unit_of_measurement = get_unit_of_measurement(hass, entry.entity_id)
|
||||
|
||||
if not unit_of_measurement:
|
||||
if not unit_of_measurement and not state_class:
|
||||
continue
|
||||
|
||||
templates = ENTITY_CONDITIONS.get(
|
||||
|
|
|
@ -17,10 +17,14 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity import get_device_class, get_unit_of_measurement
|
||||
from homeassistant.helpers.entity import (
|
||||
get_capability,
|
||||
get_device_class,
|
||||
get_unit_of_measurement,
|
||||
)
|
||||
from homeassistant.helpers.entity_registry import async_entries_for_device
|
||||
|
||||
from . import DOMAIN, SensorDeviceClass
|
||||
from . import ATTR_STATE_CLASS, DOMAIN, SensorDeviceClass
|
||||
|
||||
# mypy: allow-untyped-defs, no-check-untyped-defs
|
||||
|
||||
|
@ -165,9 +169,10 @@ async def async_get_triggers(hass, device_id):
|
|||
|
||||
for entry in entries:
|
||||
device_class = get_device_class(hass, entry.entity_id) or DEVICE_CLASS_NONE
|
||||
state_class = get_capability(hass, entry.entity_id, ATTR_STATE_CLASS)
|
||||
unit_of_measurement = get_unit_of_measurement(hass, entry.entity_id)
|
||||
|
||||
if not unit_of_measurement:
|
||||
if not unit_of_measurement and not state_class:
|
||||
continue
|
||||
|
||||
templates = ENTITY_TRIGGERS.get(
|
||||
|
|
|
@ -3,7 +3,12 @@ import pytest
|
|||
|
||||
import homeassistant.components.automation as automation
|
||||
from homeassistant.components.device_automation import DeviceAutomationType
|
||||
from homeassistant.components.sensor import DOMAIN, SensorDeviceClass
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.components.sensor.device_condition import ENTITY_CONDITIONS
|
||||
from homeassistant.const import CONF_PLATFORM, PERCENTAGE, STATE_UNKNOWN
|
||||
from homeassistant.helpers import device_registry
|
||||
|
@ -175,6 +180,56 @@ async def test_get_conditions_no_state(hass, device_reg, entity_reg):
|
|||
assert_lists_same(conditions, expected_conditions)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"state_class,unit,condition_types",
|
||||
(
|
||||
(SensorStateClass.MEASUREMENT, None, ["is_value"]),
|
||||
(SensorStateClass.TOTAL, None, ["is_value"]),
|
||||
(SensorStateClass.TOTAL_INCREASING, None, ["is_value"]),
|
||||
(SensorStateClass.MEASUREMENT, "dogs", ["is_value"]),
|
||||
(None, None, []),
|
||||
),
|
||||
)
|
||||
async def test_get_conditions_no_unit_or_stateclass(
|
||||
hass,
|
||||
device_reg,
|
||||
entity_reg,
|
||||
state_class,
|
||||
unit,
|
||||
condition_types,
|
||||
):
|
||||
"""Test we get the expected conditions from an entity with no unit or state class."""
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
DOMAIN,
|
||||
"test",
|
||||
"5678",
|
||||
capabilities={ATTR_STATE_CLASS: state_class},
|
||||
device_id=device_entry.id,
|
||||
unit_of_measurement=unit,
|
||||
)
|
||||
expected_conditions = [
|
||||
{
|
||||
"condition": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": condition,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": f"{DOMAIN}.test_5678",
|
||||
"metadata": {"secondary": False},
|
||||
}
|
||||
for condition in condition_types
|
||||
]
|
||||
conditions = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.CONDITION, device_entry.id
|
||||
)
|
||||
assert_lists_same(conditions, expected_conditions)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"set_state,device_class_reg,device_class_state,unit_reg,unit_state",
|
||||
[
|
||||
|
|
|
@ -5,7 +5,12 @@ import pytest
|
|||
|
||||
import homeassistant.components.automation as automation
|
||||
from homeassistant.components.device_automation import DeviceAutomationType
|
||||
from homeassistant.components.sensor import DOMAIN, SensorDeviceClass
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.components.sensor.device_trigger import ENTITY_TRIGGERS
|
||||
from homeassistant.const import CONF_PLATFORM, PERCENTAGE, STATE_UNKNOWN
|
||||
from homeassistant.helpers import device_registry
|
||||
|
@ -138,6 +143,56 @@ async def test_get_triggers_hidden_auxiliary(
|
|||
assert_lists_same(triggers, expected_triggers)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"state_class,unit,trigger_types",
|
||||
(
|
||||
(SensorStateClass.MEASUREMENT, None, ["value"]),
|
||||
(SensorStateClass.TOTAL, None, ["value"]),
|
||||
(SensorStateClass.TOTAL_INCREASING, None, ["value"]),
|
||||
(SensorStateClass.MEASUREMENT, "dogs", ["value"]),
|
||||
(None, None, []),
|
||||
),
|
||||
)
|
||||
async def test_get_triggers_no_unit_or_stateclass(
|
||||
hass,
|
||||
device_reg,
|
||||
entity_reg,
|
||||
state_class,
|
||||
unit,
|
||||
trigger_types,
|
||||
):
|
||||
"""Test we get the expected triggers from an entity with no unit or state class."""
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
DOMAIN,
|
||||
"test",
|
||||
"5678",
|
||||
capabilities={ATTR_STATE_CLASS: state_class},
|
||||
device_id=device_entry.id,
|
||||
unit_of_measurement=unit,
|
||||
)
|
||||
expected_triggers = [
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": trigger,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": f"{DOMAIN}.test_5678",
|
||||
"metadata": {"secondary": False},
|
||||
}
|
||||
for trigger in trigger_types
|
||||
]
|
||||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
)
|
||||
assert_lists_same(triggers, expected_triggers)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"set_state,device_class_reg,device_class_state,unit_reg,unit_state",
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue