} SUBTYPES = { EVENT_TYPE_THERM_MODE: [ STATE_NETATMO_SCHEDULE, STATE_NETATMO_HG, STATE_NETATMO_AWAY, ] } TRIGGER_TYPES = OUTDOOR_CAMERA_TRIGGERS + INDOOR_CAMERA_TRIGGERS + CLIMATE_TRIGGERS TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), vol.Optional(CONF_SUBTYPE): str, }) async def async_validate_trigger_config(hass, config): """Validate config.""" config = TRIGGER_SCHEMA(config) device_registry = await hass.helpers.device_registry.async_get_registry() device = device_registry.async_get(config[CONF_DEVICE_ID]) trigger = config[CONF_TYPE] if (not device or device.model not in DEVICES
CONF_TYPE, PERCENTAGE, ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.helpers import config_validation as cv, entity_registry from homeassistant.helpers.typing import ConfigType from . import DOMAIN TARGET_TRIGGER_SCHEMA = vol.All( TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): "target_humidity_changed", vol.Optional(CONF_BELOW): vol.Any(vol.Coerce(int)), vol.Optional(CONF_ABOVE): vol.Any(vol.Coerce(int)), vol.Optional(CONF_FOR): cv.positive_time_period_dict, }), cv.has_at_least_one_key(CONF_BELOW, CONF_ABOVE), ) TOGGLE_TRIGGER_SCHEMA = toggle_entity.TRIGGER_SCHEMA.extend( {vol.Required(CONF_DOMAIN): DOMAIN}) TRIGGER_SCHEMA = vol.Any(TARGET_TRIGGER_SCHEMA, TOGGLE_TRIGGER_SCHEMA) async def async_get_triggers(hass: HomeAssistant,
from .const import ( ATTR_CHANNEL, ATTR_CLICK_TYPE, CONF_SUBTYPE, DOMAIN, EVENT_SHELLY_CLICK, INPUTS_EVENTS_SUBTYPES, SHBTN_1_INPUTS_EVENTS_TYPES, SUPPORTED_INPUTS_EVENTS_TYPES, ) from .utils import get_device_wrapper, get_input_triggers TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_TYPE): vol.In(SUPPORTED_INPUTS_EVENTS_TYPES), vol.Required(CONF_SUBTYPE): vol.In(INPUTS_EVENTS_SUBTYPES), } ) async def async_validate_trigger_config(hass, config): """Validate config.""" config = TRIGGER_SCHEMA(config) # if device is available verify parameters against device capabilities wrapper = get_device_wrapper(hass, config[CONF_DEVICE_ID]) if not wrapper or not wrapper.device.initialized: return config trigger = (config[CONF_TYPE], config[CONF_SUBTYPE])
CONF_SUBTYPE = "subtype" CONF_TOPIC = "topic" DEFAULT_ENCODING = "utf-8" DEVICE = "device" MQTT_TRIGGER_BASE = { # Trigger when MQTT message is received CONF_PLATFORM: DEVICE, CONF_DOMAIN: DOMAIN, } TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_PLATFORM): DEVICE, vol.Required(CONF_DOMAIN): DOMAIN, vol.Required(CONF_DEVICE_ID): str, vol.Required(CONF_DISCOVERY_ID): str, vol.Required(CONF_TYPE): cv.string, vol.Required(CONF_SUBTYPE): cv.string, } ) TRIGGER_DISCOVERY_SCHEMA =zj2m.MQTT_BASE_PLATFORM_SCHEMA.extend( { vol.Required(CONF_AUTOMATION_TYPE): str, vol.Required(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA, vol.Required(CONF_TOPIC):zj2m.valid_subscribe_topic, vol.Optional(CONF_PAYLOAD, default=None): vol.Any(None, cv.string), vol.Required(CONF_TYPE): cv.string, vol.Required(CONF_SUBTYPE): cv.string, }, validate_device_has_at_least_one_identifier,
TRIGGER_SCHEMA = vol.All( TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In([ CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_ILLUMINANCE, CONF_POWER, CONF_PRESSURE, CONF_SIGNAL_STRENGTH, CONF_TEMPERATURE, CONF_TIMESTAMP, CONF_VALUE, ]), vol.Optional(CONF_BELOW): vol.Any(vol.Coerce(float)), vol.Optional(CONF_ABOVE): vol.Any(vol.Coerce(float)), vol.Optional(CONF_FOR): vol.Any( vol.All(cv.time_period, cv.positive_timedelta), cv.template, cv.template_complex, ), vol.Optional(CONF_FOR): cv.positive_time_period_dict, }), cv.has_at_least_one_key(CONF_BELOW, CONF_ABOVE), )
"button4", "button5", "button6", "button7", "button8", "button9", "button10", } TRIGGER_SUBTYPES = {"single_press", "double_press", "long_press"} CONF_IID = "iid" CONF_SUBTYPE = "subtype" TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), vol.Required(CONF_SUBTYPE): vol.In(TRIGGER_SUBTYPES), }) HK_TO_HA_INPUT_EVENT_VALUES = { InputEventValues.SINGLE_PRESS: "single_press", InputEventValues.DOUBLE_PRESS: "double_press", InputEventValues.LONG_PRESS: "long_press", } class TriggerSource: """Represents a stateless source of event data from HomeKit.""" def __init__(self, connection, aid, triggers): """Initialize a set of triggers for a device.""" self._hass = connection.hass
"""Offer device oriented automation.""" import voluptuous as vol from homeassistant.components.device_automation import ( TRIGGER_BASE_SCHEMA, async_get_device_automation_platform, ) from homeassistant.const import CONF_DOMAIN # mypy: allow-untyped-defs, no-check-untyped-defs TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA) async def async_validate_trigger_config(hass, config): """Validate config.""" platform = await async_get_device_automation_platform( hass, config[CONF_DOMAIN], "trigger") return platform.TRIGGER_SCHEMA(config) async def async_attach_trigger(hass, config, action, automation_info): """Listen for trigger.""" platform = await async_get_device_automation_platform( hass, config[CONF_DOMAIN], "trigger") return await platform.async_attach_trigger(hass, config, action, automation_info)
from .const import ( ACTION_PRESS, ACTION_RELEASE, ATTR_ACTION, ATTR_BUTTON_NUMBER, ATTR_SERIAL, BUTTON_DEVICES, CONF_SUBTYPE, DOMAIN, LUTRON_CASETA_BUTTON_EVENT, ) SUPPORTED_INPUTS_EVENTS_TYPES = [ACTION_PRESS, ACTION_RELEASE] LUTRON_BUTTON_TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_TYPE): vol.In(SUPPORTED_INPUTS_EVENTS_TYPES), }) PICO_2_BUTTON_BUTTON_TYPES = { "on": 2, "off": 4, } PICO_2_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend({ vol.Required(CONF_SUBTYPE): vol.In(PICO_2_BUTTON_BUTTON_TYPES), }) PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES = { "on": 2, "off": 4, "raise": 5,
from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.helpers import config_validation as cv, entity_registry from homeassistant.helpers.typing import ConfigType from . import DOMAIN, const TRIGGER_TYPES = { "current_temperature_changed", "current_humidity_changed", "hvac_mode_changed", } HVAC_MODE_TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): "hvac_mode_changed", vol.Required(state_trigger.CONF_TO): vol.In(const.HVAC_MODES), }) CURRENT_TRIGGER_SCHEMA = vol.All( TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(["current_temperature_changed", "current_humidity_changed"]), vol.Optional(CONF_BELOW): vol.Any(vol.Coerce(float)), vol.Optional(CONF_ABOVE): vol.Any(vol.Coerce(float)), vol.Optional(CONF_FOR):
DOMAIN, SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_SET_POSITION, SUPPORT_SET_TILT_POSITION, ) POSITION_TRIGGER_TYPES = {"position", "tilt_position"} STATE_TRIGGER_TYPES = {"opened", "closed", "opening", "closing"} POSITION_TRIGGER_SCHEMA = vol.All( TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(POSITION_TRIGGER_TYPES), vol.Optional(CONF_ABOVE): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)), vol.Optional(CONF_BELOW): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)), }), cv.has_at_least_one_key(CONF_BELOW, CONF_ABOVE), ) STATE_TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(STATE_TRIGGER_TYPES), vol.Optional(CONF_FOR): cv.positive_time_period_dict, })
DEVICE_CLASS_SAFETY: [{CONF_TYPE: CONF_UNSAFE}, {CONF_TYPE: CONF_NOT_UNSAFE}], DEVICE_CLASS_SMOKE: [{CONF_TYPE: CONF_SMOKE}, {CONF_TYPE: CONF_NO_SMOKE}], DEVICE_CLASS_SOUND: [{CONF_TYPE: CONF_SOUND}, {CONF_TYPE: CONF_NO_SOUND}], DEVICE_CLASS_VIBRATION: [ {CONF_TYPE: CONF_VIBRATION}, {CONF_TYPE: CONF_NO_VIBRATION}, ], DEVICE_CLASS_WINDOW: [{CONF_TYPE: CONF_OPENED}, {CONF_TYPE: CONF_NOT_OPENED}], DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_TURNED_ON}, {CONF_TYPE: CONF_TURNED_OFF}], } TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(TURNED_OFF + TURNED_ON), vol.Optional(CONF_FOR): cv.positive_time_period_dict, } ) async def async_attach_trigger(hass, config, action, automation_info): """Listen for state changes based on configuration.""" trigger_type = config[CONF_TYPE] if trigger_type in TURNED_ON: from_state = "off" to_state = "on" else: from_state = "on" to_state = "off"
from homeassistant.components.automation import AutomationActionType from homeassistant.components.device_automation import TRIGGER_BASE_SCHEMA from homeassistant.components.homeassistant.triggers import state as state_trigger from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from .utils import async_get_device_entries from .const import DOMAIN NEW_VOD = "new_vod" TRIGGER_TYPES = {NEW_VOD} TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), vol.Optional(CONF_ENTITY_ID): cv.entity_domain(SENSOR_DOMAIN), } ) _LOGGER = logging.getLogger(__name__) async def async_get_triggers(hass: HomeAssistant, device_id: str): """ List of device triggers """ (device, device_entries) = await async_get_device_entries(hass, device_id) triggers = [] if not device or not device_entries or len(device_entries) < 1: return triggers
import voluptuous as vol from homeassistant.components.device_automation import TRIGGER_BASE_SCHEMA from homeassistant.components.homeassistant.triggers import \ state as state_trigger from homeassistant.const import * from homeassistant.helpers import config_validation as cv from homeassistant.helpers.device_registry import DeviceEntry from . import DOMAIN from .core import zigbee from .sensor import BUTTON TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_TYPE): cv.string, vol.Required('action'): cv.string } ) async def async_attach_trigger(hass, config, action, automation_info): entity_registry = await hass.helpers.entity_registry.async_get_registry() device_id = config[CONF_DEVICE_ID] entry = next(( entry for entry in entity_registry.entities.values() if entry.device_id == device_id and entry.unique_id.endswith('action') ), None) if not entry: return None
AQARA_DOUBLE_WALL_SWITCH_MODEL: AQARA_DOUBLE_WALL_SWITCH, AQARA_DOUBLE_WALL_SWITCH_MODEL_2020: AQARA_DOUBLE_WALL_SWITCH, AQARA_DOUBLE_WALL_SWITCH_WXKG02LM_MODEL: AQARA_DOUBLE_WALL_SWITCH_WXKG02LM, AQARA_SINGLE_WALL_SWITCH_WXKG03LM_MODEL: AQARA_SINGLE_WALL_SWITCH, AQARA_SINGLE_WALL_SWITCH_WXKG06LM_MODEL: AQARA_SINGLE_WALL_SWITCH, AQARA_MINI_SWITCH_MODEL: AQARA_MINI_SWITCH, AQARA_ROUND_SWITCH_MODEL: AQARA_ROUND_SWITCH, AQARA_SQUARE_SWITCH_MODEL: AQARA_SQUARE_SWITCH, AQARA_SQUARE_SWITCH_WXKG11LM_2016_MODEL: AQARA_SQUARE_SWITCH_WXKG11LM_2016, AQARA_OPPLE_2_BUTTONS_MODEL: AQARA_OPPLE_2_BUTTONS, AQARA_OPPLE_4_BUTTONS_MODEL: AQARA_OPPLE_4_BUTTONS, AQARA_OPPLE_6_BUTTONS_MODEL: AQARA_OPPLE_6_BUTTONS, } TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( {vol.Required(CONF_TYPE): str, vol.Required(CONF_SUBTYPE): str} ) def _get_deconz_event_from_device_id(hass, device_id): """Resolve deconz event from device id.""" for gateway in hass.data.get(DOMAIN, {}).values(): for deconz_event in gateway.events: if device_id == deconz_event.device_id: return deconz_event return None
DEVICE_CLASS_PROBLEM: [{CONF_TYPE: CONF_PROBLEM}, {CONF_TYPE: CONF_NO_PROBLEM}], DEVICE_CLASS_SAFETY: [{CONF_TYPE: CONF_UNSAFE}, {CONF_TYPE: CONF_NOT_UNSAFE}], DEVICE_CLASS_SMOKE: [{CONF_TYPE: CONF_SMOKE}, {CONF_TYPE: CONF_NO_SMOKE}], DEVICE_CLASS_SOUND: [{CONF_TYPE: CONF_SOUND}, {CONF_TYPE: CONF_NO_SOUND}], DEVICE_CLASS_VIBRATION: [ {CONF_TYPE: CONF_VIBRATION}, {CONF_TYPE: CONF_NO_VIBRATION}, ], DEVICE_CLASS_WINDOW: [{CONF_TYPE: CONF_OPEN}, {CONF_TYPE: CONF_NOT_OPEN}], DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_TURNED_ON}, {CONF_TYPE: CONF_TURNED_OFF}], } TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(TURNED_OFF + TURNED_ON), } ) async def async_attach_trigger(hass, config, action, automation_info): """Listen for state changes based on configuration.""" config = TRIGGER_SCHEMA(config) trigger_type = config[CONF_TYPE] if trigger_type in TURNED_ON: from_state = "off" to_state = "on" else: from_state = "on" to_state = "off"
CONF_PLATFORM, CONF_TYPE, CONF_ZONE, ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant from homeassistant.helpers import config_validation as cv, entity_registry from homeassistant.helpers.typing import ConfigType from . import DOMAIN TRIGGER_TYPES = {"enters", "leaves"} TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend( { vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), vol.Required(CONF_ZONE): cv.entity_domain(DOMAIN_ZONE), } ) async def async_get_triggers(hass: HomeAssistant, device_id: str) -> list[dict]: """List device triggers for Device Tracker devices.""" registry = await entity_registry.async_get_registry(hass) triggers = [] # Get all the integrations entities for this device for entry in entity_registry.async_entries_for_device(registry, device_id): if entry.domain != DOMAIN: continue
TRIGGER_SCHEMA = vol.All( TRIGGER_BASE_SCHEMA.extend({ vol.Required(CONF_ENTITY_ID): cv.entity_id, vol.Required(CONF_TYPE): vol.In([ CONF_BATTERY_LEVEL, CONF_CO, CONF_CO2, CONF_CURRENT, CONF_ENERGY, CONF_HUMIDITY, CONF_ILLUMINANCE, CONF_POWER, CONF_POWER_FACTOR, CONF_PRESSURE, CONF_SIGNAL_STRENGTH, CONF_TEMPERATURE, CONF_VOLTAGE, CONF_VALUE, ]), vol.Optional(CONF_BELOW): vol.Any(vol.Coerce(float)), vol.Optional(CONF_ABOVE): vol.Any(vol.Coerce(float)), vol.Optional(CONF_FOR): cv.positive_time_period_dict, }), cv.has_at_least_one_key(CONF_BELOW, CONF_ABOVE), )