From f7e9215f5e12343986ea198c232026d307a7e4b6 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 28 Feb 2018 13:39:01 -0800 Subject: [PATCH] Fix when 2 states match with same name (#12771) --- homeassistant/helpers/intent.py | 13 +++++++------ tests/helpers/test_intent.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 tests/helpers/test_intent.py diff --git a/homeassistant/helpers/intent.py b/homeassistant/helpers/intent.py index 26c2bca34c7..dac0f4c507b 100644 --- a/homeassistant/helpers/intent.py +++ b/homeassistant/helpers/intent.py @@ -97,12 +97,12 @@ def async_match_state(hass, name, states=None): if states is None: states = hass.states.async_all() - entity = _fuzzymatch(name, states, lambda state: state.name) + state = _fuzzymatch(name, states, lambda state: state.name) - if entity is None: + if state is None: raise IntentHandleError('Unable to find entity {}'.format(name)) - return entity + return state @callback @@ -154,12 +154,13 @@ def _fuzzymatch(name, items, key): matches = [] pattern = '.*?'.join(name) regex = re.compile(pattern, re.IGNORECASE) - for item in items: + for idx, item in enumerate(items): match = regex.search(key(item)) if match: - matches.append((len(match.group()), match.start(), item)) + # Add index so we pick first match in case same group and start + matches.append((len(match.group()), match.start(), idx, item)) - return sorted(matches)[0][2] if matches else None + return sorted(matches)[0][3] if matches else None class ServiceIntentHandler(IntentHandler): diff --git a/tests/helpers/test_intent.py b/tests/helpers/test_intent.py new file mode 100644 index 00000000000..a8d37a249bc --- /dev/null +++ b/tests/helpers/test_intent.py @@ -0,0 +1,12 @@ +"""Tests for the intent helpers.""" +from homeassistant.core import State +from homeassistant.helpers import intent + + +def test_async_match_state(): + """Test async_match_state helper.""" + state1 = State('light.kitchen', 'on') + state2 = State('switch.kitchen', 'on') + + state = intent.async_match_state(None, 'kitch', [state1, state2]) + assert state is state1