core/homeassistant/components/insteon/__init__.py

161 lines
4.8 KiB
Python

"""Support for INSTEON Modems (PLM and Hub)."""
import asyncio
import logging
from pyinsteon import async_close, async_connect, devices
from homeassistant.const import (
CONF_HOST,
CONF_PLATFORM,
CONF_PORT,
EVENT_HOMEASSISTANT_STOP,
)
from .const import (
CONF_CAT,
CONF_DIM_STEPS,
CONF_FIRMWARE,
CONF_HOUSECODE,
CONF_HUB_PASSWORD,
CONF_HUB_USERNAME,
CONF_HUB_VERSION,
CONF_IP_PORT,
CONF_OVERRIDE,
CONF_PRODUCT_KEY,
CONF_SUBCAT,
CONF_UNITCODE,
CONF_X10,
DOMAIN,
INSTEON_COMPONENTS,
ON_OFF_EVENTS,
)
from .schemas import CONFIG_SCHEMA # noqa F440
from .utils import (
add_on_off_event_device,
async_register_services,
get_device_platforms,
register_new_device_callback,
)
_LOGGER = logging.getLogger(__name__)
async def async_id_unknown_devices(config_dir):
"""Send device ID commands to all unidentified devices."""
await devices.async_load(id_devices=1)
for addr in devices:
device = devices[addr]
flags = True
for name in device.operating_flags:
if not device.operating_flags[name].is_loaded:
flags = False
break
if flags:
for name in device.properties:
if not device.properties[name].is_loaded:
flags = False
break
# Cannot be done concurrently due to issues with the underlying protocol.
if not device.aldb.is_loaded or not flags:
await device.async_read_config()
await devices.async_save(workdir=config_dir)
async def async_setup_platforms(hass, config):
"""Initiate the connection and services."""
tasks = [
hass.helpers.discovery.async_load_platform(component, DOMAIN, {}, config)
for component in INSTEON_COMPONENTS
]
await asyncio.gather(*tasks)
for address in devices:
device = devices[address]
platforms = get_device_platforms(device)
if ON_OFF_EVENTS in platforms:
add_on_off_event_device(hass, device)
_LOGGER.debug("Insteon device count: %s", len(devices))
register_new_device_callback(hass, config)
async_register_services(hass)
# Cannot be done concurrently due to issues with the underlying protocol.
for address in devices:
await devices[address].async_status()
await async_id_unknown_devices(hass.config.config_dir)
async def close_insteon_connection(*args):
"""Close the Insteon connection."""
await async_close()
async def async_setup(hass, config):
"""Set up the connection to the modem."""
conf = config[DOMAIN]
port = conf.get(CONF_PORT)
host = conf.get(CONF_HOST)
ip_port = conf.get(CONF_IP_PORT)
username = conf.get(CONF_HUB_USERNAME)
password = conf.get(CONF_HUB_PASSWORD)
hub_version = conf.get(CONF_HUB_VERSION)
if host:
_LOGGER.info("Connecting to Insteon Hub on %s:%d", host, ip_port)
else:
_LOGGER.info("Connecting to Insteon PLM on %s", port)
try:
await async_connect(
device=port,
host=host,
port=ip_port,
username=username,
password=password,
hub_version=hub_version,
)
except ConnectionError:
_LOGGER.error("Could not connect to Insteon modem")
return False
_LOGGER.info("Connection to Insteon modem successful")
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, close_insteon_connection)
conf = config[DOMAIN]
overrides = conf.get(CONF_OVERRIDE, [])
x10_devices = conf.get(CONF_X10, [])
await devices.async_load(
workdir=hass.config.config_dir, id_devices=0, load_modem_aldb=0
)
for device_override in overrides:
# Override the device default capabilities for a specific address
address = device_override.get("address")
if not devices.get(address):
cat = device_override[CONF_CAT]
subcat = device_override[CONF_SUBCAT]
firmware = device_override.get(CONF_FIRMWARE)
if firmware is None:
firmware = device_override.get(CONF_PRODUCT_KEY, 0)
devices.set_id(address, cat, subcat, firmware)
for device in x10_devices:
housecode = device.get(CONF_HOUSECODE)
unitcode = device.get(CONF_UNITCODE)
x10_type = "on_off"
steps = device.get(CONF_DIM_STEPS, 22)
if device.get(CONF_PLATFORM) == "light":
x10_type = "dimmable"
elif device.get(CONF_PLATFORM) == "binary_sensor":
x10_type = "sensor"
_LOGGER.debug(
"Adding X10 device to Insteon: %s %d %s", housecode, unitcode, x10_type
)
device = devices.add_x10_device(housecode, unitcode, x10_type, steps)
asyncio.create_task(async_setup_platforms(hass, config))
return True