mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add config entry for LIFX (#17201)
* Add config entry for LIFX * Use list for dependencies * Obsolete the platform config * Use DOMAIN * Use async_create_task
This commit is contained in:
parent
06a64c0167
commit
086c71525e
@ -63,7 +63,6 @@ homeassistant/components/device_tracker/huawei_router.py @abmantis
|
|||||||
homeassistant/components/device_tracker/tile.py @bachya
|
homeassistant/components/device_tracker/tile.py @bachya
|
||||||
homeassistant/components/history_graph.py @andrey-git
|
homeassistant/components/history_graph.py @andrey-git
|
||||||
homeassistant/components/influx.py @fabaff
|
homeassistant/components/influx.py @fabaff
|
||||||
homeassistant/components/light/lifx.py @amelchio
|
|
||||||
homeassistant/components/light/lifx_legacy.py @amelchio
|
homeassistant/components/light/lifx_legacy.py @amelchio
|
||||||
homeassistant/components/light/tplink.py @rytilahti
|
homeassistant/components/light/tplink.py @rytilahti
|
||||||
homeassistant/components/light/yeelight.py @rytilahti
|
homeassistant/components/light/yeelight.py @rytilahti
|
||||||
@ -180,6 +179,10 @@ homeassistant/components/*/knx.py @Julius2342
|
|||||||
homeassistant/components/konnected.py @heythisisnate
|
homeassistant/components/konnected.py @heythisisnate
|
||||||
homeassistant/components/*/konnected.py @heythisisnate
|
homeassistant/components/*/konnected.py @heythisisnate
|
||||||
|
|
||||||
|
# L
|
||||||
|
homeassistant/components/lifx.py @amelchio
|
||||||
|
homeassistant/components/*/lifx.py @amelchio
|
||||||
|
|
||||||
# M
|
# M
|
||||||
homeassistant/components/matrix.py @tinloaf
|
homeassistant/components/matrix.py @tinloaf
|
||||||
homeassistant/components/*/matrix.py @tinloaf
|
homeassistant/components/*/matrix.py @tinloaf
|
||||||
|
15
homeassistant/components/lifx/.translations/en.json
Normal file
15
homeassistant/components/lifx/.translations/en.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"no_devices_found": "No LIFX devices found on the network.",
|
||||||
|
"single_instance_allowed": "Only a single configuration of LIFX is possible."
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"description": "Do you want to set up LIFX?",
|
||||||
|
"title": "LIFX"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "LIFX"
|
||||||
|
}
|
||||||
|
}
|
97
homeassistant/components/lifx/__init__.py
Normal file
97
homeassistant/components/lifx/__init__.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
"""Component to embed LIFX."""
|
||||||
|
import asyncio
|
||||||
|
import socket
|
||||||
|
|
||||||
|
import async_timeout
|
||||||
|
import voluptuous as vol
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.helpers import config_entry_flow
|
||||||
|
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||||
|
|
||||||
|
|
||||||
|
DOMAIN = 'lifx'
|
||||||
|
REQUIREMENTS = ['aiolifx==0.6.3']
|
||||||
|
|
||||||
|
CONF_SERVER = 'server'
|
||||||
|
CONF_BROADCAST = 'broadcast'
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
|
DOMAIN: {
|
||||||
|
LIGHT_DOMAIN: {
|
||||||
|
vol.Optional(CONF_SERVER): cv.string,
|
||||||
|
vol.Optional(CONF_BROADCAST): cv.string,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass, config):
|
||||||
|
"""Set up the LIFX component."""
|
||||||
|
conf = config.get(DOMAIN)
|
||||||
|
|
||||||
|
hass.data[DOMAIN] = conf or {}
|
||||||
|
|
||||||
|
if conf is not None:
|
||||||
|
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 LIFX from a config entry."""
|
||||||
|
hass.async_create_task(hass.config_entries.async_forward_entry_setup(
|
||||||
|
entry, LIGHT_DOMAIN))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def _async_has_devices(hass):
|
||||||
|
"""Return if there are devices that can be discovered."""
|
||||||
|
import aiolifx
|
||||||
|
|
||||||
|
manager = DiscoveryManager()
|
||||||
|
lifx_discovery = aiolifx.LifxDiscovery(hass.loop, manager)
|
||||||
|
coro = hass.loop.create_datagram_endpoint(
|
||||||
|
lambda: lifx_discovery,
|
||||||
|
family=socket.AF_INET)
|
||||||
|
hass.async_create_task(coro)
|
||||||
|
|
||||||
|
has_devices = await manager.found_devices()
|
||||||
|
lifx_discovery.cleanup()
|
||||||
|
|
||||||
|
return has_devices
|
||||||
|
|
||||||
|
|
||||||
|
config_entry_flow.register_discovery_flow(
|
||||||
|
DOMAIN, 'LIFX', _async_has_devices, config_entries.CONN_CLASS_LOCAL_POLL)
|
||||||
|
|
||||||
|
|
||||||
|
class DiscoveryManager:
|
||||||
|
"""Temporary LIFX manager for discovering any bulb."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize the manager."""
|
||||||
|
self._event = asyncio.Event()
|
||||||
|
|
||||||
|
async def found_devices(self):
|
||||||
|
"""Return whether any device could be discovered."""
|
||||||
|
try:
|
||||||
|
async with async_timeout.timeout(2):
|
||||||
|
await self._event.wait()
|
||||||
|
|
||||||
|
# Let bulbs recover from the discovery
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
return True
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def register(self, bulb):
|
||||||
|
"""Handle aiolifx detected bulb."""
|
||||||
|
self._event.set()
|
||||||
|
|
||||||
|
def unregister(self, bulb):
|
||||||
|
"""Handle aiolifx disappearing bulbs."""
|
||||||
|
pass
|
15
homeassistant/components/lifx/strings.json
Normal file
15
homeassistant/components/lifx/strings.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"title": "LIFX",
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"title": "LIFX",
|
||||||
|
"description": "Do you want to set up LIFX?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Only a single configuration of LIFX is possible.",
|
||||||
|
"no_devices_found": "No LIFX devices found on the network."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/light.lifx/
|
https://home-assistant.io/components/light.lifx/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import socket
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
@ -17,10 +18,12 @@ from homeassistant import util
|
|||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_NAME, ATTR_COLOR_TEMP,
|
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_NAME, ATTR_COLOR_TEMP,
|
||||||
ATTR_EFFECT, ATTR_HS_COLOR, ATTR_KELVIN, ATTR_RGB_COLOR, ATTR_TRANSITION,
|
ATTR_EFFECT, ATTR_HS_COLOR, ATTR_KELVIN, ATTR_RGB_COLOR, ATTR_TRANSITION,
|
||||||
ATTR_XY_COLOR, COLOR_GROUP, DOMAIN, LIGHT_TURN_ON_SCHEMA, PLATFORM_SCHEMA,
|
ATTR_XY_COLOR, COLOR_GROUP, DOMAIN, LIGHT_TURN_ON_SCHEMA,
|
||||||
SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT,
|
SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT,
|
||||||
SUPPORT_TRANSITION, VALID_BRIGHTNESS, VALID_BRIGHTNESS_PCT, Light,
|
SUPPORT_TRANSITION, VALID_BRIGHTNESS, VALID_BRIGHTNESS_PCT, Light,
|
||||||
preprocess_turn_on_alternatives)
|
preprocess_turn_on_alternatives)
|
||||||
|
from homeassistant.components.lifx import (
|
||||||
|
DOMAIN as LIFX_DOMAIN, CONF_SERVER, CONF_BROADCAST)
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
@ -30,23 +33,16 @@ import homeassistant.util.color as color_util
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
REQUIREMENTS = ['aiolifx==0.6.3', 'aiolifx_effects==0.2.1']
|
DEPENDENCIES = ['lifx']
|
||||||
|
REQUIREMENTS = ['aiolifx_effects==0.2.1']
|
||||||
|
|
||||||
UDP_BROADCAST_PORT = 56700
|
SCAN_INTERVAL = timedelta(seconds=10)
|
||||||
|
|
||||||
DISCOVERY_INTERVAL = 60
|
DISCOVERY_INTERVAL = 60
|
||||||
MESSAGE_TIMEOUT = 1.0
|
MESSAGE_TIMEOUT = 1.0
|
||||||
MESSAGE_RETRIES = 8
|
MESSAGE_RETRIES = 8
|
||||||
UNAVAILABLE_GRACE = 90
|
UNAVAILABLE_GRACE = 90
|
||||||
|
|
||||||
CONF_SERVER = 'server'
|
|
||||||
CONF_BROADCAST = 'broadcast'
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
||||||
vol.Optional(CONF_SERVER, default='0.0.0.0'): cv.string,
|
|
||||||
vol.Optional(CONF_BROADCAST, default='255.255.255.255'): cv.string,
|
|
||||||
})
|
|
||||||
|
|
||||||
SERVICE_LIFX_SET_STATE = 'lifx_set_state'
|
SERVICE_LIFX_SET_STATE = 'lifx_set_state'
|
||||||
|
|
||||||
ATTR_INFRARED = 'infrared'
|
ATTR_INFRARED = 'infrared'
|
||||||
@ -138,24 +134,33 @@ async def async_setup_platform(hass,
|
|||||||
config,
|
config,
|
||||||
async_add_entities,
|
async_add_entities,
|
||||||
discovery_info=None):
|
discovery_info=None):
|
||||||
"""Set up the LIFX platform."""
|
"""Set up the LIFX light platform. Obsolete."""
|
||||||
|
_LOGGER.warning('LIFX no longer works with light platform configuration.')
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Set up LIFX from a config entry."""
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
_LOGGER.warning("The lifx platform is known to not work on Windows. "
|
_LOGGER.warning("The lifx platform is known to not work on Windows. "
|
||||||
"Consider using the lifx_legacy platform instead")
|
"Consider using the lifx_legacy platform instead")
|
||||||
|
|
||||||
server_addr = config.get(CONF_SERVER)
|
config = hass.data[LIFX_DOMAIN].get(DOMAIN, {})
|
||||||
|
|
||||||
lifx_manager = LIFXManager(hass, async_add_entities)
|
lifx_manager = LIFXManager(hass, async_add_entities)
|
||||||
lifx_discovery = aiolifx().LifxDiscovery(
|
|
||||||
hass.loop,
|
|
||||||
lifx_manager,
|
|
||||||
discovery_interval=DISCOVERY_INTERVAL,
|
|
||||||
broadcast_ip=config.get(CONF_BROADCAST))
|
|
||||||
|
|
||||||
coro = hass.loop.create_datagram_endpoint(
|
broadcast_ip = config.get(CONF_BROADCAST)
|
||||||
lambda: lifx_discovery, local_addr=(server_addr, UDP_BROADCAST_PORT))
|
kwargs = {'discovery_interval': DISCOVERY_INTERVAL}
|
||||||
|
if broadcast_ip:
|
||||||
|
kwargs['broadcast_ip'] = broadcast_ip
|
||||||
|
lifx_discovery = aiolifx().LifxDiscovery(hass.loop, lifx_manager, **kwargs)
|
||||||
|
|
||||||
hass.async_add_job(coro)
|
kwargs = {'family': socket.AF_INET}
|
||||||
|
local_addr = config.get(CONF_SERVER)
|
||||||
|
if local_addr is not None:
|
||||||
|
kwargs['local_addr'] = (local_addr, 0)
|
||||||
|
coro = hass.loop.create_datagram_endpoint(lambda: lifx_discovery, **kwargs)
|
||||||
|
|
||||||
|
hass.async_create_task(coro)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def cleanup(event):
|
def cleanup(event):
|
||||||
@ -225,7 +230,7 @@ class LIFXManager:
|
|||||||
for light in self.service_to_entities(service):
|
for light in self.service_to_entities(service):
|
||||||
if service.service == SERVICE_LIFX_SET_STATE:
|
if service.service == SERVICE_LIFX_SET_STATE:
|
||||||
task = light.set_state(**service.data)
|
task = light.set_state(**service.data)
|
||||||
tasks.append(self.hass.async_add_job(task))
|
tasks.append(self.hass.async_create_task(task))
|
||||||
if tasks:
|
if tasks:
|
||||||
await asyncio.wait(tasks, loop=self.hass.loop)
|
await asyncio.wait(tasks, loop=self.hass.loop)
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@ FLOWS = [
|
|||||||
'hue',
|
'hue',
|
||||||
'ifttt',
|
'ifttt',
|
||||||
'ios',
|
'ios',
|
||||||
|
'lifx',
|
||||||
'mqtt',
|
'mqtt',
|
||||||
'nest',
|
'nest',
|
||||||
'openuv',
|
'openuv',
|
||||||
|
@ -106,7 +106,7 @@ aiohue==1.5.0
|
|||||||
# homeassistant.components.sensor.imap
|
# homeassistant.components.sensor.imap
|
||||||
aioimaplib==0.7.13
|
aioimaplib==0.7.13
|
||||||
|
|
||||||
# homeassistant.components.light.lifx
|
# homeassistant.components.lifx
|
||||||
aiolifx==0.6.3
|
aiolifx==0.6.3
|
||||||
|
|
||||||
# homeassistant.components.light.lifx
|
# homeassistant.components.light.lifx
|
||||||
|
Loading…
x
Reference in New Issue
Block a user