diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index fb9626ac6e2..07975d26adc 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -15,8 +15,8 @@ from .const import ATTR_DISCOVERY_HASH, CONF_STATE_TOPIC _LOGGER = logging.getLogger(__name__) TOPIC_MATCHER = re.compile( - r'(?P\w+)/(?P\w+)/' - r'(?:(?P[a-zA-Z0-9_-]+)/)?(?P[a-zA-Z0-9_-]+)/config') + r'(?P\w+)/(?:(?P[a-zA-Z0-9_-]+)/)' + r'?(?P[a-zA-Z0-9_-]+)/config') SUPPORTED_COMPONENTS = [ 'alarm_control_panel', @@ -233,12 +233,13 @@ async def async_start(hass: HomeAssistantType, discovery_topic, hass_config, """Process the received message.""" payload = msg.payload topic = msg.topic - match = TOPIC_MATCHER.match(topic) + topic_trimmed = topic.replace('{}/'.format(discovery_topic), '', 1) + match = TOPIC_MATCHER.match(topic_trimmed) if not match: return - _prefix_topic, component, node_id, object_id = match.groups() + component, node_id, object_id = match.groups() if component not in SUPPORTED_COMPONENTS: _LOGGER.warning("Component %s is not supported", component) diff --git a/tests/components/mqtt/test_discovery.py b/tests/components/mqtt/test_discovery.py index 42513a2e900..99c90a15de1 100644 --- a/tests/components/mqtt/test_discovery.py +++ b/tests/components/mqtt/test_discovery.py @@ -369,3 +369,21 @@ async def test_no_implicit_state_topic_switch(hass, mqtt_mock, caplog): state = hass.states.get('switch.Test1') assert state.state == 'off' + + +async def test_complex_discovery_topic_prefix(hass, mqtt_mock, caplog): + """Tests handling of discovery topic prefix with multiple slashes.""" + entry = MockConfigEntry(domain=mqtt.DOMAIN) + + await async_start(hass, 'my_home/homeassistant/register', {}, entry) + + async_fire_mqtt_message(hass, ('my_home/homeassistant/register' + '/binary_sensor/node1/object1/config'), + '{ "name": "Beer" }') + await hass.async_block_till_done() + + state = hass.states.get('binary_sensor.beer') + + assert state is not None + assert state.name == 'Beer' + assert ('binary_sensor', 'node1 object1') in hass.data[ALREADY_DISCOVERED]