Add a discovery config flow to Wemo (#24208)
parent
b1dcfaf6b3
commit
4c88578371
|
@ -58,7 +58,6 @@ SERVICE_HANDLERS = {
|
|||
SERVICE_MOBILE_APP: ('mobile_app', None),
|
||||
SERVICE_HASS_IOS_APP: ('ios', None),
|
||||
SERVICE_NETGEAR: ('device_tracker', None),
|
||||
SERVICE_WEMO: ('wemo', None),
|
||||
SERVICE_HASSIO: ('hassio', None),
|
||||
SERVICE_APPLE_TV: ('apple_tv', None),
|
||||
SERVICE_ENIGMA2: ('media_player', 'enigma2'),
|
||||
|
@ -94,19 +93,20 @@ OPTIONAL_SERVICE_HANDLERS = {
|
|||
SERVICE_DLNA_DMR: ('media_player', 'dlna_dmr'),
|
||||
}
|
||||
|
||||
MIGRATED_SERVICE_HANDLERS = {
|
||||
'axis': None,
|
||||
'deconz': None,
|
||||
'esphome': None,
|
||||
'ikea_tradfri': None,
|
||||
'homekit': None,
|
||||
'philips_hue': None
|
||||
}
|
||||
MIGRATED_SERVICE_HANDLERS = [
|
||||
'axis',
|
||||
'deconz',
|
||||
'esphome',
|
||||
'ikea_tradfri',
|
||||
'homekit',
|
||||
'philips_hue',
|
||||
SERVICE_WEMO,
|
||||
]
|
||||
|
||||
DEFAULT_ENABLED = list(CONFIG_ENTRY_HANDLERS) + list(SERVICE_HANDLERS) + \
|
||||
list(MIGRATED_SERVICE_HANDLERS)
|
||||
MIGRATED_SERVICE_HANDLERS
|
||||
DEFAULT_DISABLED = list(OPTIONAL_SERVICE_HANDLERS) + \
|
||||
list(MIGRATED_SERVICE_HANDLERS)
|
||||
MIGRATED_SERVICE_HANDLERS
|
||||
|
||||
CONF_IGNORE = 'ignore'
|
||||
CONF_ENABLE = 'enable'
|
||||
|
|
|
@ -4,6 +4,7 @@ import logging
|
|||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.discovery import SERVICE_WEMO
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers import discovery
|
||||
|
@ -68,22 +69,35 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
|
||||
def setup(hass, config):
|
||||
"""Set up for WeMo devices."""
|
||||
hass.data[DOMAIN] = config
|
||||
|
||||
if DOMAIN in config:
|
||||
hass.async_create_task(hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={'source': config_entries.SOURCE_IMPORT}))
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry):
|
||||
"""Set up a wemo config entry."""
|
||||
import pywemo
|
||||
|
||||
config = hass.data[DOMAIN]
|
||||
|
||||
# Keep track of WeMo devices
|
||||
devices = []
|
||||
|
||||
# Keep track of WeMo device subscriptions for push updates
|
||||
global SUBSCRIPTION_REGISTRY
|
||||
SUBSCRIPTION_REGISTRY = pywemo.SubscriptionRegistry()
|
||||
SUBSCRIPTION_REGISTRY.start()
|
||||
await hass.async_add_executor_job(SUBSCRIPTION_REGISTRY.start)
|
||||
|
||||
def stop_wemo(event):
|
||||
"""Shutdown Wemo subscriptions and subscription thread on exit."""
|
||||
_LOGGER.debug("Shutting down WeMo event subscriptions")
|
||||
SUBSCRIPTION_REGISTRY.stop()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_wemo)
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_wemo)
|
||||
|
||||
def setup_url_for_device(device):
|
||||
"""Determine setup.xml url for given device."""
|
||||
|
@ -119,7 +133,7 @@ def setup(hass, config):
|
|||
discovery.load_platform(
|
||||
hass, component, DOMAIN, discovery_info, config)
|
||||
|
||||
discovery.listen(hass, SERVICE_WEMO, discovery_dispatch)
|
||||
discovery.async_listen(hass, SERVICE_WEMO, discovery_dispatch)
|
||||
|
||||
def discover_wemo_devices(now):
|
||||
"""Run discovery for WeMo devices."""
|
||||
|
@ -145,7 +159,7 @@ def setup(hass, config):
|
|||
if d[1].serialnumber == device.serialnumber]:
|
||||
devices.append((url, device))
|
||||
|
||||
if config.get(DOMAIN, {}).get(CONF_DISCOVERY):
|
||||
if config.get(DOMAIN, {}).get(CONF_DISCOVERY, DEFAULT_DISCOVERY):
|
||||
_LOGGER.debug("Scanning network for WeMo devices...")
|
||||
for device in pywemo.discover_devices():
|
||||
if not [d[1] for d in devices
|
||||
|
@ -168,6 +182,7 @@ def setup(hass, config):
|
|||
|
||||
_LOGGER.debug("WeMo device discovery has finished")
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, discover_wemo_devices)
|
||||
hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, discover_wemo_devices)
|
||||
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
"""Config flow for Wemo."""
|
||||
from homeassistant.helpers import config_entry_flow
|
||||
from homeassistant import config_entries
|
||||
from . import DOMAIN
|
||||
|
||||
|
||||
async def _async_has_devices(hass):
|
||||
"""Return if there are devices that can be discovered."""
|
||||
import pywemo
|
||||
|
||||
return bool(pywemo.discover_devices())
|
||||
|
||||
|
||||
config_entry_flow.register_discovery_flow(
|
||||
DOMAIN, 'Wemo', _async_has_devices, config_entries.CONN_CLASS_LOCAL_PUSH)
|
|
@ -1,10 +1,16 @@
|
|||
{
|
||||
"domain": "wemo",
|
||||
"name": "Wemo",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/components/wemo",
|
||||
"requirements": [
|
||||
"pywemo==0.4.34"
|
||||
],
|
||||
"ssdp": {
|
||||
"manufacturer": [
|
||||
"Belkin International Inc."
|
||||
]
|
||||
},
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
"@sqldiablo"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"config": {
|
||||
"title": "Wemo",
|
||||
"step": {
|
||||
"confirm": {
|
||||
"title": "Wemo",
|
||||
"description": "Do you want to set up Wemo?"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "Only a single configuration of Wemo is possible.",
|
||||
"no_devices_found": "No Wemo devices found on the network."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,6 +50,7 @@ FLOWS = [
|
|||
"twilio",
|
||||
"unifi",
|
||||
"upnp",
|
||||
"wemo",
|
||||
"zha",
|
||||
"zone",
|
||||
"zwave"
|
||||
|
|
|
@ -7,6 +7,9 @@ To update, run python3 -m script.hassfest
|
|||
SSDP = {
|
||||
"device_type": {},
|
||||
"manufacturer": {
|
||||
"Belkin International Inc.": [
|
||||
"wemo"
|
||||
],
|
||||
"Royal Philips Electronics": [
|
||||
"deconz",
|
||||
"hue"
|
||||
|
|
|
@ -43,7 +43,9 @@ def generate_and_validate(integrations: Dict[str, Integration]):
|
|||
|
||||
try:
|
||||
with open(str(integration.path / "config_flow.py")) as fp:
|
||||
if ' async_step_ssdp(' not in fp.read():
|
||||
content = fp.read()
|
||||
if (' async_step_ssdp(' not in content and
|
||||
'register_discovery_flow' not in content):
|
||||
integration.add_error(
|
||||
'ssdp', 'Config flow has no async_step_ssdp')
|
||||
continue
|
||||
|
|
Loading…
Reference in New Issue