async def async_attach_trigger(hass, config, action, automation_info): """Listen for state changes based on configuration.""" 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) job = HassJob(action) @callback def state_change_listener(event): """Handle specific state changes.""" # Skip if the event's source does not match the trigger's source. from_state = event.data.get("old_state") to_state = event.data.get("new_state") if not source_match(from_state, source) and not source_match( to_state, source): return zone_state = hass.states.get(zone_entity_id) if zone_state is None: _LOGGER.warning( "Unable to execute automation %s: Zone %s not found", automation_info["name"], zone_entity_id, ) return from_match = (condition.zone(hass, zone_state, from_state) if from_state else False) to_match = condition.zone(hass, zone_state, to_state) if to_state else False if (trigger_event == EVENT_ENTER and not from_match and to_match or trigger_event == EVENT_LEAVE and from_match and not to_match): hass.async_run_hass_job( job, { "trigger": { **trigger_data, "platform": "geo_location", "source": source, "entity_id": event.data.get("entity_id"), "from_state": from_state, "to_state": to_state, "zone": zone_state, "event": trigger_event, "description": f"geo_location - {source}", } }, event.context, ) return async_track_state_change_filtered( hass, TrackStates(False, set(), {DOMAIN}), state_change_listener).async_remove
return from_match = (condition.zone(hass, zone_state, from_state) if from_state else False) to_match = condition.zone(hass, zone_state, to_state) if to_state else False if (trigger_event == EVENT_ENTER and not from_match and to_match or trigger_event == EVENT_LEAVE and from_match and not to_match): hass.async_run_hass_job( job, { "trigger": { **trigger_data, "platform": "geo_location", "source": source, "entity_id": event.data.get("entity_id"), "from_state": from_state, "to_state": to_state, "zone": zone_state, "event": trigger_event, "description": f"geo_location - {source}", } }, event.context, ) return async_track_state_change_filtered( hass, TrackStates(False, set(), {DOMAIN}), state_change_listener).async_remove