Cleanup if discovered mqtt fan can't be added (#19741)

* Cleanup if discovered mqtt fan can't be added
This commit is contained in:
emontnemery 2019-01-08 16:51:03 +01:00 committed by GitHub
parent 44f6151548
commit 203701bc7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 10 deletions

View File

@ -25,7 +25,8 @@ from homeassistant.components.fan import (SPEED_LOW, SPEED_MEDIUM,
SPEED_HIGH, FanEntity, SPEED_HIGH, FanEntity,
SUPPORT_SET_SPEED, SUPPORT_OSCILLATE, SUPPORT_SET_SPEED, SUPPORT_OSCILLATE,
SPEED_OFF, ATTR_SPEED) SPEED_OFF, ATTR_SPEED)
from homeassistant.components.mqtt.discovery import MQTT_DISCOVERY_NEW from homeassistant.components.mqtt.discovery import (
MQTT_DISCOVERY_NEW, clear_discovery_hash)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -86,23 +87,29 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
async def async_setup_platform(hass: HomeAssistantType, config: ConfigType, async def async_setup_platform(hass: HomeAssistantType, config: ConfigType,
async_add_entities, discovery_info=None): async_add_entities, discovery_info=None):
"""Set up MQTT fan through configuration.yaml.""" """Set up MQTT fan through configuration.yaml."""
await _async_setup_entity(hass, config, async_add_entities) await _async_setup_entity(config, async_add_entities)
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up MQTT fan dynamically through MQTT discovery.""" """Set up MQTT fan dynamically through MQTT discovery."""
async def async_discover(discovery_payload): async def async_discover(discovery_payload):
"""Discover and add a MQTT fan.""" """Discover and add a MQTT fan."""
config = PLATFORM_SCHEMA(discovery_payload) try:
await _async_setup_entity(hass, config, async_add_entities, discovery_hash = discovery_payload[ATTR_DISCOVERY_HASH]
discovery_payload[ATTR_DISCOVERY_HASH]) config = PLATFORM_SCHEMA(discovery_payload)
await _async_setup_entity(config, async_add_entities,
discovery_hash)
except Exception:
if discovery_hash:
clear_discovery_hash(hass, discovery_hash)
raise
async_dispatcher_connect( async_dispatcher_connect(
hass, MQTT_DISCOVERY_NEW.format(fan.DOMAIN, 'mqtt'), hass, MQTT_DISCOVERY_NEW.format(fan.DOMAIN, 'mqtt'),
async_discover) async_discover)
async def _async_setup_entity(hass, config, async_add_entities, async def _async_setup_entity(config, async_add_entities,
discovery_hash=None): discovery_hash=None):
"""Set up the MQTT fan.""" """Set up the MQTT fan."""
async_add_entities([MqttFan( async_add_entities([MqttFan(

View File

@ -3,7 +3,7 @@ import json
from unittest.mock import ANY from unittest.mock import ANY
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.components import fan from homeassistant.components import fan, mqtt
from homeassistant.components.mqtt.discovery import async_start from homeassistant.components.mqtt.discovery import async_start
from homeassistant.const import ATTR_ASSUMED_STATE, STATE_UNAVAILABLE from homeassistant.const import ATTR_ASSUMED_STATE, STATE_UNAVAILABLE
@ -111,7 +111,7 @@ async def test_custom_availability_payload(hass, mqtt_mock):
async def test_discovery_removal_fan(hass, mqtt_mock, caplog): async def test_discovery_removal_fan(hass, mqtt_mock, caplog):
"""Test removal of discovered fan.""" """Test removal of discovered fan."""
entry = MockConfigEntry(domain='mqtt') entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, 'homeassistant', {}, entry) await async_start(hass, 'homeassistant', {}, entry)
data = ( data = (
'{ "name": "Beer",' '{ "name": "Beer",'
@ -132,8 +132,8 @@ async def test_discovery_removal_fan(hass, mqtt_mock, caplog):
async def test_discovery_update_fan(hass, mqtt_mock, caplog): async def test_discovery_update_fan(hass, mqtt_mock, caplog):
"""Test removal of discovered fan.""" """Test update of discovered fan."""
entry = MockConfigEntry(domain='mqtt') entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, 'homeassistant', {}, entry) await async_start(hass, 'homeassistant', {}, entry)
data1 = ( data1 = (
'{ "name": "Beer",' '{ "name": "Beer",'
@ -163,6 +163,38 @@ async def test_discovery_update_fan(hass, mqtt_mock, caplog):
assert state is None assert state is None
async def test_discovery_broken(hass, mqtt_mock, caplog):
"""Test handling of bad discovery message."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, 'homeassistant', {}, entry)
data1 = (
'{ "name": "Beer" }'
)
data2 = (
'{ "name": "Milk",'
' "command_topic": "test_topic" }'
)
async_fire_mqtt_message(hass, 'homeassistant/fan/bla/config',
data1)
await hass.async_block_till_done()
state = hass.states.get('fan.beer')
assert state is None
async_fire_mqtt_message(hass, 'homeassistant/fan/bla/config',
data2)
await hass.async_block_till_done()
await hass.async_block_till_done()
state = hass.states.get('fan.milk')
assert state is not None
assert state.name == 'Milk'
state = hass.states.get('fan.beer')
assert state is None
async def test_unique_id(hass): async def test_unique_id(hass):
"""Test unique_id option only creates one fan per id.""" """Test unique_id option only creates one fan per id."""
await async_mock_mqtt_component(hass) await async_mock_mqtt_component(hass)