hass-core/homeassistant/components/light/tradfri.py

204 lines
6.5 KiB
Python
Raw Normal View History

"""
Support for the IKEA Tradfri platform.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.tradfri/
"""
import logging
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_BRIGHTNESS,
SUPPORT_COLOR_TEMP, SUPPORT_RGB_COLOR, Light)
from homeassistant.components.light import (
PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA)
from homeassistant.components.tradfri import (
KEY_GATEWAY, KEY_TRADFRI_GROUPS, KEY_API)
from homeassistant.util import color as color_util
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['tradfri']
PLATFORM_SCHEMA = LIGHT_PLATFORM_SCHEMA
IKEA = 'IKEA of Sweden'
ALLOWED_TEMPERATURES = {IKEA}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the IKEA Tradfri Light platform."""
if discovery_info is None:
return
gateway_id = discovery_info['gateway']
api = hass.data[KEY_API][gateway_id]
gateway = hass.data[KEY_GATEWAY][gateway_id]
devices = api(gateway.get_devices())
lights = [dev for dev in devices if api(dev).has_light_control]
add_devices(Tradfri(light, api) for light in lights)
allow_tradfri_groups = hass.data[KEY_TRADFRI_GROUPS][gateway_id]
if allow_tradfri_groups:
groups = api(gateway.get_groups())
add_devices(TradfriGroup(group, api) for group in groups)
class TradfriGroup(Light):
"""The platform class required by hass."""
def __init__(self, light, api):
"""Initialize a Group."""
self._group = api(light)
self._api = api
self._name = self._group.name
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_BRIGHTNESS
@property
def name(self):
"""Return the display name of this group."""
return self._name
@property
def is_on(self):
"""Return true if group lights are on."""
return self._group.state
@property
def brightness(self):
"""Return the brightness of the group lights."""
return self._group.dimmer
def turn_off(self, **kwargs):
"""Instruct the group lights to turn off."""
self._api(self._group.set_state(0))
def turn_on(self, **kwargs):
"""Instruct the group lights to turn on, or dim."""
if ATTR_BRIGHTNESS in kwargs:
self._api(self._group.set_dimmer(kwargs[ATTR_BRIGHTNESS]))
else:
self._api(self._group.set_state(1))
def update(self):
"""Fetch new state data for this group."""
from pytradfri import RequestTimeout
try:
self._api(self._group.update())
except RequestTimeout:
_LOGGER.warning("Tradfri update request timed out")
class Tradfri(Light):
"""The platform class required by Home Asisstant."""
def __init__(self, light, api):
"""Initialize a Light."""
self._light = api(light)
self._api = api
# Caching of LightControl and light object
self._light_control = self._light.light_control
self._light_data = self._light_control.lights[0]
self._name = self._light.name
self._rgb_color = None
self._features = SUPPORT_BRIGHTNESS
if self._light_data.hex_color is not None:
if self._light.device_info.manufacturer == IKEA:
self._features |= SUPPORT_COLOR_TEMP
else:
self._features |= SUPPORT_RGB_COLOR
self._ok_temps = \
self._light.device_info.manufacturer in ALLOWED_TEMPERATURES
@property
def min_mireds(self):
"""Return the coldest color_temp that this light supports."""
from pytradfri.color import MAX_KELVIN_WS
return color_util.color_temperature_kelvin_to_mired(MAX_KELVIN_WS)
@property
def max_mireds(self):
"""Return the warmest color_temp that this light supports."""
from pytradfri.color import MIN_KELVIN_WS
return color_util.color_temperature_kelvin_to_mired(MIN_KELVIN_WS)
@property
def supported_features(self):
"""Flag supported features."""
2017-04-19 09:15:39 -07:00
return self._features
@property
def name(self):
"""Return the display name of this light."""
return self._name
@property
def is_on(self):
"""Return true if light is on."""
return self._light_data.state
@property
def brightness(self):
"""Return the brightness of the light."""
return self._light_data.dimmer
@property
def color_temp(self):
"""Return the CT color value in mireds."""
if (self._light_data.kelvin_color is None or
self.supported_features & SUPPORT_COLOR_TEMP == 0 or
not self._ok_temps):
return None
return color_util.color_temperature_kelvin_to_mired(
self._light_data.kelvin_color
)
@property
def rgb_color(self):
"""RGB color of the light."""
2017-04-19 09:15:39 -07:00
return self._rgb_color
def turn_off(self, **kwargs):
"""Instruct the light to turn off."""
self._api(self._light_control.set_state(False))
def turn_on(self, **kwargs):
"""
Instruct the light to turn on.
After adding "self._light_data.hexcolor is not None"
for ATTR_RGB_COLOR, this also supports Philips Hue bulbs.
"""
if ATTR_BRIGHTNESS in kwargs:
self._api(self._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS]))
else:
self._api(self._light_control.set_state(True))
if ATTR_RGB_COLOR in kwargs and self._light_data.hex_color is not None:
full RGB support for users of tradfri GW (#9411) * Update tradfri.py ## 201709013: set_hex_color() seems not to work in pytradfri api - set_rgb_color() does ## -> changed function set_hex_color() to set_rgb_color() ## tested w. IKEA tradfri GW and zigbee rgb PWM module (dresden elektronik FLS-PP lp) * Update tradfri.py Setup: Home Assistant 0.53.0 pytradfri 2.2 IKEA tradfri gateway fw 1.1.0015 zigbee rgb PWM module (dresden elektronik FLS-PP lp) Issue: pytradfri's set_hex_color() does not work for arbitrary colors with the current IKEA tradfri gateway. Only setting rgb hex values (param 5706) of some predefined colors has the desired effect. Others will fall back to one predefined value. I assume, the GW doesn't allow for values deviating from the predefined values. However, pytradfri's set_rgb_color() does also work for arbitrary colors. Latest pytradfri (2.2/PR51?) will convert rgb to xy and send xy thru the GW (param 5709 and 5710). -> changed the function used from set_hex_color() to set_rgb_color() in HA's component\light\tradfri Result: Full RGB support with arbitrary colors with my setup. Unfortunately I cannot test tradfri GW with other bulbs (no have hue/lightify bulbs). ___ Predefined colors from <https://github.com/ggravlingen/pytradfri/pull/51>: this.f3891b = new HashMap(); this.f3891b.put("f5faf6", new C1386c(0.3804d, 0.3804d, "f5faf6", 0.54d)); this.f3891b.put("f1e0b5", new C1386c(0.4599d, 0.4106d, "CCT_LIGHT_NEUTRAL", 0.61d)); this.f3891b.put("efd275", new C1386c(0.5056d, 0.4152d, "efd275", 0.66d)); this.f3891b.put("dcf0f8", new C1386c(0.3221d, 0.3317d, "dcf0f8", 0.45d)); this.f3891b.put("eaf6fb", new C1386c(0.3451d, 0.3451d, "eaf6fb", 0.48d)); this.f3891b.put("f5faf6", new C1386c(0.3804d, 0.3804d, "f5faf6", 0.54d)); this.f3891b.put("f2eccf", new C1386c(0.4369d, 0.4041d, "f2eccf", 0.59d)); this.f3891b.put("CCT_LIGHT_NEUTRAL", new C1386c(0.4599d, 0.4106d, "CCT_LIGHT_NEUTRAL", 0.61d)); this.f3891b.put("efd275", new C1386c(0.5056d, 0.4152d, "efd275", 0.66d)); this.f3891b.put("ebb63e", new C1386c(0.5516d, 0.4075d, "ebb63e", 0.68d)); this.f3891b.put("e78834", new C1386c(0.58d, 0.38d, "e78834", 0.69d)); this.f3891b.put("e57345", new C1386c(0.58d, 0.35d, "e57345", 0.67d)); this.f3891b.put("da5d41", new C1386c(0.62d, 0.34d, "da5d41", 0.7d)); this.f3891b.put("dc4b31", new C1386c(0.66d, 0.32d, "dc4b31", 0.73d)); this.f3891b.put("e491af", new C1386c(0.5d, 0.28d, "e491af", 0.57d)); this.f3891b.put("e8bedd", new C1386c(0.45d, 0.28d, "e8bedd", 0.53d)); this.f3891b.put("d9337c", new C1386c(0.5d, 0.24d, "d9337c", 0.55d)); this.f3891b.put("c984bb", new C1386c(0.34d, 0.19d, "c984bb", 0.38d)); this.f3891b.put("8f2686", new C1386c(0.31d, 0.12d, "8f2686", 0.33d)); this.f3891b.put("4a418a", new C1386c(0.17d, 0.05d, "4a418a", 0.18d)); this.f3891b.put("6c83ba", new C1386c(0.2d, 0.1d, "6c83ba", 0.22d)); this.f3891b.put("a9d62b", new C1386c(0.4099999964237213d, 0.5099999904632568d, "a9d62b", 0.654d)); this.f3891b.put("d6e44b", new C1386c(0.44999998807907104d, 0.4699999988079071d, "d6e44b", 0.65d));
2017-09-14 07:24:46 +02:00
self._api(self._light.light_control.set_rgb_color(
*kwargs[ATTR_RGB_COLOR]))
elif ATTR_COLOR_TEMP in kwargs and \
self._light_data.hex_color is not None and self._ok_temps:
kelvin = color_util.color_temperature_mired_to_kelvin(
kwargs[ATTR_COLOR_TEMP])
self._api(self._light_control.set_kelvin_color(kelvin))
def update(self):
"""Fetch new state data for this light."""
from pytradfri import RequestTimeout
try:
self._api(self._light.update())
except RequestTimeout as exception:
_LOGGER.warning("Tradfri update request timed out: %s", exception)
2017-04-24 21:57:27 -07:00
# Handle Hue lights paired with the gateway
# hex_color is 0 when bulb is unreachable
if self._light_data.hex_color not in (None, '0'):
self._rgb_color = color_util.rgb_hex_to_rgb_list(
self._light_data.hex_color)