def __init__(self, device): """Initialize of KNX light.""" self.device = device self._min_kelvin = device.min_kelvin self._max_kelvin = device.max_kelvin self._min_mireds = \ color_util.color_temperature_kelvin_to_mired(self._max_kelvin) self._max_mireds = \ color_util.color_temperature_kelvin_to_mired(self._min_kelvin)
def flux_update(self, now=None): """Update all the lights using flux.""" if now is None: now = dt_now() sunset = next_setting(self.hass, SUN).replace(day=now.day, month=now.month, year=now.year) start_time = self.find_start_time(now) stop_time = now.replace(hour=self._stop_time.hour, minute=self._stop_time.minute, second=0) if start_time < now < sunset: # Daytime time_state = 'day' temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Nightime time_state = 'night' if now < stop_time and now > start_time: now_time = now else: now_time = stop_time temp_range = abs(self._sunset_colortemp - self._stop_colortemp) night_length = int(stop_time.timestamp() - sunset.timestamp()) seconds_from_sunset = int(now_time.timestamp() - sunset.timestamp()) percentage_complete = seconds_from_sunset / night_length temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset x_val, y_val, b_val = color_RGB_to_xy(*color_temperature_to_rgb(temp)) brightness = self._brightness if self._brightness else b_val if self._mode == MODE_XY: set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _LOGGER.info("Lights updated to x:%s y:%s brightness:%s, %s%%" " of %s cycle complete at %s", x_val, y_val, brightness, round( percentage_complete * 100), time_state, as_local(now)) 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, round(percentage_complete * 100), time_state, as_local(now))
def color_temp(self): """Return the color temperature.""" kelvin = self.device.color[3] temperature = color_util.color_temperature_kelvin_to_mired(kelvin) _LOGGER.debug("color_temp: %d", temperature) return temperature
def color_temp(self): """Return the CT color value in mireds.""" kelvin_color = self._light_data.kelvin_color_inferred if kelvin_color is not None: return color_util.color_temperature_kelvin_to_mired( kelvin_color )
def color_temp(self): """Return the color temperature in mireds.""" if self.device.supports_color_temperature: kelvin = self.device.current_color_temperature if kelvin is not None: return color_util.color_temperature_kelvin_to_mired(kelvin) if self.device.supports_tunable_white: relative_ct = self.device.current_tunable_white if relative_ct is not None: # as KNX devices typically use Kelvin we use it as base for # calculating ct from percent return color_util.color_temperature_kelvin_to_mired( self._min_kelvin + ( (relative_ct / 255) * (self._max_kelvin - self._min_kelvin))) return None
def preprocess_turn_on_alternatives(params): """Process extra data for turn light on request.""" profile = Profiles.get(params.pop(ATTR_PROFILE, None)) if profile is not None: params.setdefault(ATTR_XY_COLOR, profile[:2]) params.setdefault(ATTR_BRIGHTNESS, profile[2]) color_name = params.pop(ATTR_COLOR_NAME, None) if color_name is not None: try: params[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name) except ValueError: _LOGGER.warning('Got unknown color %s, falling back to white', color_name) params[ATTR_RGB_COLOR] = (255, 255, 255) kelvin = params.pop(ATTR_KELVIN, None) if kelvin is not None: mired = color_util.color_temperature_kelvin_to_mired(kelvin) params[ATTR_COLOR_TEMP] = int(mired) brightness_pct = params.pop(ATTR_BRIGHTNESS_PCT, None) if brightness_pct is not None: params[ATTR_BRIGHTNESS] = int(255 * brightness_pct/100) xy_color = params.pop(ATTR_XY_COLOR, None) if xy_color is not None: params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color) rgb_color = params.pop(ATTR_RGB_COLOR, None) if rgb_color is not None: params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
def max_mireds(self): """Return the warmest color_temp that this light supports.""" # The 3 LIFX "White" products supported a limited temperature range if self.lifxwhite: kelvin = 2700 else: kelvin = 2500 return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
def min_mireds(self): """Return the coldest color_temp that this light supports.""" # The 3 LIFX "White" products supported a limited temperature range if self.lifxwhite: kelvin = 6500 else: kelvin = 9000 return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin))
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._temp_supported): return None return color_util.color_temperature_kelvin_to_mired( self._light_data.kelvin_color )
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))
async def test_color_temperature_light(hass): """Test ColorTemperature trait support for light domain.""" assert not trait.ColorTemperatureTrait.supported(light.DOMAIN, 0) assert trait.ColorTemperatureTrait.supported(light.DOMAIN, light.SUPPORT_COLOR_TEMP) trt = trait.ColorTemperatureTrait(State('light.bla', STATE_ON, { light.ATTR_MIN_MIREDS: 200, light.ATTR_COLOR_TEMP: 300, light.ATTR_MAX_MIREDS: 500, })) assert trt.sync_attributes() == { 'temperatureMinK': 2000, 'temperatureMaxK': 5000, } assert trt.query_attributes() == { 'color': { 'temperature': 3333 } } assert trt.can_execute(trait.COMMAND_COLOR_ABSOLUTE, { 'color': { 'temperature': 400 } }) assert not trt.can_execute(trait.COMMAND_COLOR_ABSOLUTE, { 'color': { 'spectrumRGB': 16715792 } }) calls = async_mock_service(hass, light.DOMAIN, SERVICE_TURN_ON) with pytest.raises(helpers.SmartHomeError) as err: await trt.execute(hass, trait.COMMAND_COLOR_ABSOLUTE, { 'color': { 'temperature': 5555 } }) assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE await trt.execute(hass, trait.COMMAND_COLOR_ABSOLUTE, { 'color': { 'temperature': 2857 } }) assert len(calls) == 1 assert calls[0].data == { ATTR_ENTITY_ID: 'light.bla', light.ATTR_COLOR_TEMP: color.color_temperature_kelvin_to_mired(2857) }
def update(self): """Synchronize state with bridge.""" self.update_lights(no_throttle=True) self._brightness = int(self._light.lum() * 2.55) self._name = self._light.name() self._rgb = self._light.rgb() o_temp = self._light.temp() if o_temp == 0: self._temperature = None else: self._temperature = color_temperature_kelvin_to_mired(o_temp) self._state = self._light.on()
def update(self): """Update status of a light.""" super().update() self._state = self._luminary.on() self._rgb = self._luminary.rgb() o_temp = self._luminary.temp() if o_temp == 0: self._temperature = None else: self._temperature = color_temperature_kelvin_to_mired( self._luminary.temp()) self._brightness = int(self._luminary.lum() * 2.55)
def update(self): """Update group status.""" super().update() self._light_ids = self._luminary.lights() light = self._bridge.lights()[self._light_ids[0]] self._brightness = int(light.lum() * 2.55) self._rgb = light.rgb() o_temp = light.temp() if o_temp == 0: self._temperature = None else: self._temperature = color_temperature_kelvin_to_mired(o_temp) self._state = light.on()
def color_temp(self): """Return the CT color value in mireds.""" if (self._light_data.hex_color is None or self.supported_features & SUPPORT_COLOR_TEMP == 0 or not self._ok_temps): return None kelvin = next(( kelvin for kelvin, hex_color in self._ok_temps.items() if hex_color == self._light_data.hex_color), None) if kelvin is None: _LOGGER.error( "Unexpected color temperature found for %s: %s", self.name, self._light_data.hex_color) return return color_util.color_temperature_kelvin_to_mired(kelvin)
async def async_update(self): """Update entity attributes when the device status has changed.""" # Brightness and transition if self._supported_features & SUPPORT_BRIGHTNESS: self._brightness = convert_scale( self._device.status.level, 100, 255) # Color Temperature if self._supported_features & SUPPORT_COLOR_TEMP: self._color_temp = color_util.color_temperature_kelvin_to_mired( self._device.status.color_temperature) # Color if self._supported_features & SUPPORT_COLOR: self._hs_color = ( convert_scale(self._device.status.hue, 100, 360), self._device.status.saturation )
async def execute(self, command, params): """Execute a color temperature command.""" temp = color_util.color_temperature_kelvin_to_mired( params['color']['temperature']) min_temp = self.state.attributes[light.ATTR_MIN_MIREDS] max_temp = self.state.attributes[light.ATTR_MAX_MIREDS] if temp < min_temp or temp > max_temp: raise SmartHomeError( ERR_VALUE_OUT_OF_RANGE, "Temperature should be between {} and {}".format(min_temp, max_temp)) await self.hass.services.async_call(light.DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: self.state.entity_id, light.ATTR_COLOR_TEMP: temp, }, blocking=True)
def preprocess_turn_on_alternatives(params): """Processing extra data for turn light on request.""" profile = Profiles.get(params.pop(ATTR_PROFILE, None)) if profile is not None: params.setdefault(ATTR_XY_COLOR, profile[:2]) params.setdefault(ATTR_BRIGHTNESS, profile[2]) color_name = params.pop(ATTR_COLOR_NAME, None) if color_name is not None: params[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name) kelvin = params.pop(ATTR_KELVIN, None) if kelvin is not None: mired = color_util.color_temperature_kelvin_to_mired(kelvin) params[ATTR_COLOR_TEMP] = int(mired) brightness_pct = params.pop(ATTR_BRIGHTNESS_PCT, None) if brightness_pct is not None: params[ATTR_BRIGHTNESS] = int(255 * brightness_pct/100)
async def execute(self, command, data, params, challenge): """Execute a color temperature command.""" if 'temperature' in params['color']: temp = color_util.color_temperature_kelvin_to_mired( params['color']['temperature']) min_temp = self.state.attributes[light.ATTR_MIN_MIREDS] max_temp = self.state.attributes[light.ATTR_MAX_MIREDS] if temp < min_temp or temp > max_temp: raise SmartHomeError( ERR_VALUE_OUT_OF_RANGE, "Temperature should be between {} and {}".format(min_temp, max_temp)) await self.hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: self.state.entity_id, light.ATTR_COLOR_TEMP: temp, }, blocking=True, context=data.context) elif 'spectrumRGB' in params['color']: # Convert integer to hex format and left pad with 0's till length 6 hex_value = "{0:06x}".format(params['color']['spectrumRGB']) color = color_util.color_RGB_to_hs( *color_util.rgb_hex_to_rgb_list(hex_value)) await self.hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: self.state.entity_id, light.ATTR_HS_COLOR: color }, blocking=True, context=data.context) elif 'spectrumHSV' in params['color']: color = params['color']['spectrumHSV'] saturation = color['saturation'] * 100 brightness = color['value'] * 255 await self.hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: self.state.entity_id, light.ATTR_HS_COLOR: [color['hue'], saturation], light.ATTR_BRIGHTNESS: brightness }, blocking=True, context=data.context)
return if ATTR_PROFILE in params: hass.data[DATA_PROFILES].apply_profile(params.pop(ATTR_PROFILE), params) if (color_name := params.pop(ATTR_COLOR_NAME, None)) is not None: try: params[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name) except ValueError: _LOGGER.warning("Got unknown color %s, falling back to white", color_name) params[ATTR_RGB_COLOR] = (255, 255, 255) if (kelvin := params.pop(ATTR_KELVIN, None)) is not None: mired = color_util.color_temperature_kelvin_to_mired(kelvin) params[ATTR_COLOR_TEMP] = int(mired) brightness_pct = params.pop(ATTR_BRIGHTNESS_PCT, None) if brightness_pct is not None: params[ATTR_BRIGHTNESS] = round(255 * brightness_pct / 100) def filter_turn_off_params(light, params): """Filter out params not used in turn off or not supported by the light.""" supported_features = light.supported_features if not supported_features & LightEntityFeature.FLASH: params.pop(ATTR_FLASH, None) if not supported_features & LightEntityFeature.TRANSITION: params.pop(ATTR_TRANSITION, None)
def color_temp(self): """Return the current color temperature.""" if self._color_temp is not None: return color_util.color_temperature_kelvin_to_mired( self._color_temp) return None
def color_temp(self): """Return the color temperature.""" _, sat, _, kelvin = self.bulb.color if sat: return None return color_util.color_temperature_kelvin_to_mired(kelvin)
def color_temp(self): """Return the current color temperature.""" if self._color_temp is not None: return color_util.color_temperature_kelvin_to_mired( self._color_temp) return None
def max_mireds(self): """Return the warmest color_temp that this light supports.""" if self._light_control.min_kelvin is not None: return color_util.color_temperature_kelvin_to_mired( self._light_control.min_kelvin )
def color_temp(self): """Return the color temperature.""" temperature = color_temperature_kelvin_to_mired(self._kel) _LOGGER.debug("color_temp: %d", temperature) return temperature
def test_color_temperature_kelvin_to_mired(): """Test color_temperature_kelvin_to_mired.""" assert color_util.color_temperature_kelvin_to_mired(25000) == 40 assert color_util.color_temperature_kelvin_to_mired(5000) == 200 with pytest.raises(ZeroDivisionError): assert color_util.color_temperature_kelvin_to_mired(0)
def test_should_return_200_mired_when_input_is_5000_kelvin(self): """Function should return 200 mired when given 5000 Kelvin.""" mired = color_util.color_temperature_kelvin_to_mired(5000) assert 200 == mired
def min_mireds(self): """Return the coldest color_temp that this light supports.""" return math.floor(color_util.color_temperature_kelvin_to_mired(9000))
def test_should_return_40_mired_when_input_is_25000_kelvin(self): """Function should return 40 mired when given 25000 Kelvin.""" mired = color_util.color_temperature_kelvin_to_mired(25000) self.assertEqual(40, mired)
def test_should_return_200_mired_when_input_is_5000_kelvin(self): """Function should return 200 mired when given 5000 Kelvin.""" mired = color_util.color_temperature_kelvin_to_mired(5000) self.assertEqual(200, mired)
def color_temp(self): """Return the color temperature.""" _, sat, _, kelvin = self.device.color if sat: return None return color_util.color_temperature_kelvin_to_mired(kelvin)
def flux_update(self, now=None): """Update all the lights using flux.""" if now is None: now = dt_now() sunset = get_astral_event_date(self.hass, 'sunset', now.date()) start_time = self.find_start_time(now) stop_time = now.replace(hour=self._stop_time.hour, minute=self._stop_time.minute, second=0) if start_time < now < sunset: # Daytime time_state = 'day' temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Nightime time_state = 'night' if now < stop_time and now > start_time: now_time = now else: now_time = stop_time temp_range = abs(self._sunset_colortemp - self._stop_colortemp) night_length = int(stop_time.timestamp() - sunset.timestamp()) seconds_from_sunset = int(now_time.timestamp() - sunset.timestamp()) percentage_complete = seconds_from_sunset / night_length temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset rgb = color_temperature_to_rgb(temp) x_val, y_val, b_val = color_RGB_to_xy(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None if self._mode == MODE_XY: set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _LOGGER.info( "Lights updated to x:%s y:%s brightness:%s, %s%% " "of %s cycle complete at %s", x_val, y_val, brightness, round(percentage_complete * 100), time_state, now) elif self._mode == MODE_RGB: set_lights_rgb(self.hass, self._lights, rgb) _LOGGER.info( "Lights updated to rgb:%s, %s%% " "of %s cycle complete at %s", rgb, round(percentage_complete * 100), time_state, now) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) 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, round(percentage_complete * 100), time_state, now)
def min_mireds(self): """Return the coldest color_temp that this light supports.""" kelvin = lifx_features(self.bulb)['max_kelvin'] return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin))
def min_mireds(self) -> float: """Return the coldest color_temp that this light supports.""" return color_temperature_kelvin_to_mired(6500)
def color_temp(self): """Return the current color temperature.""" return color_util.color_temperature_kelvin_to_mired( self._nanoleaf.color_temperature )
def max_mireds(self): """Return the warmest color_temp that this light supports.""" return math.ceil(color_util.color_temperature_kelvin_to_mired(2700))
def max_mireds(self): """Return maximum supported color temperature.""" return color_util.color_temperature_kelvin_to_mired(2500)
def calc_ct(self): if self.is_sleep(): _LOGGER.debug(self._name + " in Sleep mode") return color_temperature_kelvin_to_mired(self._sleep_colortemp) else: return color_temperature_kelvin_to_mired(self._cl.data['colortemp'])
def color_temp(self): """Return the color temperature.""" return color_util.color_temperature_kelvin_to_mired(self._color_temp)
def color_temp(self) -> int: """Return the kelvin value of this light in mired.""" return color_temperature_kelvin_to_mired(self._device.color_temp)
def min_mireds(self): """Return the coldest color_temp that this light supports.""" return math.ceil(color_util.color_temperature_kelvin_to_mired( self._lamp.max_kelvin))
def max_mireds(self): """Return the warmest color_temp that this light supports.""" kelvin = lifx_features(self.device)['min_kelvin'] return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
def flux_update(self, now=None): """Update all the lights using flux.""" if now is None: now = dt_now() sunset = get_astral_event_date(self.hass, 'sunset', now.date()) start_time = self.find_start_time(now) stop_time = now.replace(hour=self._stop_time.hour, minute=self._stop_time.minute, second=0) if stop_time <= start_time: # stop_time does not happen in the same day as start_time if start_time < now: # stop time is tomorrow stop_time += datetime.timedelta(days=1) elif now < start_time: # stop_time was yesterday since the new start_time is not reached stop_time -= datetime.timedelta(days=1) if start_time < now < sunset: # Daytime time_state = 'day' temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Nightime time_state = 'night' if now < stop_time: if stop_time < start_time and stop_time.day == sunset.day: # we need to use yesterday's sunset time sunset_time = sunset - datetime.timedelta(days=1) else: sunset_time = sunset # pylint: disable=no-member night_length = int(stop_time.timestamp() - sunset_time.timestamp()) seconds_from_sunset = int(now.timestamp() - sunset_time.timestamp()) percentage_complete = seconds_from_sunset / night_length else: percentage_complete = 1 temp_range = abs(self._sunset_colortemp - self._stop_colortemp) temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset rgb = color_temperature_to_rgb(temp) x_val, y_val, b_val = color_RGB_to_xy(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None if self._mode == MODE_XY: set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _LOGGER.info( "Lights updated to x:%s y:%s brightness:%s, %s%% " "of %s cycle complete at %s", x_val, y_val, brightness, round(percentage_complete * 100), time_state, now) elif self._mode == MODE_RGB: set_lights_rgb(self.hass, self._lights, rgb) _LOGGER.info( "Lights updated to rgb:%s, %s%% " "of %s cycle complete at %s", rgb, round(percentage_complete * 100), time_state, now) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) 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, round(percentage_complete * 100), time_state, now)
async def async_flux_update(self, utcnow=None): """Update all the lights using flux.""" if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) sunset = get_astral_event_date(self.hass, SUN_EVENT_SUNSET, now.date()) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) if stop_time <= start_time: # stop_time does not happen in the same day as start_time if start_time < now: # stop time is tomorrow stop_time += datetime.timedelta(days=1) elif now < start_time: # stop_time was yesterday since the new start_time is not reached stop_time -= datetime.timedelta(days=1) if start_time < now < sunset: # Daytime time_state = "day" temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Night time time_state = "night" if now < stop_time: if stop_time < start_time and stop_time.day == sunset.day: # we need to use yesterday's sunset time sunset_time = sunset - datetime.timedelta(days=1) else: sunset_time = sunset night_length = int(stop_time.timestamp() - sunset_time.timestamp()) seconds_from_sunset = int(now.timestamp() - sunset_time.timestamp()) percentage_complete = seconds_from_sunset / night_length else: percentage_complete = 1 temp_range = abs(self._sunset_colortemp - self._stop_colortemp) temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset rgb = color_temperature_to_rgb(temp) x_val, y_val, b_val = color_RGB_to_xy_brightness(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None if self._mode == MODE_XY: await async_set_lights_xy(self.hass, self._lights, x_val, y_val, brightness, self._transition) _LOGGER.debug( "Lights updated to x:%s y:%s brightness:%s, %s%% " "of %s cycle complete at %s", x_val, y_val, brightness, round(percentage_complete * 100), time_state, now, ) elif self._mode == MODE_RGB: await async_set_lights_rgb(self.hass, self._lights, rgb, self._transition) _LOGGER.debug( "Lights updated to rgb:%s, %s%% of %s cycle complete at %s", rgb, round(percentage_complete * 100), time_state, now, ) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) await async_set_lights_temp(self.hass, self._lights, mired, brightness, self._transition) _LOGGER.debug( "Lights updated to mired:%s brightness:%s, %s%% " "of %s cycle complete at %s", mired, brightness, round(percentage_complete * 100), time_state, now, )
def color_temp(self): """Return the color_temp of the light.""" if not self._device.color_temp: return None return color.color_temperature_kelvin_to_mired(self._device.color_temp)
def max_mireds(self): """Return the warmest color_temp that this light supports.""" kelvin = lifx_features(self.bulb)["min_kelvin"] return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
def max_mireds(self): """Return the warmest color_temp that this light supports.""" return color.color_temperature_kelvin_to_mired(COLOR_TEMP_KELVIN_MIN)
def _async_update_attrs(self) -> None: """Update attrs from device.""" super()._async_update_attrs() self._attr_color_temp = color_temperature_kelvin_to_mired( self._device.light_color_temperature)
async def test_device_types(hass: HomeAssistant): """Test different device types.""" properties = {**PROPERTIES} properties.pop("active_mode") properties["color_mode"] = "3" def _create_mocked_bulb(bulb_type, model, unique_id): capabilities = {**CAPABILITIES} capabilities["id"] = f"yeelight.{unique_id}" mocked_bulb = _mocked_bulb() mocked_bulb.bulb_type = bulb_type mocked_bulb.last_properties = properties mocked_bulb.capabilities = capabilities model_specs = _MODEL_SPECS.get(model) type(mocked_bulb).get_model_specs = MagicMock(return_value=model_specs) return mocked_bulb types = { "default": (None, "mono"), "white": (BulbType.White, "mono"), "color": (BulbType.Color, "color"), "white_temp": (BulbType.WhiteTemp, "ceiling1"), "white_temp_mood": (BulbType.WhiteTempMood, "ceiling4"), "ambient": (BulbType.WhiteTempMood, "ceiling4"), } devices = {} mocked_bulbs = [] unique_id = 0 for name, (bulb_type, model) in types.items(): devices[f"{name}.yeelight"] = {CONF_NAME: name} devices[f"{name}_nightlight.yeelight"] = { CONF_NAME: f"{name}_nightlight", CONF_NIGHTLIGHT_SWITCH_TYPE: NIGHTLIGHT_SWITCH_TYPE_LIGHT, } mocked_bulbs.append(_create_mocked_bulb(bulb_type, model, unique_id)) mocked_bulbs.append( _create_mocked_bulb(bulb_type, model, unique_id + 1)) unique_id += 2 with patch(f"{MODULE}.Bulb", side_effect=mocked_bulbs): await async_setup_component(hass, DOMAIN, {DOMAIN: { CONF_DEVICES: devices }}) await hass.async_block_till_done() async def _async_test( name, bulb_type, model, target_properties, nightlight_properties=None, entity_name=None, entity_id=None, ): if entity_id is None: entity_id = f"light.{name}" state = hass.states.get(entity_id) assert state.state == "on" target_properties["friendly_name"] = entity_name or name target_properties["flowing"] = False target_properties["night_light"] = True assert dict(state.attributes) == target_properties # nightlight if nightlight_properties is None: return name += "_nightlight" entity_id = f"light.{name}" assert hass.states.get(entity_id).state == "off" state = hass.states.get(f"{entity_id}_nightlight") assert state.state == "on" nightlight_properties["friendly_name"] = f"{name} nightlight" nightlight_properties["icon"] = "mdi:weather-night" nightlight_properties["flowing"] = False nightlight_properties["night_light"] = True assert dict(state.attributes) == nightlight_properties bright = round(255 * int(PROPERTIES["bright"]) / 100) current_brightness = round(255 * int(PROPERTIES["current_brightness"]) / 100) ct = color_temperature_kelvin_to_mired(int(PROPERTIES["ct"])) hue = int(PROPERTIES["hue"]) sat = int(PROPERTIES["sat"]) hs_color = (round(hue / 360 * 65536, 3), round(sat / 100 * 255, 3)) rgb_color = color_hs_to_RGB(*hs_color) xy_color = color_hs_to_xy(*hs_color) bg_bright = round(255 * int(PROPERTIES["bg_bright"]) / 100) bg_ct = color_temperature_kelvin_to_mired(int(PROPERTIES["bg_ct"])) bg_rgb = int(PROPERTIES["bg_rgb"]) bg_rgb_color = ((bg_rgb >> 16) & 0xFF, (bg_rgb >> 8) & 0xFF, bg_rgb & 0xFF) bg_hs_color = color_RGB_to_hs(*bg_rgb_color) bg_xy_color = color_RGB_to_xy(*bg_rgb_color) nl_br = round(255 * int(PROPERTIES["nl_br"]) / 100) # Default await _async_test( "default", None, "mono", { "effect_list": YEELIGHT_MONO_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": bright, }, ) # White await _async_test( "white", BulbType.White, "mono", { "effect_list": YEELIGHT_MONO_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": bright, }, ) # Color model_specs = _MODEL_SPECS["color"] await _async_test( "color", BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT_RGB, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"]), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"]), "brightness": current_brightness, "color_temp": ct, "hs_color": hs_color, "rgb_color": rgb_color, "xy_color": xy_color, }, {"supported_features": 0}, ) # WhiteTemp model_specs = _MODEL_SPECS["ceiling1"] await _async_test( "white_temp", BulbType.WhiteTemp, "ceiling1", { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT_WHITE_TEMP, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"]), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"]), "brightness": current_brightness, "color_temp": ct, }, { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": nl_br, }, ) # WhiteTempMood model_specs = _MODEL_SPECS["ceiling4"] await _async_test( "white_temp_mood", BulbType.WhiteTempMood, "ceiling4", { "friendly_name": NAME, "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "flowing": False, "night_light": True, "supported_features": SUPPORT_YEELIGHT_WHITE_TEMP, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"]), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"]), "brightness": current_brightness, "color_temp": ct, }, { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": nl_br, }, ) await _async_test( "ambient", BulbType.WhiteTempMood, "ceiling4", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT_RGB, "min_mireds": color_temperature_kelvin_to_mired(6500), "max_mireds": color_temperature_kelvin_to_mired(1700), "brightness": bg_bright, "color_temp": bg_ct, "hs_color": bg_hs_color, "rgb_color": bg_rgb_color, "xy_color": bg_xy_color, }, entity_name="ambient ambilight", entity_id="light.ambient_ambilight", )
def color_temp(self): """Return the color temperature.""" temperature = color_temperature_kelvin_to_mired(self._kel) _LOGGER.debug("color_temp: %d", temperature) return temperature
def color_temp(self): """Return the color temperature.""" return color_util.color_temperature_kelvin_to_mired( self._lamp.state()['white'])
def max_mireds(self) -> float: """Return the warmest color_temp that this light supports.""" return color_temperature_kelvin_to_mired(2700)
def max_mireds(self): """Return the warmest color_temp that this light supports.""" return math.ceil(color_util.color_temperature_kelvin_to_mired( self._lamp.min_kelvin))
def min_mireds(self): """Return the coldest color_temp that this light supports.""" return math.floor(color_util.color_temperature_kelvin_to_mired(9000))
def color_temp(self): """Define current bulb color in degrees Kelvin.""" if not self.wink.supports_temperature(): return None return color_util.color_temperature_kelvin_to_mired( self.wink.color_temperature_kelvin())
def color_temp(self): """Return the color_temp of the light.""" color_temp = int(self._tuya.color_temp()) if color_temp is None: return None return colorutil.color_temperature_kelvin_to_mired(color_temp)
async def test_device_types(hass: HomeAssistant, caplog): """Test different device types.""" mocked_bulb = _mocked_bulb() properties = {**PROPERTIES} properties.pop("active_mode") properties["color_mode"] = "3" # HSV mocked_bulb.last_properties = properties async def _async_setup(config_entry): with patch(f"{MODULE}.AsyncBulb", return_value=mocked_bulb): assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() # We use asyncio.create_task now to avoid # blocking starting so we need to block again await hass.async_block_till_done() async def _async_test( bulb_type, model, target_properties, nightlight_properties=None, name=UNIQUE_FRIENDLY_NAME, entity_id=ENTITY_LIGHT, ): config_entry = MockConfigEntry( domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: False} ) config_entry.add_to_hass(hass) mocked_bulb.bulb_type = bulb_type model_specs = _MODEL_SPECS.get(model) type(mocked_bulb).get_model_specs = MagicMock(return_value=model_specs) await _async_setup(config_entry) state = hass.states.get(entity_id) assert state.state == "on" target_properties["friendly_name"] = name target_properties["flowing"] = False target_properties["night_light"] = True target_properties["music_mode"] = False assert dict(state.attributes) == target_properties await hass.config_entries.async_unload(config_entry.entry_id) await config_entry.async_remove(hass) registry = er.async_get(hass) registry.async_clear_config_entry(config_entry.entry_id) # nightlight if nightlight_properties is None: return config_entry = MockConfigEntry( domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: True} ) config_entry.add_to_hass(hass) await _async_setup(config_entry) assert hass.states.get(entity_id).state == "off" state = hass.states.get(f"{entity_id}_nightlight") assert state.state == "on" nightlight_properties["friendly_name"] = f"{name} Nightlight" nightlight_properties["icon"] = "mdi:weather-night" nightlight_properties["flowing"] = False nightlight_properties["night_light"] = True nightlight_properties["music_mode"] = False assert dict(state.attributes) == nightlight_properties await hass.config_entries.async_unload(config_entry.entry_id) await config_entry.async_remove(hass) registry.async_clear_config_entry(config_entry.entry_id) await hass.async_block_till_done() bright = round(255 * int(PROPERTIES["bright"]) / 100) current_brightness = round(255 * int(PROPERTIES["current_brightness"]) / 100) ct = color_temperature_kelvin_to_mired(int(PROPERTIES["ct"])) hue = int(PROPERTIES["hue"]) sat = int(PROPERTIES["sat"]) rgb = int(PROPERTIES["rgb"]) rgb_color = ((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF) hs_color = (hue, sat) bg_bright = round(255 * int(PROPERTIES["bg_bright"]) / 100) bg_ct = color_temperature_kelvin_to_mired(int(PROPERTIES["bg_ct"])) bg_hue = int(PROPERTIES["bg_hue"]) bg_sat = int(PROPERTIES["bg_sat"]) bg_rgb = int(PROPERTIES["bg_rgb"]) bg_hs_color = (bg_hue, bg_sat) bg_rgb_color = ((bg_rgb >> 16) & 0xFF, (bg_rgb >> 8) & 0xFF, bg_rgb & 0xFF) nl_br = round(255 * int(PROPERTIES["nl_br"]) / 100) # Default await _async_test( None, "mono", { "effect_list": YEELIGHT_MONO_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": bright, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, ) # White await _async_test( BulbType.White, "mono", { "effect_list": YEELIGHT_MONO_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": bright, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, ) # Color - color mode CT mocked_bulb.last_properties["color_mode"] = "2" # CT model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp", "hs", "rgb"], "hs_color": (26.812, 34.87), "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) # Color - color mode HS mocked_bulb.last_properties["color_mode"] = "3" # HSV model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "hs_color": hs_color, "rgb_color": color_hs_to_RGB(*hs_color), "xy_color": color_hs_to_xy(*hs_color), "color_mode": "hs", "supported_color_modes": ["color_temp", "hs", "rgb"], }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) # Color - color mode RGB mocked_bulb.last_properties["color_mode"] = "1" # RGB model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "hs_color": color_RGB_to_hs(*rgb_color), "rgb_color": rgb_color, "xy_color": color_RGB_to_xy(*rgb_color), "color_mode": "rgb", "supported_color_modes": ["color_temp", "hs", "rgb"], }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) # Color - color mode HS but no hue mocked_bulb.last_properties["color_mode"] = "3" # HSV mocked_bulb.last_properties["hue"] = None model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "color_mode": "hs", "supported_color_modes": ["color_temp", "hs", "rgb"], }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) # Color - color mode RGB but no color mocked_bulb.last_properties["color_mode"] = "1" # RGB mocked_bulb.last_properties["rgb"] = None model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "color_mode": "rgb", "supported_color_modes": ["color_temp", "hs", "rgb"], }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) # Color - unsupported color_mode mocked_bulb.last_properties["color_mode"] = 4 # Unsupported model_specs = _MODEL_SPECS["color"] await _async_test( BulbType.Color, "color", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "color_mode": "unknown", "supported_color_modes": ["color_temp", "hs", "rgb"], }, { "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, ) assert "Light reported unknown color mode: 4" in caplog.text # WhiteTemp model_specs = _MODEL_SPECS["ceiling1"] await _async_test( BulbType.WhiteTemp, "ceiling1", { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp"], "hs_color": (26.812, 34.87), "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": nl_br, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, ) # WhiteTempMood properties.pop("power") properties["main_power"] = "on" model_specs = _MODEL_SPECS["ceiling4"] await _async_test( BulbType.WhiteTempMood, "ceiling4", { "friendly_name": NAME, "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "flowing": False, "night_light": True, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["max"] ), "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), "brightness": current_brightness, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp"], "hs_color": (26.812, 34.87), "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, { "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "brightness": nl_br, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, ) # Background light - color mode CT mocked_bulb.last_properties["bg_lmode"] = "2" # CT await _async_test( BulbType.WhiteTempMood, "ceiling4", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired(6500), "max_mireds": color_temperature_kelvin_to_mired(1700), "brightness": bg_bright, "color_temp": bg_ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp", "hs", "rgb"], "hs_color": (27.001, 19.243), "rgb_color": (255, 228, 205), "xy_color": (0.372, 0.35), }, name=f"{UNIQUE_FRIENDLY_NAME} Ambilight", entity_id=f"{ENTITY_LIGHT}_ambilight", ) # Background light - color mode HS mocked_bulb.last_properties["bg_lmode"] = "3" # HS await _async_test( BulbType.WhiteTempMood, "ceiling4", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired(6500), "max_mireds": color_temperature_kelvin_to_mired(1700), "brightness": bg_bright, "hs_color": bg_hs_color, "rgb_color": color_hs_to_RGB(*bg_hs_color), "xy_color": color_hs_to_xy(*bg_hs_color), "color_mode": "hs", "supported_color_modes": ["color_temp", "hs", "rgb"], }, name=f"{UNIQUE_FRIENDLY_NAME} Ambilight", entity_id=f"{ENTITY_LIGHT}_ambilight", ) # Background light - color mode RGB mocked_bulb.last_properties["bg_lmode"] = "1" # RGB await _async_test( BulbType.WhiteTempMood, "ceiling4", { "effect_list": YEELIGHT_COLOR_EFFECT_LIST, "supported_features": SUPPORT_YEELIGHT, "min_mireds": color_temperature_kelvin_to_mired(6500), "max_mireds": color_temperature_kelvin_to_mired(1700), "brightness": bg_bright, "hs_color": color_RGB_to_hs(*bg_rgb_color), "rgb_color": bg_rgb_color, "xy_color": color_RGB_to_xy(*bg_rgb_color), "color_mode": "rgb", "supported_color_modes": ["color_temp", "hs", "rgb"], }, name=f"{UNIQUE_FRIENDLY_NAME} Ambilight", entity_id=f"{ENTITY_LIGHT}_ambilight", )
def color_temp(self): """Return the color temp of the light.""" if self._device.has_color: return color_temperature_kelvin_to_mired(self._device.color_temp)
def max_mireds(self): """Return color temperature max mireds.""" return colorutil.color_temperature_kelvin_to_mired(self._min_kelvin)