Add config flow to insteon component (#36467)
* Squashed * Fix requirements_all * Update homeassistant/components/insteon/__init__.py Only update options if the result is to create the entry. Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/insteon/__init__.py No return value needed. Co-authored-by: J. Nick Koston <nick@koston.org> * Ref RESULT_TYPE_CREATE_ENTRY correctly * Return result back to import config process * Make DOMAIN ref more clear Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
6bdb2f3d11
commit
b1fd931cdc
20 changed files with 1740 additions and 111 deletions
|
@ -3,6 +3,7 @@ import asyncio
|
|||
import logging
|
||||
|
||||
from pyinsteon import devices
|
||||
from pyinsteon.address import Address
|
||||
from pyinsteon.constants import ALDBStatus
|
||||
from pyinsteon.events import OFF_EVENT, OFF_FAST_EVENT, ON_EVENT, ON_FAST_EVENT
|
||||
from pyinsteon.managers.link_manager import (
|
||||
|
@ -18,10 +19,15 @@ from pyinsteon.managers.x10_manager import (
|
|||
async_x10_all_lights_on,
|
||||
async_x10_all_units_off,
|
||||
)
|
||||
from pyinsteon.x10_address import create as create_x10_address
|
||||
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_ENTITY_ID, ENTITY_MATCH_ALL
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_ENTITY_ID,
|
||||
CONF_PLATFORM,
|
||||
ENTITY_MATCH_ALL,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import discovery
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect,
|
||||
async_dispatcher_send,
|
||||
|
@ -29,6 +35,11 @@ from homeassistant.helpers.dispatcher import (
|
|||
)
|
||||
|
||||
from .const import (
|
||||
CONF_CAT,
|
||||
CONF_DIM_STEPS,
|
||||
CONF_HOUSECODE,
|
||||
CONF_SUBCAT,
|
||||
CONF_UNITCODE,
|
||||
DOMAIN,
|
||||
EVENT_CONF_BUTTON,
|
||||
EVENT_GROUP_OFF,
|
||||
|
@ -37,8 +48,14 @@ from .const import (
|
|||
EVENT_GROUP_ON_FAST,
|
||||
ON_OFF_EVENTS,
|
||||
SIGNAL_ADD_DEFAULT_LINKS,
|
||||
SIGNAL_ADD_DEVICE_OVERRIDE,
|
||||
SIGNAL_ADD_ENTITIES,
|
||||
SIGNAL_ADD_X10_DEVICE,
|
||||
SIGNAL_LOAD_ALDB,
|
||||
SIGNAL_PRINT_ALDB,
|
||||
SIGNAL_REMOVE_DEVICE_OVERRIDE,
|
||||
SIGNAL_REMOVE_ENTITY,
|
||||
SIGNAL_REMOVE_X10_DEVICE,
|
||||
SIGNAL_SAVE_DEVICES,
|
||||
SRV_ADD_ALL_LINK,
|
||||
SRV_ADD_DEFAULT_LINKS,
|
||||
|
@ -116,9 +133,8 @@ def add_on_off_event_device(hass, device):
|
|||
)
|
||||
|
||||
|
||||
def register_new_device_callback(hass, config):
|
||||
def register_new_device_callback(hass):
|
||||
"""Register callback for new Insteon device."""
|
||||
new_device_lock = asyncio.Lock()
|
||||
|
||||
@callback
|
||||
def async_new_insteon_device(address=None):
|
||||
|
@ -129,27 +145,17 @@ def register_new_device_callback(hass, config):
|
|||
_LOGGER.debug(
|
||||
"Adding new INSTEON device to Home Assistant with address %s", address
|
||||
)
|
||||
async with new_device_lock:
|
||||
await devices.async_save(workdir=hass.config.config_dir)
|
||||
await devices.async_save(workdir=hass.config.config_dir)
|
||||
device = devices[address]
|
||||
await device.async_status()
|
||||
platforms = get_device_platforms(device)
|
||||
tasks = []
|
||||
for platform in platforms:
|
||||
if platform == ON_OFF_EVENTS:
|
||||
add_on_off_event_device(hass, device)
|
||||
|
||||
else:
|
||||
tasks.append(
|
||||
discovery.async_load_platform(
|
||||
hass,
|
||||
platform,
|
||||
DOMAIN,
|
||||
discovered={"address": device.address.id},
|
||||
hass_config=config,
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
signal = f"{SIGNAL_ADD_ENTITIES}_{platform}"
|
||||
dispatcher_send(hass, signal, {"address": device.address})
|
||||
|
||||
devices.subscribe(async_new_insteon_device, force_strong_ref=True)
|
||||
|
||||
|
@ -158,6 +164,8 @@ def register_new_device_callback(hass, config):
|
|||
def async_register_services(hass):
|
||||
"""Register services used by insteon component."""
|
||||
|
||||
save_lock = asyncio.Lock()
|
||||
|
||||
async def async_srv_add_all_link(service):
|
||||
"""Add an INSTEON All-Link between two devices."""
|
||||
group = service.data.get(SRV_ALL_LINK_GROUP)
|
||||
|
@ -192,8 +200,9 @@ def async_register_services(hass):
|
|||
|
||||
async def async_srv_save_devices():
|
||||
"""Write the Insteon device configuration to file."""
|
||||
_LOGGER.debug("Saving Insteon devices")
|
||||
await devices.async_save(hass.config.config_dir)
|
||||
async with save_lock:
|
||||
_LOGGER.debug("Saving Insteon devices")
|
||||
await devices.async_save(hass.config.config_dir)
|
||||
|
||||
def print_aldb(service):
|
||||
"""Print the All-Link Database for a device."""
|
||||
|
@ -241,6 +250,56 @@ def async_register_services(hass):
|
|||
signal = f"{entity_id}_{SIGNAL_ADD_DEFAULT_LINKS}"
|
||||
async_dispatcher_send(hass, signal)
|
||||
|
||||
async def async_add_device_override(override):
|
||||
"""Remove an Insten device and associated entities."""
|
||||
address = Address(override[CONF_ADDRESS])
|
||||
await async_remove_device(address)
|
||||
devices.set_id(address, override[CONF_CAT], override[CONF_SUBCAT], 0)
|
||||
await async_srv_save_devices()
|
||||
|
||||
async def async_remove_device_override(address):
|
||||
"""Remove an Insten device and associated entities."""
|
||||
address = Address(address)
|
||||
await async_remove_device(address)
|
||||
devices.set_id(address, None, None, None)
|
||||
await devices.async_identify_device(address)
|
||||
await async_srv_save_devices()
|
||||
|
||||
@callback
|
||||
def async_add_x10_device(x10_config):
|
||||
"""Add X10 device."""
|
||||
housecode = x10_config[CONF_HOUSECODE]
|
||||
unitcode = x10_config[CONF_UNITCODE]
|
||||
platform = x10_config[CONF_PLATFORM]
|
||||
steps = x10_config.get(CONF_DIM_STEPS, 22)
|
||||
x10_type = "on_off"
|
||||
if platform == "light":
|
||||
x10_type = "dimmable"
|
||||
elif platform == "binary_sensor":
|
||||
x10_type = "sensor"
|
||||
_LOGGER.debug(
|
||||
"Adding X10 device to Insteon: %s %d %s", housecode, unitcode, x10_type
|
||||
)
|
||||
# This must be run in the event loop
|
||||
devices.add_x10_device(housecode, unitcode, x10_type, steps)
|
||||
|
||||
async def async_remove_x10_device(housecode, unitcode):
|
||||
"""Remove an X10 device and associated entities."""
|
||||
address = create_x10_address(housecode, unitcode)
|
||||
devices.pop(address)
|
||||
await async_remove_device(address)
|
||||
|
||||
async def async_remove_device(address):
|
||||
"""Remove the device and all entities from hass."""
|
||||
signal = f"{address.id}_{SIGNAL_REMOVE_ENTITY}"
|
||||
async_dispatcher_send(hass, signal)
|
||||
dev_registry = await hass.helpers.device_registry.async_get_registry()
|
||||
device = dev_registry.async_get_device(
|
||||
identifiers={(DOMAIN, str(address))}, connections=set()
|
||||
)
|
||||
if device:
|
||||
dev_registry.async_remove_device(device.id)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SRV_ADD_ALL_LINK, async_srv_add_all_link, schema=ADD_ALL_LINK_SCHEMA
|
||||
)
|
||||
|
@ -286,6 +345,14 @@ def async_register_services(hass):
|
|||
schema=ADD_DEFAULT_LINKS_SCHEMA,
|
||||
)
|
||||
async_dispatcher_connect(hass, SIGNAL_SAVE_DEVICES, async_srv_save_devices)
|
||||
async_dispatcher_connect(
|
||||
hass, SIGNAL_ADD_DEVICE_OVERRIDE, async_add_device_override
|
||||
)
|
||||
async_dispatcher_connect(
|
||||
hass, SIGNAL_REMOVE_DEVICE_OVERRIDE, async_remove_device_override
|
||||
)
|
||||
async_dispatcher_connect(hass, SIGNAL_ADD_X10_DEVICE, async_add_x10_device)
|
||||
async_dispatcher_connect(hass, SIGNAL_REMOVE_X10_DEVICE, async_remove_x10_device)
|
||||
_LOGGER.debug("Insteon Services registered")
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue