Automation trigger info type hint improvements (#55402)

* Make automation trigger info a TypedDict

* zwave_js trigger type hint fixes

* Remove redundant automation trigger info field presence checks

* Use async_initialize_triggers in mqtt and tasmota device_trigger tests
This commit is contained in:
Ville Skyttä 2021-09-04 03:25:51 +03:00 committed by GitHub
parent 0749e045bb
commit b10fc89a6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 344 additions and 210 deletions

View file

@ -11,7 +11,10 @@ from homeassistant.components.alarm_control_panel.const import (
SUPPORT_ALARM_ARM_NIGHT,
SUPPORT_ALARM_ARM_VACATION,
)
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import state as state_trigger
from homeassistant.const import (
@ -129,7 +132,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "triggered":

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -57,10 +60,10 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
job = HassJob(action)
if config[CONF_TYPE] == "turn_on":

View file

@ -2,7 +2,7 @@
from __future__ import annotations
import logging
from typing import Any, Awaitable, Callable, Dict, cast
from typing import Any, Awaitable, Callable, Dict, TypedDict, cast
import voluptuous as vol
from voluptuous.humanize import humanize_error
@ -106,6 +106,23 @@ _LOGGER = logging.getLogger(__name__)
AutomationActionType = Callable[[HomeAssistant, TemplateVarsType], Awaitable[None]]
class AutomationTriggerData(TypedDict):
"""Automation trigger data."""
id: str
idx: str
class AutomationTriggerInfo(TypedDict):
"""Information about automation trigger."""
domain: str
name: str
home_assistant_start: bool
variables: TemplateVarsType
trigger_data: AutomationTriggerData
@bind_hass
def is_on(hass, entity_id):
"""

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import (
numeric_state as numeric_state_trigger,
@ -112,7 +115,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
trigger_type = config[CONF_TYPE]

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import (
numeric_state as numeric_state_trigger,
@ -147,7 +150,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] in STATE_TRIGGER_TYPES:

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation.const import (
CONF_IS_OFF,
CONF_IS_ON,
@ -146,7 +149,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
trigger_type = config[CONF_TYPE]

View file

@ -5,7 +5,10 @@ from typing import Any, Final
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.zone import DOMAIN as DOMAIN_ZONE, trigger as zone
from homeassistant.const import (
@ -72,7 +75,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "enters":

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import toggle_entity
from homeassistant.const import CONF_DOMAIN
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
@ -36,7 +39,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
return await toggle_entity.async_attach_trigger(

View file

@ -37,7 +37,7 @@ def source_match(state, source):
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
source = config.get(CONF_SOURCE).lower()
zone_entity_id = config.get(CONF_ZONE)
trigger_event = config.get(CONF_EVENT)

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.const import CONF_EVENT_DATA, CONF_PLATFORM
from homeassistant.core import CALLBACK_TYPE, Event, HassJob, HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, template
@ -35,15 +38,13 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict[str, Any],
automation_info: AutomationTriggerInfo,
*,
platform_type: str = "event",
) -> CALLBACK_TYPE:
"""Listen for events based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
variables = None
if automation_info:
variables = automation_info.get("variables")
trigger_data = automation_info["trigger_data"]
variables = automation_info["variables"]
template.attach(hass, config[CONF_EVENT_TYPE])
event_types = template.render_complex(

View file

@ -20,7 +20,7 @@ TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for events based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
event = config.get(CONF_EVENT)
job = HassJob(action)

View file

@ -78,10 +78,8 @@ async def async_attach_trigger(
attribute = config.get(CONF_ATTRIBUTE)
job = HassJob(action)
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
_variables: dict = {}
if automation_info:
_variables = automation_info.get("variables") or {}
trigger_data = automation_info["trigger_data"]
_variables = automation_info["variables"] or {}
if value_template is not None:
value_template.hass = hass

View file

@ -87,10 +87,8 @@ async def async_attach_trigger(
attribute = config.get(CONF_ATTRIBUTE)
job = HassJob(action)
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
_variables: dict = {}
if automation_info:
_variables = automation_info.get("variables") or {}
trigger_data = automation_info["trigger_data"]
_variables = automation_info["variables"] or {}
@callback
def state_automation_listener(event: Event):

View file

@ -39,7 +39,7 @@ TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
entities = {}
removes = []
job = HassJob(action)

View file

@ -57,7 +57,7 @@ TRIGGER_SCHEMA = vol.All(
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
hours = config.get(CONF_HOURS)
minutes = config.get(CONF_MINUTES)
seconds = config.get(CONF_SECONDS)

View file

@ -9,7 +9,10 @@ from aiohomekit.model.services import ServicesTypes
from aiohomekit.utils import clamp_enum_to_char
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
@ -75,12 +78,10 @@ class TriggerSource:
self,
config: TRIGGER_SCHEMA,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
trigger_data = (
automation_info.get("trigger_data", {}) if automation_info else {}
)
trigger_data = automation_info["trigger_data"]
def event_handler(char):
if config[CONF_SUBTYPE] != HK_TO_HA_INPUT_EVENT_VALUES[char["value"]]:
@ -260,7 +261,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
device_id = config[CONF_DEVICE_ID]

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import (
DEVICE_TRIGGER_BASE_SCHEMA,
toggle_entity,
@ -80,7 +83,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
trigger_type = config[CONF_TYPE]

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -69,9 +72,9 @@ def _attach_trigger(
config: ConfigType,
action: AutomationActionType,
event_type,
automation_info: dict,
automation_info: AutomationTriggerInfo,
):
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
job = HassJob(action)
@callback
@ -90,7 +93,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "turn_on":

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import toggle_entity
from homeassistant.const import CONF_DOMAIN
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
@ -22,7 +25,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
return await toggle_entity.async_attach_trigger(

View file

@ -31,7 +31,7 @@ TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for events based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
number = config.get(CONF_NUMBER)
held_more_than = config.get(CONF_HELD_MORE_THAN)
held_less_than = config.get(CONF_HELD_LESS_THAN)

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import state as state_trigger
from homeassistant.const import (
@ -80,7 +83,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "jammed":

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
@ -258,7 +261,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
device = get_button_device_by_dr_id(hass, config[CONF_DEVICE_ID])

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import state as state_trigger
from homeassistant.const import (
@ -80,7 +83,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "turned_on":

View file

@ -7,7 +7,10 @@ from typing import Any, Callable
import attr
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.const import (
CONF_DEVICE,
@ -86,7 +89,7 @@ class TriggerInstance:
"""Attached trigger settings."""
action: AutomationActionType = attr.ib()
automation_info: dict = attr.ib()
automation_info: AutomationTriggerInfo = attr.ib()
trigger: Trigger = attr.ib()
remove: CALLBACK_TYPE | None = attr.ib(default=None)
@ -316,7 +319,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if DEVICE_TRIGGERS not in hass.data:

View file

@ -37,7 +37,7 @@ _LOGGER = logging.getLogger(__name__)
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
topic = config[CONF_TOPIC]
wanted_payload = config.get(CONF_PAYLOAD)
value_template = config.get(CONF_VALUE_TEMPLATE)

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
@ -87,7 +90,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
event_config = event_trigger.TRIGGER_SCHEMA(

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
@ -128,7 +131,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
device_registry = await hass.helpers.device_registry.async_get_registry()

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.const import CONF_DEVICE_ID, CONF_DOMAIN, CONF_PLATFORM, CONF_TYPE
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
@ -46,10 +49,10 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE | None:
"""Attach a trigger."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
registry: DeviceRegistry = await async_get_registry(hass)
if config[CONF_TYPE] == TRIGGER_TYPE_TURN_ON:
variables = {

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import toggle_entity
from homeassistant.const import CONF_DOMAIN
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
@ -22,7 +25,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
return await toggle_entity.async_attach_trigger(

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers.state import (
CONF_FOR,
@ -64,7 +67,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
state_config = {

View file

@ -5,7 +5,10 @@ from typing import Any, Final
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
@ -111,7 +114,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
event_config = {

View file

@ -26,7 +26,7 @@ TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
async def async_attach_trigger(hass, config, action, automation_info):
"""Listen for events based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
event = config.get(CONF_EVENT)
offset = config.get(CONF_OFFSET)
description = event

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import toggle_entity
from homeassistant.const import CONF_DOMAIN
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
@ -22,7 +25,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
return await toggle_entity.async_attach_trigger(

View file

@ -1,7 +1,10 @@
"""Support for tag triggers."""
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.const import CONF_PLATFORM
from homeassistant.core import CALLBACK_TYPE, Event, HassJob, HomeAssistant
from homeassistant.helpers import config_validation as cv
@ -22,10 +25,10 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Listen for tag_scanned events based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
tag_ids = set(config[TAG_ID])
device_ids = set(config[DEVICE_ID]) if DEVICE_ID in config else None

View file

@ -9,7 +9,10 @@ from hatasmota.models import DiscoveryHashType
from hatasmota.trigger import TasmotaTrigger, TasmotaTriggerConfig
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import event as event_trigger
from homeassistant.config_entries import ConfigEntry
@ -49,7 +52,7 @@ class TriggerInstance:
"""Attached trigger settings."""
action: AutomationActionType = attr.ib()
automation_info: dict = attr.ib()
automation_info: AutomationTriggerInfo = attr.ib()
trigger: Trigger = attr.ib()
remove: CALLBACK_TYPE | None = attr.ib(default=None)
@ -93,7 +96,7 @@ class Trigger:
trigger_instances: list[TriggerInstance] = attr.ib(factory=list)
async def add_trigger(
self, action: AutomationActionType, automation_info: dict
self, action: AutomationActionType, automation_info: AutomationTriggerInfo
) -> Callable[[], None]:
"""Add Tasmota trigger."""
instance = TriggerInstance(action, automation_info, self)
@ -289,7 +292,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: Callable,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a device trigger."""
if DEVICE_TRIGGERS not in hass.data:

View file

@ -31,7 +31,7 @@ async def async_attach_trigger(
hass, config, action, automation_info, *, platform_type="template"
):
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
value_template = config.get(CONF_VALUE_TEMPLATE)
value_template.hass = hass
time_delta = config.get(CONF_FOR)

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import state as state_trigger
from homeassistant.const import (
@ -74,7 +77,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "cleaning":

View file

@ -37,7 +37,7 @@ async def _handle_webhook(job, trigger_data, hass, webhook_id, request):
async def async_attach_trigger(hass, config, action, automation_info):
"""Trigger based on incoming webhooks."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
webhook_id = config.get(CONF_WEBHOOK_ID)
job = HassJob(action)
hass.components.webhook.async_register(

View file

@ -37,7 +37,7 @@ async def async_attach_trigger(
hass, config, action, automation_info, *, platform_type: str = "zone"
) -> CALLBACK_TYPE:
"""Listen for state changes based on configuration."""
trigger_data = automation_info.get("trigger_data", {}) if automation_info else {}
trigger_data = automation_info["trigger_data"]
entity_id = config.get(CONF_ENTITY_ID)
zone_entity_id = config.get(CONF_ZONE)
event = config.get(CONF_EVENT)

View file

@ -6,7 +6,10 @@ from typing import Any
import voluptuous as vol
from zwave_js_server.const import CommandClass
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
@ -358,7 +361,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
trigger_type = config[CONF_TYPE]

View file

@ -2,10 +2,14 @@
from __future__ import annotations
from types import ModuleType
from typing import Any, Callable, cast
from typing import cast
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.const import CONF_PLATFORM
from homeassistant.core import HomeAssistant
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
from homeassistant.helpers.typing import ConfigType
from .triggers import value_updated
@ -40,14 +44,14 @@ async def async_validate_trigger_config(
async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: Callable,
automation_info: dict[str, Any],
) -> Callable:
action: AutomationActionType,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach trigger of specified platform."""
platform = _get_trigger_platform(config)
assert hasattr(platform, "async_attach_trigger")
return cast(
Callable,
CALLBACK_TYPE,
await getattr(platform, "async_attach_trigger")(
hass, config, action, automation_info
),

View file

@ -3,7 +3,6 @@ from __future__ import annotations
import functools
import logging
from typing import Any, Callable
import voluptuous as vol
from zwave_js_server.const import CommandClass
@ -11,6 +10,10 @@ from zwave_js_server.event import Event
from zwave_js_server.model.node import Node
from zwave_js_server.model.value import Value, get_value_id
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.zwave_js.const import (
ATTR_COMMAND_CLASS,
ATTR_COMMAND_CLASS_NAME,
@ -79,8 +82,8 @@ TRIGGER_SCHEMA = vol.All(
async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: Callable,
automation_info: dict[str, Any],
action: AutomationActionType,
automation_info: AutomationTriggerInfo,
*,
platform_type: str = PLATFORM_TYPE,
) -> CALLBACK_TYPE:
@ -110,9 +113,7 @@ async def async_attach_trigger(
unsubs = []
job = HassJob(action)
trigger_data: dict = {}
if automation_info:
trigger_data = automation_info.get("trigger_data", {})
trigger_data = automation_info["trigger_data"]
@callback
def async_on_value_updated(

View file

@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio
import logging
from types import MappingProxyType
from typing import Any, Callable
import voluptuous as vol
@ -11,7 +10,7 @@ import voluptuous as vol
from homeassistant.const import CONF_ID, CONF_PLATFORM
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
from homeassistant.loader import IntegrationNotFound, async_get_integration
_PLATFORM_ALIASES = {
@ -62,15 +61,9 @@ async def async_initialize_triggers(
name: str,
log_cb: Callable,
home_assistant_start: bool = False,
variables: dict[str, Any] | MappingProxyType | None = None,
variables: TemplateVarsType = None,
) -> CALLBACK_TYPE | None:
"""Initialize triggers."""
info = {
"domain": domain,
"name": name,
"home_assistant_start": home_assistant_start,
"variables": variables,
}
triggers = []
for idx, conf in enumerate(trigger_config):
@ -78,7 +71,13 @@ async def async_initialize_triggers(
trigger_id = conf.get(CONF_ID, f"{idx}")
trigger_idx = f"{idx}"
trigger_data = {"id": trigger_id, "idx": trigger_idx}
info = {**info, "trigger_data": trigger_data}
info = {
"domain": domain,
"name": name,
"home_assistant_start": home_assistant_start,
"variables": variables,
"trigger_data": trigger_data,
}
triggers.append(platform.async_attach_trigger(hass, conf, action, info))
attach_results = await asyncio.gather(*triggers, return_exceptions=True)

View file

@ -5,7 +5,10 @@ from typing import Any
import voluptuous as vol
from homeassistant.components.automation import AutomationActionType
from homeassistant.components.automation import (
AutomationActionType,
AutomationTriggerInfo,
)
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
from homeassistant.components.homeassistant.triggers import state
from homeassistant.const import (
@ -71,7 +74,7 @@ async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: AutomationActionType,
automation_info: dict,
automation_info: AutomationTriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
# TODO Implement your own logic to attach triggers.

View file

@ -4,9 +4,9 @@ import json
import pytest
import homeassistant.components.automation as automation
from homeassistant.components.mqtt import DOMAIN, debug_info
from homeassistant.components.mqtt.device_trigger import async_attach_trigger
from homeassistant.components.mqtt import _LOGGER, DOMAIN, debug_info
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.trigger import async_initialize_triggers
from homeassistant.setup import async_setup_component
from tests.common import (
@ -697,18 +697,22 @@ async def test_attach_remove(hass, device_reg, mqtt_mock):
def callback(trigger):
calls.append(trigger["trigger"]["payload"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Fake short press.
@ -751,18 +755,22 @@ async def test_attach_remove_late(hass, device_reg, mqtt_mock):
def callback(trigger):
calls.append(trigger["trigger"]["payload"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data1)
@ -808,18 +816,22 @@ async def test_attach_remove_late2(hass, device_reg, mqtt_mock):
def callback(trigger):
calls.append(trigger["trigger"]["payload"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "bla1",
"type": "button_short_press",
"subtype": "button_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Remove the trigger

View file

@ -1,15 +1,16 @@
"""The tests for MQTT device triggers."""
"""The tests for Tasmota device triggers."""
import copy
import json
from unittest.mock import patch
from unittest.mock import Mock, patch
from hatasmota.switch import TasmotaSwitchTriggerConfig
import pytest
import homeassistant.components.automation as automation
from homeassistant.components.tasmota import _LOGGER
from homeassistant.components.tasmota.const import DEFAULT_PREFIX, DOMAIN
from homeassistant.components.tasmota.device_trigger import async_attach_trigger
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.trigger import async_initialize_triggers
from homeassistant.setup import async_setup_component
from .test_common import DEFAULT_CONFIG
@ -812,18 +813,22 @@ async def test_attach_remove(hass, device_reg, mqtt_mock, setup_tasmota):
def callback(trigger, context):
calls.append(trigger["trigger"]["description"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Fake short press.
@ -869,18 +874,22 @@ async def test_attach_remove_late(hass, device_reg, mqtt_mock, setup_tasmota):
def callback(trigger, context):
calls.append(trigger["trigger"]["description"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Fake short press.
@ -936,18 +945,22 @@ async def test_attach_remove_late2(hass, device_reg, mqtt_mock, setup_tasmota):
def callback(trigger, context):
calls.append(trigger["trigger"]["description"])
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Remove the trigger
@ -979,18 +992,22 @@ async def test_attach_remove_unknown1(hass, device_reg, mqtt_mock, setup_tasmota
set(), {(dr.CONNECTION_NETWORK_MAC, mac)}
)
remove = await async_attach_trigger(
remove = await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
None,
None,
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
Mock(),
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Remove the trigger
@ -1023,18 +1040,22 @@ async def test_attach_unknown_remove_device_from_registry(
set(), {(dr.CONNECTION_NETWORK_MAC, mac)}
)
await async_attach_trigger(
await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
None,
None,
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
Mock(),
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Remove the device
@ -1063,18 +1084,22 @@ async def test_attach_remove_config_entry(hass, device_reg, mqtt_mock, setup_tas
def callback(trigger, context):
calls.append(trigger["trigger"]["description"])
await async_attach_trigger(
await async_initialize_triggers(
hass,
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
[
{
"platform": "device",
"domain": DOMAIN,
"device_id": device_entry.id,
"discovery_id": "00000049A3BC_switch_1_TOGGLE",
"type": "button_short_press",
"subtype": "switch_1",
},
],
callback,
None,
DOMAIN,
"mock-name",
_LOGGER.log,
)
# Fake short press.