Remove global limit on white light temperature (#7206)

* Remove global limit on white light temperature

Here are the supported temperatures of some popular bulbs:

 Philips Hue: 2000K-6500K (the current 500-154 mired range)
 LIFX Color 1000: 2500K-9000K
 IKEA TRÅDFRI: 2200K, 2700K, 4000K

Obviously, Home Assistant cannot enforce a global limit and work properly
with all of these bulbs. So just remove the limit and leave it up to each
platform to work it out.

This commit updates the existing users and adds a clamp to Hue (where the
limit appears to have originated). It does not attempt to update other
platforms that might need extra handling of the larger range that is now
possible.

* Add min_mireds/max_mireds state attributes to lights

* Support min_mireds/max_mireds with LIFX lights
This commit is contained in:
Anders Melchiorsen 2017-04-30 00:04:20 +02:00 committed by Paulus Schoutsen
parent ae9f44c708
commit 64a7be66b1
8 changed files with 60 additions and 17 deletions

View file

@ -50,6 +50,8 @@ ATTR_TRANSITION = "transition"
ATTR_RGB_COLOR = "rgb_color"
ATTR_XY_COLOR = "xy_color"
ATTR_COLOR_TEMP = "color_temp"
ATTR_MIN_MIREDS = "min_mireds"
ATTR_MAX_MIREDS = "max_mireds"
ATTR_COLOR_NAME = "color_name"
ATTR_WHITE_VALUE = "white_value"
@ -78,6 +80,8 @@ LIGHT_PROFILES_FILE = "light_profiles.csv"
PROP_TO_ATTR = {
'brightness': ATTR_BRIGHTNESS,
'color_temp': ATTR_COLOR_TEMP,
'min_mireds': ATTR_MIN_MIREDS,
'max_mireds': ATTR_MAX_MIREDS,
'rgb_color': ATTR_RGB_COLOR,
'xy_color': ATTR_XY_COLOR,
'white_value': ATTR_WHITE_VALUE,
@ -99,9 +103,7 @@ LIGHT_TURN_ON_SCHEMA = vol.Schema({
vol.Coerce(tuple)),
ATTR_XY_COLOR: vol.All(vol.ExactSequence((cv.small_float, cv.small_float)),
vol.Coerce(tuple)),
ATTR_COLOR_TEMP: vol.All(vol.Coerce(int),
vol.Range(min=color_util.HASS_COLOR_MIN,
max=color_util.HASS_COLOR_MAX)),
ATTR_COLOR_TEMP: vol.All(vol.Coerce(int), vol.Range(min=1)),
ATTR_WHITE_VALUE: vol.All(vol.Coerce(int), vol.Range(min=0, max=255)),
ATTR_FLASH: vol.In([FLASH_SHORT, FLASH_LONG]),
ATTR_EFFECT: cv.string,
@ -337,6 +339,18 @@ class Light(ToggleEntity):
"""Return the CT color value in mireds."""
return None
@property
def min_mireds(self):
"""Return the coldest color_temp that this light supports."""
# Default to the Philips Hue value that HA has always assumed
return 154
@property
def max_mireds(self):
"""Return the warmest color_temp that this light supports."""
# Default to the Philips Hue value that HA has always assumed
return 500
@property
def white_value(self):
"""Return the white value of this light between 0..255."""

View file

@ -403,7 +403,8 @@ class HueLight(Light):
command['bri'] = kwargs[ATTR_BRIGHTNESS]
if ATTR_COLOR_TEMP in kwargs:
command['ct'] = kwargs[ATTR_COLOR_TEMP]
temp = kwargs[ATTR_COLOR_TEMP]
command['ct'] = max(self.min_mireds, min(temp, self.max_mireds))
flash = kwargs.get(ATTR_FLASH)

View file

@ -8,6 +8,7 @@ import colorsys
import logging
import asyncio
import sys
import math
from functools import partial
from datetime import timedelta
import async_timeout
@ -96,7 +97,12 @@ class LIFXManager(object):
self.hass.async_add_job(entity.async_update_ha_state())
else:
_LOGGER.debug("%s register NEW", device.ip_addr)
device.get_color(self.ready)
device.get_version(self.got_version)
@callback
def got_version(self, device, msg):
"""Request current color setting once we have the product version."""
device.get_color(self.ready)
@callback
def ready(self, device, msg):
@ -166,6 +172,7 @@ class LIFXLight(Light):
def __init__(self, device):
"""Initialize the light."""
self.device = device
self.product = device.product
self.blocker = None
self.effect_data = None
self.postponed_update = None
@ -213,6 +220,28 @@ class LIFXLight(Light):
_LOGGER.debug("color_temp: %d", temperature)
return temperature
@property
def min_mireds(self):
"""Return the coldest color_temp that this light supports."""
# The 3 LIFX "White" products supported a limited temperature range
# https://lan.developer.lifx.com/docs/lifx-products
if self.product in [10, 11, 18]:
kelvin = 6500
else:
kelvin = 9000
return math.floor(color_temperature_kelvin_to_mired(kelvin))
@property
def max_mireds(self):
"""Return the warmest color_temp that this light supports."""
# The 3 LIFX "White" products supported a limited temperature range
# https://lan.developer.lifx.com/docs/lifx-products
if self.product in [10, 11, 18]:
kelvin = 2700
else:
kelvin = 2500
return math.ceil(color_temperature_kelvin_to_mired(kelvin))
@property
def is_on(self):
"""Return true if device is on."""

View file

@ -25,7 +25,7 @@ turn_on:
example: '[0.52, 0.43]'
color_temp:
description: Color temperature for the light in mireds (154-500)
description: Color temperature for the light in mireds
example: '250'
white_value:

View file

@ -15,9 +15,8 @@ from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, \
from homeassistant.components import zwave
from homeassistant.components.zwave import async_setup_platform # noqa # pylint: disable=unused-import
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.util.color import HASS_COLOR_MAX, HASS_COLOR_MIN, \
color_temperature_mired_to_kelvin, color_temperature_to_rgb, \
color_rgb_to_rgbw, color_rgbw_to_rgb
from homeassistant.util.color import color_temperature_mired_to_kelvin, \
color_temperature_to_rgb, color_rgb_to_rgbw, color_rgbw_to_rgb
_LOGGER = logging.getLogger(__name__)
@ -39,9 +38,11 @@ DEVICE_MAPPINGS = {
# Generate midpoint color temperatures for bulbs that have limited
# support for white light colors
TEMP_MID_HASS = (HASS_COLOR_MAX - HASS_COLOR_MIN) / 2 + HASS_COLOR_MIN
TEMP_WARM_HASS = (HASS_COLOR_MAX - HASS_COLOR_MIN) / 3 * 2 + HASS_COLOR_MIN
TEMP_COLD_HASS = (HASS_COLOR_MAX - HASS_COLOR_MIN) / 3 + HASS_COLOR_MIN
TEMP_COLOR_MAX = 500 # mireds (inverted)
TEMP_COLOR_MIN = 154
TEMP_MID_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 2 + TEMP_COLOR_MIN
TEMP_WARM_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 3 * 2 + TEMP_COLOR_MIN
TEMP_COLD_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 3 + TEMP_COLOR_MIN
def get_device(node, values, node_config, **kwargs):

View file

@ -17,7 +17,7 @@ from homeassistant.const import CONF_NAME, CONF_PLATFORM
from homeassistant.helpers.event import track_time_change
from homeassistant.util.color import (
color_temperature_to_rgb, color_RGB_to_xy,
color_temperature_kelvin_to_mired, HASS_COLOR_MIN, HASS_COLOR_MAX)
color_temperature_kelvin_to_mired)
from homeassistant.util.dt import now as dt_now
import homeassistant.helpers.config_validation as cv
@ -208,7 +208,6 @@ class FluxSwitch(SwitchDevice):
else:
# Convert to mired and clamp to allowed values
mired = color_temperature_kelvin_to_mired(temp)
mired = max(HASS_COLOR_MIN, min(mired, HASS_COLOR_MAX))
set_lights_temp(self.hass, self._lights, mired, brightness)
_LOGGER.info("Lights updated to mired:%s brightness:%s, %s%%"
" of %s cycle complete at %s", mired, brightness,

View file

@ -7,9 +7,6 @@ from typing import Tuple
_LOGGER = logging.getLogger(__name__)
HASS_COLOR_MAX = 500 # mireds (inverted)
HASS_COLOR_MIN = 154
# Official CSS3 colors from w3.org:
# https://www.w3.org/TR/2010/PR-css3-color-20101028/#html4
# names do not have spaces in them so that we can compare against

View file

@ -53,6 +53,8 @@ class TestDemoLight(unittest.TestCase):
self.hass.block_till_done()
state = self.hass.states.get(ENTITY_LIGHT)
self.assertEqual(400, state.attributes.get(light.ATTR_COLOR_TEMP))
self.assertEqual(154, state.attributes.get(light.ATTR_MIN_MIREDS))
self.assertEqual(500, state.attributes.get(light.ATTR_MAX_MIREDS))
self.assertEqual('none', state.attributes.get(light.ATTR_EFFECT))
def test_turn_off(self):