Support yeelight color light with nightlight (#30194)

* Support color light with nightlight

* Better nightlight mode support check

* Lint fixes

* Remove brightness control for color light with nightlight mode
pull/30727/head
zewelor 2020-01-13 06:03:48 +01:00 committed by Teemu R
parent 96c11bc6d7
commit ce13fb8d73
2 changed files with 94 additions and 22 deletions

View File

@ -237,21 +237,30 @@ class YeelightDevice:
"""Return configured device model.""" """Return configured device model."""
return self._model return self._model
@property
def is_nightlight_enabled(self) -> bool:
"""Return true / false if nightlight is currently enabled."""
if self.bulb is None:
return False
return self._active_mode == ACTIVE_MODE_NIGHTLIGHT
@property @property
def is_nightlight_supported(self) -> bool: def is_nightlight_supported(self) -> bool:
"""Return true / false if nightlight is supported.""" """Return true / false if nightlight is supported."""
if self.model: if self.model:
return self.bulb.get_model_specs().get("night_light", False) return self.bulb.get_model_specs().get("night_light", False)
return self._active_mode is not None # It should support both ceiling and other lights
return self._nightlight_brightness is not None
@property
def is_nightlight_enabled(self) -> bool:
"""Return true / false if nightlight is currently enabled."""
if self.bulb is None:
return False
# Only ceiling lights have active_mode, from SDK docs:
# active_mode 0: daylight mode / 1: moonlight mode (ceiling light only)
if self._active_mode is not None:
return self._active_mode == ACTIVE_MODE_NIGHTLIGHT
if self._nightlight_brightness is not None:
return int(self._nightlight_brightness) > 0
return False
@property @property
def is_color_flow_enabled(self) -> bool: def is_color_flow_enabled(self) -> bool:
@ -266,6 +275,10 @@ class YeelightDevice:
def _color_flow(self): def _color_flow(self):
return self.bulb.last_properties.get("flowing") return self.bulb.last_properties.get("flowing")
@property
def _nightlight_brightness(self):
return self.bulb.last_properties.get("nl_br")
@property @property
def type(self): def type(self):
"""Return bulb type.""" """Return bulb type."""

View File

@ -134,6 +134,7 @@ MODEL_TO_DEVICE_TYPE = {
"color2": BulbType.Color, "color2": BulbType.Color,
"strip1": BulbType.Color, "strip1": BulbType.Color,
"bslamp1": BulbType.Color, "bslamp1": BulbType.Color,
"bslamp2": BulbType.Color,
"RGBW": BulbType.Color, "RGBW": BulbType.Color,
"lamp1": BulbType.WhiteTemp, "lamp1": BulbType.WhiteTemp,
"ceiling1": BulbType.WhiteTemp, "ceiling1": BulbType.WhiteTemp,
@ -281,7 +282,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
if device_type == BulbType.White: if device_type == BulbType.White:
_lights_setup_helper(YeelightGenericLight) _lights_setup_helper(YeelightGenericLight)
elif device_type == BulbType.Color: elif device_type == BulbType.Color:
_lights_setup_helper(YeelightColorLight) if nl_switch_light and device.is_nightlight_supported:
_lights_setup_helper(YeelightColorLightWithNightlightSwitch)
_lights_setup_helper(YeelightNightLightModeWithWithoutBrightnessControl)
else:
_lights_setup_helper(YeelightColorLightWithoutNightlightSwitch)
elif device_type == BulbType.WhiteTemp: elif device_type == BulbType.WhiteTemp:
if nl_switch_light and device.is_nightlight_supported: if nl_switch_light and device.is_nightlight_supported:
_lights_setup_helper(YeelightWithNightLight) _lights_setup_helper(YeelightWithNightLight)
@ -290,7 +295,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
_lights_setup_helper(YeelightWhiteTempWithoutNightlightSwitch) _lights_setup_helper(YeelightWhiteTempWithoutNightlightSwitch)
elif device_type == BulbType.WhiteTempMood: elif device_type == BulbType.WhiteTempMood:
if nl_switch_light and device.is_nightlight_supported: if nl_switch_light and device.is_nightlight_supported:
_lights_setup_helper(YeelightNightLightMode) _lights_setup_helper(YeelightNightLightModeWithAmbientSupport)
_lights_setup_helper(YeelightWithAmbientAndNightlight) _lights_setup_helper(YeelightWithAmbientAndNightlight)
else: else:
_lights_setup_helper(YeelightWithAmbientWithoutNightlight) _lights_setup_helper(YeelightWithAmbientWithoutNightlight)
@ -808,8 +813,8 @@ class YeelightGenericLight(Light):
_LOGGER.error("Unable to set scene: %s", ex) _LOGGER.error("Unable to set scene: %s", ex)
class YeelightColorLight(YeelightGenericLight): class YeelightColorLightSupport:
"""Representation of a Color Yeelight light.""" """Representation of a Color Yeelight light support."""
@property @property
def supported_features(self) -> int: def supported_features(self) -> int:
@ -821,7 +826,7 @@ class YeelightColorLight(YeelightGenericLight):
return YEELIGHT_COLOR_EFFECT_LIST return YEELIGHT_COLOR_EFFECT_LIST
class YeelightWhiteTempLightsupport: class YeelightWhiteTempLightSupport:
"""Representation of a Color Yeelight light.""" """Representation of a Color Yeelight light."""
@property @property
@ -834,18 +839,28 @@ class YeelightWhiteTempLightsupport:
return YEELIGHT_TEMP_ONLY_EFFECT_LIST return YEELIGHT_TEMP_ONLY_EFFECT_LIST
class YeelightWhiteTempWithoutNightlightSwitch( class YeelightNightLightSupport:
YeelightWhiteTempLightsupport, YeelightGenericLight """Representation of a Yeelight nightlight support."""
@property
def _turn_on_power_mode(self):
return PowerMode.NORMAL
class YeelightColorLightWithoutNightlightSwitch(
YeelightColorLightSupport, YeelightGenericLight
): ):
"""White temp light, when nightlight switch is not set to light.""" """Representation of a Color Yeelight light."""
@property @property
def _brightness_property(self): def _brightness_property(self):
return "current_brightness" return "current_brightness"
class YeelightWithNightLight(YeelightWhiteTempLightsupport, YeelightGenericLight): class YeelightColorLightWithNightlightSwitch(
"""Representation of a Yeelight with nightlight support. YeelightNightLightSupport, YeelightColorLightSupport, YeelightGenericLight
):
"""Representation of a Yeelight with rgb support and nightlight.
It represents case when nightlight switch is set to light. It represents case when nightlight switch is set to light.
""" """
@ -855,9 +870,29 @@ class YeelightWithNightLight(YeelightWhiteTempLightsupport, YeelightGenericLight
"""Return true if device is on.""" """Return true if device is on."""
return super().is_on and not self.device.is_nightlight_enabled return super().is_on and not self.device.is_nightlight_enabled
class YeelightWhiteTempWithoutNightlightSwitch(
YeelightWhiteTempLightSupport, YeelightGenericLight
):
"""White temp light, when nightlight switch is not set to light."""
@property @property
def _turn_on_power_mode(self): def _brightness_property(self):
return PowerMode.NORMAL return "current_brightness"
class YeelightWithNightLight(
YeelightNightLightSupport, YeelightWhiteTempLightSupport, YeelightGenericLight
):
"""Representation of a Yeelight with temp only support and nightlight.
It represents case when nightlight switch is set to light.
"""
@property
def is_on(self) -> bool:
"""Return true if device is on."""
return super().is_on and not self.device.is_nightlight_enabled
class YeelightNightLightMode(YeelightGenericLight): class YeelightNightLightMode(YeelightGenericLight):
@ -891,6 +926,26 @@ class YeelightNightLightMode(YeelightGenericLight):
return YEELIGHT_TEMP_ONLY_EFFECT_LIST return YEELIGHT_TEMP_ONLY_EFFECT_LIST
class YeelightNightLightModeWithAmbientSupport(YeelightNightLightMode):
"""Representation of a Yeelight, with ambient support, when in nightlight mode."""
@property
def _power_property(self):
return "main_power"
class YeelightNightLightModeWithWithoutBrightnessControl(YeelightNightLightMode):
"""Representation of a Yeelight, when in nightlight mode.
It represents case when nightlight mode brightness control is not supported.
"""
@property
def supported_features(self):
"""Flag no supported features."""
return 0
class YeelightWithAmbientWithoutNightlight(YeelightWhiteTempWithoutNightlightSwitch): class YeelightWithAmbientWithoutNightlight(YeelightWhiteTempWithoutNightlightSwitch):
"""Representation of a Yeelight which has ambilight support. """Representation of a Yeelight which has ambilight support.
@ -913,7 +968,7 @@ class YeelightWithAmbientAndNightlight(YeelightWithNightLight):
return "main_power" return "main_power"
class YeelightAmbientLight(YeelightColorLight): class YeelightAmbientLight(YeelightColorLightWithoutNightlightSwitch):
"""Representation of a Yeelight ambient light.""" """Representation of a Yeelight ambient light."""
PROPERTIES_MAPPING = {"color_mode": "bg_lmode"} PROPERTIES_MAPPING = {"color_mode": "bg_lmode"}
@ -931,6 +986,10 @@ class YeelightAmbientLight(YeelightColorLight):
"""Return the name of the device if any.""" """Return the name of the device if any."""
return f"{self.device.name} ambilight" return f"{self.device.name} ambilight"
@property
def _brightness_property(self):
return "bright"
def _get_property(self, prop, default=None): def _get_property(self, prop, default=None):
bg_prop = self.PROPERTIES_MAPPING.get(prop) bg_prop = self.PROPERTIES_MAPPING.get(prop)