mirror of https://github.com/home-assistant/core
342 lines
11 KiB
Python
342 lines
11 KiB
Python
"""Tests for KNX integration specific triggers."""
|
|
|
|
import logging
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components import automation
|
|
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF
|
|
from homeassistant.core import HomeAssistant, ServiceCall
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from .conftest import KNXTestKit
|
|
|
|
|
|
async def test_telegram_trigger(
|
|
hass: HomeAssistant,
|
|
service_calls: list[ServiceCall],
|
|
knx: KNXTestKit,
|
|
) -> None:
|
|
"""Test telegram triggers firing."""
|
|
await knx.setup_integration({})
|
|
|
|
# "id" field added to action to test if `trigger_data` passed correctly in `async_attach_trigger`
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
# "catch_all" trigger
|
|
{
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"catch_all": ("telegram - {{ trigger.destination }}"),
|
|
"id": (" {{ trigger.id }}"),
|
|
},
|
|
},
|
|
},
|
|
# "specific" trigger
|
|
{
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
"id": "test-id",
|
|
"destination": ["1/2/3", 2564], # 2564 -> "1/2/4" in raw format
|
|
"group_value_write": True,
|
|
"group_value_response": False,
|
|
"group_value_read": False,
|
|
"incoming": True,
|
|
"outgoing": True,
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"specific": ("telegram - {{ trigger.destination }}"),
|
|
"id": (" {{ trigger.id }}"),
|
|
},
|
|
},
|
|
},
|
|
]
|
|
},
|
|
)
|
|
|
|
# "specific" shall ignore destination address
|
|
await knx.receive_write("0/0/1", (0x03, 0x2F))
|
|
assert len(service_calls) == 1
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["catch_all"] == "telegram - 0/0/1"
|
|
assert test_call.data["id"] == 0
|
|
|
|
await knx.receive_write("1/2/4", (0x03, 0x2F))
|
|
assert len(service_calls) == 2
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["specific"] == "telegram - 1/2/4"
|
|
assert test_call.data["id"] == "test-id"
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["catch_all"] == "telegram - 1/2/4"
|
|
assert test_call.data["id"] == 0
|
|
|
|
# "specific" shall ignore GroupValueRead
|
|
await knx.receive_read("1/2/4")
|
|
assert len(service_calls) == 1
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["catch_all"] == "telegram - 1/2/4"
|
|
assert test_call.data["id"] == 0
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("payload", "type_option", "expected_value", "expected_unit"),
|
|
[
|
|
((0x4C,), {"type": "percent"}, 30, "%"),
|
|
((0x03,), {}, None, None), # "dpt" omitted defaults to None
|
|
((0x0C, 0x1A), {"type": "temperature"}, 21.00, "°C"),
|
|
],
|
|
)
|
|
async def test_telegram_trigger_dpt_option(
|
|
hass: HomeAssistant,
|
|
service_calls: list[ServiceCall],
|
|
knx: KNXTestKit,
|
|
payload: tuple[int, ...],
|
|
type_option: dict[str, bool],
|
|
expected_value: int | None,
|
|
expected_unit: str | None,
|
|
) -> None:
|
|
"""Test telegram trigger type option."""
|
|
await knx.setup_integration({})
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
# "catch_all" trigger
|
|
{
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
**type_option,
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"catch_all": ("telegram - {{ trigger.destination }}"),
|
|
"trigger": (" {{ trigger }}"),
|
|
},
|
|
},
|
|
},
|
|
]
|
|
},
|
|
)
|
|
await knx.receive_write("0/0/1", payload)
|
|
|
|
assert len(service_calls) == 1
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["catch_all"] == "telegram - 0/0/1"
|
|
assert test_call.data["trigger"]["value"] == expected_value
|
|
assert test_call.data["trigger"]["unit"] == expected_unit
|
|
|
|
await knx.receive_read("0/0/1")
|
|
|
|
assert len(service_calls) == 1
|
|
test_call = service_calls.pop()
|
|
assert test_call.data["catch_all"] == "telegram - 0/0/1"
|
|
assert test_call.data["trigger"]["value"] is None
|
|
assert test_call.data["trigger"]["unit"] is None
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"group_value_options",
|
|
[
|
|
{
|
|
"group_value_write": True,
|
|
"group_value_response": True,
|
|
"group_value_read": False,
|
|
},
|
|
{
|
|
"group_value_write": False,
|
|
"group_value_response": False,
|
|
"group_value_read": True,
|
|
},
|
|
{
|
|
# "group_value_write": True, # omitted defaults to True
|
|
"group_value_response": False,
|
|
"group_value_read": False,
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"direction_options",
|
|
[
|
|
{
|
|
"incoming": True,
|
|
"outgoing": True,
|
|
},
|
|
{
|
|
# "incoming": True, # omitted defaults to True
|
|
"outgoing": False,
|
|
},
|
|
{
|
|
"incoming": False,
|
|
"outgoing": True,
|
|
},
|
|
],
|
|
)
|
|
async def test_telegram_trigger_options(
|
|
hass: HomeAssistant,
|
|
service_calls: list[ServiceCall],
|
|
knx: KNXTestKit,
|
|
group_value_options: dict[str, bool],
|
|
direction_options: dict[str, bool],
|
|
) -> None:
|
|
"""Test telegram trigger options."""
|
|
await knx.setup_integration({})
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
# "catch_all" trigger
|
|
{
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
**group_value_options,
|
|
**direction_options,
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"catch_all": ("telegram - {{ trigger.destination }}"),
|
|
},
|
|
},
|
|
},
|
|
]
|
|
},
|
|
)
|
|
await knx.receive_write("0/0/1", 1)
|
|
if group_value_options.get("group_value_write", True) and direction_options.get(
|
|
"incoming", True
|
|
):
|
|
assert len(service_calls) == 1
|
|
assert service_calls.pop().data["catch_all"] == "telegram - 0/0/1"
|
|
else:
|
|
assert len(service_calls) == 0
|
|
|
|
await knx.receive_response("0/0/1", 1)
|
|
if group_value_options["group_value_response"] and direction_options.get(
|
|
"incoming", True
|
|
):
|
|
assert len(service_calls) == 1
|
|
assert service_calls.pop().data["catch_all"] == "telegram - 0/0/1"
|
|
else:
|
|
assert len(service_calls) == 0
|
|
|
|
await knx.receive_read("0/0/1")
|
|
if group_value_options["group_value_read"] and direction_options.get(
|
|
"incoming", True
|
|
):
|
|
assert len(service_calls) == 1
|
|
assert service_calls.pop().data["catch_all"] == "telegram - 0/0/1"
|
|
else:
|
|
assert len(service_calls) == 0
|
|
|
|
await hass.services.async_call(
|
|
"knx",
|
|
"send",
|
|
{"address": "0/0/1", "payload": True},
|
|
blocking=True,
|
|
)
|
|
assert len(service_calls) == 1
|
|
|
|
await knx.assert_write("0/0/1", True)
|
|
if (
|
|
group_value_options.get("group_value_write", True)
|
|
and direction_options["outgoing"]
|
|
):
|
|
assert len(service_calls) == 2
|
|
assert service_calls.pop().data["catch_all"] == "telegram - 0/0/1"
|
|
else:
|
|
assert len(service_calls) == 1
|
|
|
|
|
|
async def test_remove_telegram_trigger(
|
|
hass: HomeAssistant,
|
|
service_calls: list[ServiceCall],
|
|
knx: KNXTestKit,
|
|
) -> None:
|
|
"""Test for removed callback when telegram trigger not used."""
|
|
automation_name = "telegram_trigger_automation"
|
|
await knx.setup_integration({})
|
|
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
{
|
|
"alias": automation_name,
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"catch_all": ("telegram - {{ trigger.destination }}")
|
|
},
|
|
},
|
|
}
|
|
]
|
|
},
|
|
)
|
|
|
|
await knx.receive_write("0/0/1", (0x03, 0x2F))
|
|
assert len(service_calls) == 1
|
|
assert service_calls.pop().data["catch_all"] == "telegram - 0/0/1"
|
|
|
|
await hass.services.async_call(
|
|
automation.DOMAIN,
|
|
SERVICE_TURN_OFF,
|
|
{ATTR_ENTITY_ID: f"automation.{automation_name}"},
|
|
blocking=True,
|
|
)
|
|
assert len(service_calls) == 1
|
|
|
|
await knx.receive_write("0/0/1", (0x03, 0x2F))
|
|
assert len(service_calls) == 1
|
|
|
|
|
|
async def test_invalid_trigger(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test invalid telegram trigger configuration."""
|
|
await knx.setup_integration({})
|
|
caplog.clear()
|
|
with caplog.at_level(logging.ERROR):
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
{
|
|
"trigger": {
|
|
"platform": "knx.telegram",
|
|
"invalid": True,
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"catch_all": ("telegram - {{ trigger.destination }}"),
|
|
},
|
|
},
|
|
},
|
|
]
|
|
},
|
|
)
|
|
assert (
|
|
"Unnamed automation failed to setup triggers and has been disabled: "
|
|
"extra keys not allowed @ data['invalid']. Got None"
|
|
in caplog.records[0].message
|
|
)
|