Exemplo n.º 1
0
 def limitlessled_temperature(self):
     """Convert Home Assistant color temperature units to percentage."""
     max_kelvin = color_temperature_mired_to_kelvin(self.min_mireds)
     min_kelvin = color_temperature_mired_to_kelvin(self.max_mireds)
     width = max_kelvin - min_kelvin
     kelvin = color_temperature_mired_to_kelvin(self._temperature)
     temperature = (kelvin - min_kelvin) / width
     return max(0, min(1, temperature))
Exemplo n.º 2
0
 def sync_attributes(self):
     """Return color temperature attributes for a sync request."""
     attrs = self.state.attributes
     return {
         'temperatureMinK': color_util.color_temperature_mired_to_kelvin(
             attrs.get(light.ATTR_MIN_MIREDS)),
         'temperatureMaxK': color_util.color_temperature_mired_to_kelvin(
             attrs.get(light.ATTR_MAX_MIREDS)),
     }
Exemplo n.º 3
0
    async def async_turn_on(self, **kwargs):
        """Turn the light on."""
        brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness)
        hs_color = kwargs.get(ATTR_HS_COLOR, self.hs_color)
        mireds = kwargs.get(ATTR_COLOR_TEMP, self.color_temp)

        update_brightness = ATTR_BRIGHTNESS in kwargs
        update_color = ATTR_HS_COLOR in kwargs
        update_color_temp = ATTR_COLOR_TEMP in kwargs

        # always only go one path for turning on (avoid conflicting changes
        # and weird effects)
        if self.device.supports_brightness and \
                (update_brightness and not update_color):
            # if we don't need to update the color, try updating brightness
            # directly if supported; don't do it if color also has to be
            # changed, as RGB color implicitly sets the brightness as well
            await self.device.set_brightness(brightness)
        elif self.device.supports_color and \
                (update_brightness or update_color):
            # change RGB color (includes brightness)
            # if brightness or hs_color was not yet set use the default value
            # to calculate RGB from as a fallback
            if brightness is None:
                brightness = DEFAULT_BRIGHTNESS
            if hs_color is None:
                hs_color = DEFAULT_COLOR
            await self.device.set_color(
                color_util.color_hsv_to_RGB(*hs_color, brightness * 100 / 255))
        elif self.device.supports_color_temperature and \
                update_color_temp:
            # change color temperature without ON telegram
            kelvin = int(color_util.color_temperature_mired_to_kelvin(mireds))
            if kelvin > self._max_kelvin:
                kelvin = self._max_kelvin
            elif kelvin < self._min_kelvin:
                kelvin = self._min_kelvin
            await self.device.set_color_temperature(kelvin)
        elif self.device.supports_tunable_white and \
                update_color_temp:
            # calculate relative_ct from Kelvin to fit typical KNX devices
            kelvin = int(color_util.color_temperature_mired_to_kelvin(mireds))
            relative_ct = int(255 * (kelvin - self._min_kelvin) /
                              (self._max_kelvin - self._min_kelvin))
            await self.device.set_tunable_white(relative_ct)
        else:
            # no color/brightness change requested, so just turn it on
            await self.device.set_on()
Exemplo n.º 4
0
    def query_attributes(self):
        """Return color temperature query attributes."""
        features = self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
        color = {}

        if features & light.SUPPORT_COLOR:
            color_hs = self.state.attributes.get(light.ATTR_HS_COLOR)
            brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1)
            if color_hs is not None:
                color['spectrumHsv'] = {
                    'hue': color_hs[0],
                    'saturation': color_hs[1]/100,
                    'value': brightness/255,
                }

        if features & light.SUPPORT_COLOR_TEMP:
            temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
            # Some faulty integrations might put 0 in here, raising exception.
            if temp == 0:
                _LOGGER.warning('Entity %s has incorrect color temperature %s',
                                self.state.entity_id, temp)
            elif temp is not None:
                color['temperatureK'] = \
                    color_util.color_temperature_mired_to_kelvin(temp)

        response = {}

        if color:
            response['color'] = color

        return response
Exemplo n.º 5
0
    def async_turn_on(self, **kwargs):
        """
        Instruct the light to turn on.

        After adding "self._light_data.hexcolor is not None"
        for ATTR_HS_COLOR, this also supports Philips Hue bulbs.
        """
        if ATTR_HS_COLOR in kwargs and self._light_data.hex_color is not None:
            rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            yield from self._api(
                self._light.light_control.set_rgb_color(*rgb))

        elif ATTR_COLOR_TEMP in kwargs and \
                self._light_data.hex_color is not None and \
                self._temp_supported:
            kelvin = color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP])
            yield from self._api(
                self._light_control.set_kelvin_color(kelvin))

        keys = {}
        if ATTR_TRANSITION in kwargs:
            keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10

        if ATTR_BRIGHTNESS in kwargs:
            if kwargs[ATTR_BRIGHTNESS] == 255:
                kwargs[ATTR_BRIGHTNESS] = 254

            yield from self._api(
                self._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS],
                                               **keys))
        else:
            yield from self._api(
                self._light_control.set_state(True))
Exemplo n.º 6
0
def find_hsbk(**kwargs):
    """Find the desired color from a number of possible inputs."""
    hue, saturation, brightness, kelvin = [None]*4

    preprocess_turn_on_alternatives(kwargs)

    if ATTR_RGB_COLOR in kwargs:
        hue, saturation, brightness = \
            color_util.color_RGB_to_hsv(*kwargs[ATTR_RGB_COLOR])
        saturation = convert_8_to_16(saturation)
        brightness = convert_8_to_16(brightness)
        kelvin = 3500

    if ATTR_XY_COLOR in kwargs:
        hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
        saturation = convert_8_to_16(saturation)
        kelvin = 3500

    if ATTR_COLOR_TEMP in kwargs:
        kelvin = int(color_util.color_temperature_mired_to_kelvin(
            kwargs[ATTR_COLOR_TEMP]))
        saturation = 0

    if ATTR_BRIGHTNESS in kwargs:
        brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])

    hsbk = [hue, saturation, brightness, kelvin]
    return None if hsbk == [None]*4 else hsbk
Exemplo n.º 7
0
    def turn_on(self, **kwargs):
        """Turn the device on."""
        if ATTR_TRANSITION in kwargs:
            fade = kwargs[ATTR_TRANSITION] * 1000
        else:
            fade = 0

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR])
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
        else:
            brightness = self._bri

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
        else:
            kelvin = self._kel

        _LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
                      self._ip, self._power,
                      hue, saturation, brightness, kelvin, fade)

        if self._power == 0:
            self._liffylights.set_power(self._ip, 65535, fade)

        self._liffylights.set_color(self._ip, hue, saturation,
                                    brightness, kelvin, fade)
Exemplo n.º 8
0
def query_response_light(
        entity: Entity, config: Config, units: UnitSystem) -> dict:
    """Convert a light entity to a QUERY response."""
    response = {}  # type: Dict[str, Any]

    brightness = entity.attributes.get(light.ATTR_BRIGHTNESS)
    if brightness is not None:
        response['brightness'] = int(100 * (brightness / 255))

    supported_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
    if supported_features & \
       (light.SUPPORT_COLOR_TEMP | light.SUPPORT_RGB_COLOR):
        response['color'] = {}

        if entity.attributes.get(light.ATTR_COLOR_TEMP) is not None:
            response['color']['temperature'] = \
                int(round(color.color_temperature_mired_to_kelvin(
                    entity.attributes.get(light.ATTR_COLOR_TEMP))))

        if entity.attributes.get(light.ATTR_COLOR_NAME) is not None:
            response['color']['name'] = \
                entity.attributes.get(light.ATTR_COLOR_NAME)

        if entity.attributes.get(light.ATTR_RGB_COLOR) is not None:
            color_rgb = entity.attributes.get(light.ATTR_RGB_COLOR)
            if color_rgb is not None:
                response['color']['spectrumRGB'] = \
                    int(color.color_rgb_to_hex(
                        color_rgb[0], color_rgb[1], color_rgb[2]), 16)

    return response
Exemplo n.º 9
0
    async def async_turn_on(self, **kwargs):
        """Instruct the light to turn on."""
        params = {}
        transition_time = None
        if ATTR_TRANSITION in kwargs:
            transition_time = int(kwargs[ATTR_TRANSITION]) * 10

        brightness = kwargs.get(ATTR_BRIGHTNESS)

        if brightness is not None:
            if brightness > 254:
                brightness = 254
            elif brightness < 0:
                brightness = 0

        if ATTR_HS_COLOR in kwargs and self._light_control.can_set_color:
            params[ATTR_BRIGHTNESS] = brightness
            hue = int(kwargs[ATTR_HS_COLOR][0] * (65535 / 360))
            sat = int(kwargs[ATTR_HS_COLOR][1] * (65279 / 100))
            if brightness is None:
                params[ATTR_TRANSITION_TIME] = transition_time
            await self._api(
                self._light_control.set_hsb(hue, sat, **params))
            return

        if ATTR_COLOR_TEMP in kwargs and (self._light_control.can_set_temp or
                                          self._light_control.can_set_color):
            temp = kwargs[ATTR_COLOR_TEMP]
            if temp > self.max_mireds:
                temp = self.max_mireds
            elif temp < self.min_mireds:
                temp = self.min_mireds

            if brightness is None:
                params[ATTR_TRANSITION_TIME] = transition_time
            # White Spectrum bulb
            if (self._light_control.can_set_temp and
                    not self._light_control.can_set_color):
                await self._api(
                    self._light_control.set_color_temp(temp, **params))
            # Color bulb (CWS)
            # color_temp needs to be set with hue/saturation
            if self._light_control.can_set_color:
                params[ATTR_BRIGHTNESS] = brightness
                temp_k = color_util.color_temperature_mired_to_kelvin(temp)
                hs_color = color_util.color_temperature_to_hs(temp_k)
                hue = int(hs_color[0] * (65535 / 360))
                sat = int(hs_color[1] * (65279 / 100))
                await self._api(
                    self._light_control.set_hsb(hue, sat,
                                                **params))

        if brightness is not None:
            params[ATTR_TRANSITION_TIME] = transition_time
            await self._api(
                self._light_control.set_dimmer(brightness,
                                               **params))
        else:
            await self._api(
                self._light_control.set_state(True))
Exemplo n.º 10
0
    def turn_on(self, **kwargs):
        """Turn the device on."""
        if ATTR_TRANSITION in kwargs:
            transition = int(kwargs[ATTR_TRANSITION] * 10)
        else:
            transition = 0

        if ATTR_BRIGHTNESS in kwargs:
            self._brightness = kwargs[ATTR_BRIGHTNESS]
            self._luminary.set_luminance(
                int(self._brightness / 2.55), transition)
        else:
            self._luminary.set_onoff(1)

        if ATTR_HS_COLOR in kwargs:
            red, green, blue = \
                color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            self._luminary.set_rgb(red, green, blue, transition)

        if ATTR_COLOR_TEMP in kwargs:
            color_t = kwargs[ATTR_COLOR_TEMP]
            kelvin = int(color_temperature_mired_to_kelvin(color_t))
            self._luminary.set_temperature(kelvin, transition)

        if ATTR_EFFECT in kwargs:
            effect = kwargs.get(ATTR_EFFECT)
            if effect == EFFECT_RANDOM:
                self._luminary.set_rgb(
                    random.randrange(0, 255), random.randrange(0, 255),
                    random.randrange(0, 255), transition)

        self.schedule_update_ha_state()
Exemplo n.º 11
0
    def turn_on(self, **kwargs):
        """Turn the device on."""
        if ATTR_TRANSITION in kwargs:
            transition = int(kwargs[ATTR_TRANSITION] * 10)
            _LOGGER.debug("turn_on requested transition time for light: "
                          "%s is: %s", self._name, transition)
        else:
            transition = 0
            _LOGGER.debug("turn_on requested transition time for light: "
                          "%s is: %s", self._name, transition)

        if ATTR_BRIGHTNESS in kwargs:
            self._brightness = kwargs[ATTR_BRIGHTNESS]
            _LOGGER.debug("turn_on requested brightness for light: %s is: %s ",
                          self._name, self._brightness)
            self._luminary.set_luminance(
                int(self._brightness / 2.55),
                transition)
        else:
            self._luminary.set_onoff(1)

        if ATTR_RGB_COLOR in kwargs:
            red, green, blue = kwargs[ATTR_RGB_COLOR]
            _LOGGER.debug("turn_on requested ATTR_RGB_COLOR for light:"
                          " %s is: %s %s %s ",
                          self._name, red, green, blue)
            self._luminary.set_rgb(red, green, blue, transition)

        if ATTR_XY_COLOR in kwargs:
            x_mired, y_mired = kwargs[ATTR_XY_COLOR]
            _LOGGER.debug("turn_on requested ATTR_XY_COLOR for light:"
                          " %s is: %s,%s", self._name, x_mired, y_mired)
            red, green, blue = color_xy_brightness_to_RGB(
                x_mired, y_mired, self._brightness
            )
            self._luminary.set_rgb(red, green, blue, transition)

        if ATTR_COLOR_TEMP in kwargs:
            color_t = kwargs[ATTR_COLOR_TEMP]
            kelvin = int(color_temperature_mired_to_kelvin(color_t))
            _LOGGER.debug("turn_on requested set_temperature for light: "
                          "%s: %s", self._name, kelvin)
            self._luminary.set_temperature(kelvin, transition)

        if ATTR_EFFECT in kwargs:
            effect = kwargs.get(ATTR_EFFECT)
            if effect == EFFECT_RANDOM:
                self._luminary.set_rgb(random.randrange(0, 255),
                                       random.randrange(0, 255),
                                       random.randrange(0, 255),
                                       transition)
                _LOGGER.debug("turn_on requested random effect for light: "
                              "%s with transition %s", self._name, transition)

        self.schedule_update_ha_state()
Exemplo n.º 12
0
    def query_attributes(self):
        """Return color temperature query attributes."""
        response = {}

        temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
        if temp is not None:
            response['color'] = {
                'temperature':
                    color_util.color_temperature_mired_to_kelvin(temp)
            }

        return response
Exemplo n.º 13
0
    def sync_attributes(self):
        """Return color temperature attributes for a sync request."""
        attrs = self.state.attributes
        features = attrs.get(ATTR_SUPPORTED_FEATURES, 0)
        response = {}

        if features & light.SUPPORT_COLOR:
            response['colorModel'] = 'hsv'

        if features & light.SUPPORT_COLOR_TEMP:
            # Max Kelvin is Min Mireds K = 1000000 / mireds
            # Min Kevin is Max Mireds K = 1000000 / mireds
            response['colorTemperatureRange'] = {
                'temperatureMaxK':
                color_util.color_temperature_mired_to_kelvin(
                    attrs.get(light.ATTR_MIN_MIREDS)),
                'temperatureMinK':
                color_util.color_temperature_mired_to_kelvin(
                    attrs.get(light.ATTR_MAX_MIREDS)),
            }

        return response
Exemplo n.º 14
0
 def turn_on(self, **kwargs):
     """Turn on or control the light."""
     if (ATTR_BRIGHTNESS not in kwargs
             and ATTR_HS_COLOR not in kwargs
             and ATTR_COLOR_TEMP not in kwargs):
         self.tuya.turn_on()
     if ATTR_BRIGHTNESS in kwargs:
         self.tuya.set_brightness(kwargs[ATTR_BRIGHTNESS])
     if ATTR_HS_COLOR in kwargs:
         self.tuya.set_color(kwargs[ATTR_HS_COLOR])
     if ATTR_COLOR_TEMP in kwargs:
         color_temp = colorutil.color_temperature_mired_to_kelvin(
             kwargs[ATTR_COLOR_TEMP])
         self.tuya.set_color_temp(color_temp)
Exemplo n.º 15
0
    def async_turn_on(self, **kwargs):
        """Turn the device on."""
        if ATTR_TRANSITION in kwargs:
            fade = int(kwargs[ATTR_TRANSITION] * 1000)
        else:
            fade = 0

        changed_color = False

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR])
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
            changed_color = True
        else:
            brightness = self._bri

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            changed_color = True
        else:
            kelvin = self._kel

        hsbk = [hue, saturation, brightness, kelvin]
        _LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
                      self.ipaddr, self._power, fade, *hsbk)

        if self._power == 0:
            if changed_color:
                self.device.set_color(hsbk, None, 0)
            self.device.set_power(True, None, fade)
        else:
            self.device.set_power(True, None, 0)     # racing for power status
            if changed_color:
                self.device.set_color(hsbk, None, fade)

        self.update_later(0)
        if fade < BULB_LATENCY:
            self.set_power(1)
            self.set_color(*hsbk)
Exemplo n.º 16
0
    def turn_on(self, **kwargs):
        """Turn on the light."""
        if ATTR_COLOR_TEMP in kwargs and self._device.is_color_capable:
            self._device.set_color_temp(
                int(color_temperature_mired_to_kelvin(
                    kwargs[ATTR_COLOR_TEMP])))

        if ATTR_HS_COLOR in kwargs and self._device.is_color_capable:
            self._device.set_color(kwargs[ATTR_HS_COLOR])

        if ATTR_BRIGHTNESS in kwargs and self._device.is_dimmable:
            # Convert HASS brightness (0-255) to Abode brightness (0-99)
            # If 100 is sent to Abode, response is 99 causing an error
            self._device.set_level(ceil(kwargs[ATTR_BRIGHTNESS] * 99 / 255.0))
        else:
            self._device.switch_on()
Exemplo n.º 17
0
    def query_attributes(self):
        """Return color temperature query attributes."""
        response = {}

        temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
        # Some faulty integrations might put 0 in here, raising exception.
        if temp == 0:
            _LOGGER.warning('Entity %s has incorrect color temperature %s',
                            self.state.entity_id, temp)
        elif temp is not None:
            response['color'] = {
                'temperature':
                    color_util.color_temperature_mired_to_kelvin(temp)
            }

        return response
Exemplo n.º 18
0
    def find_hsbk(self, **kwargs):
        """Find the desired color from a number of possible inputs."""
        changed_color = False

        hsbk = kwargs.pop(ATTR_HSBK, None)
        if hsbk is not None:
            return [hsbk, True]

        preprocess_turn_on_alternatives(kwargs)

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                color_util.color_RGB_to_hsv(*kwargs[ATTR_RGB_COLOR])
            saturation = convert_8_to_16(saturation)
            brightness = convert_8_to_16(brightness)
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_XY_COLOR in kwargs:
            hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
            saturation = convert_8_to_16(saturation)
            changed_color = True

        # When color or temperature is set, use a default value for the other
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            if not changed_color:
                saturation = 0
            changed_color = True
        else:
            if changed_color:
                kelvin = 3500
            else:
                kelvin = self._kel

        if ATTR_BRIGHTNESS in kwargs:
            brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])
            changed_color = True
        else:
            brightness = self._bri

        return [[hue, saturation, brightness, kelvin], changed_color]
Exemplo n.º 19
0
    def find_hsbk(self, **kwargs):
        """Find the desired color from a number of possible inputs."""
        changed_color = False

        hsbk = kwargs.pop(ATTR_HSBK, None)
        if hsbk is not None:
            return [hsbk, True]

        color_name = kwargs.pop(ATTR_COLOR_NAME, None)
        if color_name is not None:
            kwargs[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name)

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR])
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_XY_COLOR in kwargs:
            hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
            saturation = saturation * (BYTE_MAX + 1)
            changed_color = True

        # When color or temperature is set, use a default value for the other
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            if not changed_color:
                saturation = 0
            changed_color = True
        else:
            if changed_color:
                kelvin = 3500
            else:
                kelvin = self._kel

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
            changed_color = True
        else:
            brightness = self._bri

        return [[hue, saturation, brightness, kelvin], changed_color]
Exemplo n.º 20
0
    def turn_on(self, **kwargs):
        """Turn the light on."""
        if not self._on:
            self._lamp.switch(True)
        if ATTR_BRIGHTNESS in kwargs:
            brightness = int((kwargs[ATTR_BRIGHTNESS] / 255.0) * 200.0)
            self._lamp.brightness(brightness)
            return

        if ATTR_RGB_COLOR in kwargs:
            rgb = kwargs[ATTR_RGB_COLOR]
            self._lamp.rgb(*rgb)
            return

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            self._lamp.white(kelvin)
            return
Exemplo n.º 21
0
    def find_hsbk(self, **kwargs):
        """Find the desired color from a number of possible inputs."""
        changed_color = False

        hsbk = kwargs.pop(ATTR_HSBK, None)
        if hsbk is not None:
            return [hsbk, True]

        color_name = kwargs.pop(ATTR_COLOR_NAME, None)
        if color_name is not None:
            kwargs[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name)

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR])
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
            changed_color = True
        else:
            brightness = self._bri

        if ATTR_XY_COLOR in kwargs:
            hue, saturation, _ = \
                color_util.color_xy_brightness_to_hsv(
                    *kwargs[ATTR_XY_COLOR],
                    ibrightness=(brightness // (BYTE_MAX + 1)))
            saturation = saturation * (BYTE_MAX + 1)
            changed_color = True

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            changed_color = True
        else:
            kelvin = self._kel

        return [[hue, saturation, brightness, kelvin], changed_color]
    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:
            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))
Exemplo n.º 23
0
 def turn_on(self, **kwargs):
     """Turn on or control the light."""
     if (
         ATTR_BRIGHTNESS not in kwargs
         and ATTR_HS_COLOR not in kwargs
         and ATTR_COLOR_TEMP not in kwargs
     ):
         self.tuya.turn_on()
     if ATTR_BRIGHTNESS in kwargs:
         brightness = self.map_brightness(kwargs[ATTR_BRIGHTNESS], 1, 255, 29, 255)
         self.tuya.set_brightness(brightness)
     if ATTR_HS_COLOR in kwargs:
         self.tuya.set_color(kwargs[ATTR_HS_COLOR])
         if not "entity_data" in self.hass.data[DOMAIN]:
           self.hass.data[DOMAIN] = {"entity_data": {}}
         self.hass.data[DOMAIN]["entity_data"][self.tuya.object_id()] = {"color": kwargs[ATTR_HS_COLOR]}
     if ATTR_COLOR_TEMP in kwargs:
         color_temp = colorutil.color_temperature_mired_to_kelvin(
             kwargs[ATTR_COLOR_TEMP]
         )
         self.tuya.set_color_temp(color_temp)
Exemplo n.º 24
0
Arquivo: light.py Projeto: jbouwh/core
    async def async_turn_on(self, **kwargs: Any) -> None:
        """Instruct the light to turn on."""
        brightness = round(
            kwargs.get(ATTR_BRIGHTNESS, self.brightness) / 255 * 100)

        if (self.supported_color_modes
                and ColorMode.COLOR_TEMP in self.supported_color_modes
                and ATTR_COLOR_TEMP in kwargs):
            color_temp = kwargs[ATTR_COLOR_TEMP]
            kelvin = max(
                2700, min(6500, color_temperature_mired_to_kelvin(color_temp)))
            await self._device.set_color_temp(brightness, kelvin)
            return
        if ATTR_RGB_COLOR in kwargs:
            rgb = kwargs[ATTR_RGB_COLOR]
            await self._device.set_rgb(brightness, rgb[0], rgb[1], rgb[2])
            return
        if ATTR_BRIGHTNESS in kwargs:
            await self._device.set_brightness(brightness)
            return
        await self._device.turn_on()
Exemplo n.º 25
0
    def turn_on(self, **kwargs):
        """Turn the entity on."""
        _LOGGER.debug("turn_on: {} {} {}".format(self._name, self._state, kwargs))

        self._light.nightlight_on()
        if ATTR_BRIGHTNESS in kwargs:
            self._light.set_nightlight_brightness(kwargs[ATTR_BRIGHTNESS])

        if ATTR_HS_COLOR in kwargs:
            rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            self._light.set_nightlight_rgb(red=rgb[0], green=rgb[1], blue=rgb[2])

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = color_util.color_temperature_mired_to_kelvin(kwargs.get(ATTR_COLOR_TEMP))
            self._light.set_nightlight_color_temperature(kelvin)

        if ATTR_EFFECT in kwargs:
            effect = kwargs[ATTR_EFFECT]
            if effect == LIGHT_EFFECT_RAINBOW:
                self._light.set_nightlight_mode("rainbow")
            else:
                self._light.set_nightlight_mode("rgb")
Exemplo n.º 26
0
def find_hsbk(**kwargs):
    """Find the desired color from a number of possible inputs."""
    hue, saturation, brightness, kelvin = [None]*4

    preprocess_turn_on_alternatives(kwargs)

    if ATTR_HS_COLOR in kwargs:
        hue, saturation = kwargs[ATTR_HS_COLOR]
        hue = int(hue / 360 * 65535)
        saturation = int(saturation / 100 * 65535)
        kelvin = 3500

    if ATTR_COLOR_TEMP in kwargs:
        kelvin = int(color_util.color_temperature_mired_to_kelvin(
            kwargs[ATTR_COLOR_TEMP]))
        saturation = 0

    if ATTR_BRIGHTNESS in kwargs:
        brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])

    hsbk = [hue, saturation, brightness, kelvin]
    return None if hsbk == [None]*4 else hsbk
Exemplo n.º 27
0
    async def async_turn_on(self, **kwargs) -> None:
        """Turn on light."""
        if self.block.type == "relay":
            self.control_result = await self.block.set_state(turn="on")
            self.async_write_ha_state()
            return

        params = {"turn": "on"}
        if ATTR_BRIGHTNESS in kwargs:
            tmp_brightness = int(kwargs[ATTR_BRIGHTNESS] / 255 * 100)
            if hasattr(self.block, "gain"):
                params["gain"] = tmp_brightness
            if hasattr(self.block, "brightness"):
                params["brightness"] = tmp_brightness
        if ATTR_COLOR_TEMP in kwargs:
            color_temp = color_temperature_mired_to_kelvin(kwargs[ATTR_COLOR_TEMP])
            color_temp = min(
                KELVIN_MAX_VALUE, max(min_kelvin(self.wrapper.model), color_temp)
            )
            # Color temperature change - used only in white mode, switch device mode to white
            if self.mode == "color":
                self.mode_result = await self.wrapper.device.switch_light_mode("white")
                params["red"] = params["green"] = params["blue"] = 255
            params["temp"] = int(color_temp)
        elif ATTR_HS_COLOR in kwargs:
            red, green, blue = color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            # Color channels change - used only in color mode, switch device mode to color
            if self.mode == "white":
                self.mode_result = await self.wrapper.device.switch_light_mode("color")
            params["red"] = red
            params["green"] = green
            params["blue"] = blue
        elif ATTR_WHITE_VALUE in kwargs:
            # White channel change - used only in color mode, switch device mode device to color
            if self.mode == "white":
                self.mode_result = await self.wrapper.device.switch_light_mode("color")
            params["white"] = int(kwargs[ATTR_WHITE_VALUE])
        self.control_result = await self.block.set_state(**params)
        self.async_write_ha_state()
Exemplo n.º 28
0
    async def async_turn_on(self, **kwargs):
        """
            Instruct the light to turn on.
        """
        # TODO: change this to set state using a single UDP call
        #

        
        rgb = None
        if ATTR_RGB_COLOR in kwargs:
           rgb = kwargs[ATTR_RGB_COLOR]
        if ATTR_HS_COLOR in kwargs:
           rgb = color_utils.color_hs_to_RGB(kwargs[ATTR_HS_COLOR][0], kwargs[ATTR_HS_COLOR][1])

        brightness = None
        if ATTR_BRIGHTNESS in kwargs:
           brightness = kwargs[ATTR_BRIGHTNESS]

        colortemp = None
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = color_utils.color_temperature_mired_to_kelvin(kwargs[ATTR_COLOR_TEMP])
            colortemp = kelvin

        sceneid = None
        if ATTR_EFFECT in kwargs:
            sceneid = self._light.get_id_from_scene_name(kwargs[ATTR_EFFECT])

        if sceneid == 1000: #rhythm
            pilot = PilotBuilder()
        else:
            pilot = PilotBuilder(
                    rgb = rgb,
                    brightness = brightness,
                    colortemp = colortemp,
                    scene = sceneid
                )

        await self._light.turn_on(pilot)
Exemplo n.º 29
0
def _async_pilot_builder(**kwargs: Any) -> PilotBuilder:
    """Create the PilotBuilder for turn on."""
    brightness = kwargs.get(ATTR_BRIGHTNESS)

    if ATTR_RGBWW_COLOR in kwargs:
        return PilotBuilder(brightness=brightness, rgbww=kwargs[ATTR_RGBWW_COLOR])

    if ATTR_RGBW_COLOR in kwargs:
        return PilotBuilder(brightness=brightness, rgbw=kwargs[ATTR_RGBW_COLOR])

    if ATTR_COLOR_TEMP in kwargs:
        return PilotBuilder(
            brightness=brightness,
            colortemp=color_temperature_mired_to_kelvin(kwargs[ATTR_COLOR_TEMP]),
        )

    if ATTR_EFFECT in kwargs:
        scene_id = get_id_from_scene_name(kwargs[ATTR_EFFECT])
        if scene_id == 1000:  # rhythm
            return PilotBuilder()
        return PilotBuilder(brightness=brightness, scene=scene_id)

    return PilotBuilder(brightness=brightness)
Exemplo n.º 30
0
    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._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS])
        else:
            self._light_control.set_state(True)

        if ATTR_RGB_COLOR in kwargs and self._light_data.hex_color is not None:
            self._light.light_control.set_hex_color(
                color_util.color_rgb_to_hex(*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])
            # find closest allowed kelvin temp from user input
            kelvin = min(self._ok_temps.keys(), key=lambda x: abs(x - kelvin))
            self._light_control.set_hex_color(self._ok_temps[kelvin])
Exemplo n.º 31
0
    def turn_on(self, **kwargs):
        """Turn the device on."""
        if ATTR_TRANSITION in kwargs:
            fade = int(kwargs[ATTR_TRANSITION] * 1000)
        else:
            fade = 0

        if ATTR_HS_COLOR in kwargs:
            hue, saturation = kwargs[ATTR_HS_COLOR]
            hue = hue / 360 * 65535
            saturation = saturation / 100 * 65535
        else:
            hue = self._hue
            saturation = self._sat

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
        else:
            brightness = self._bri

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
        else:
            kelvin = self._kel

        _LOGGER.debug("turn_on: %s (%d) %d %d %d %d %d",
                      self._ip, self._power,
                      hue, saturation, brightness, kelvin, fade)

        if self._power == 0:
            self._liffylights.set_color(self._ip, hue, saturation,
                                        brightness, kelvin, 0)
            self._liffylights.set_power(self._ip, 65535, fade)
        else:
            self._liffylights.set_color(self._ip, hue, saturation,
                                        brightness, kelvin, fade)
Exemplo n.º 32
0
    async def async_turn_on(self, **kwargs):
        """Instruct the light to turn on."""
        rgb = None
        if ATTR_RGB_COLOR in kwargs:
            rgb = kwargs.get(ATTR_RGB_COLOR)
        if ATTR_HS_COLOR in kwargs:
            rgb = color_utils.color_hs_to_RGB(
                kwargs[ATTR_HS_COLOR][0], kwargs[ATTR_HS_COLOR][1]
            )

        brightness = None
        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs.get(ATTR_BRIGHTNESS)

        colortemp = None
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = color_utils.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]
            )
            colortemp = kelvin
            _LOGGER.debug(
                "[wizlight %s] kelvin changed and send to bulb: %s",
                self._light.ip,
                colortemp,
            )

        sceneid = None
        if ATTR_EFFECT in kwargs:
            sceneid = self._light.get_id_from_scene_name(kwargs[ATTR_EFFECT])

        if sceneid == 1000:  # rhythm
            pilot = PilotBuilder()
        else:
            pilot = PilotBuilder(
                rgb=rgb, brightness=brightness, colortemp=colortemp, scene=sceneid
            )
        await self._light.turn_on(pilot)
Exemplo n.º 33
0
    def async_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_RGB_COLOR in kwargs and self._light_data.hex_color is not None:
            self.hass.async_add_job(
                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._temp_supported:
            kelvin = color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP])
            self.hass.async_add_job(
                self._api(self._light_control.set_kelvin_color(kelvin)))

        keys = {}
        if ATTR_TRANSITION in kwargs:
            keys['transition_time'] = int(kwargs[ATTR_TRANSITION]) * 10

        if ATTR_BRIGHTNESS in kwargs:
            if kwargs[ATTR_BRIGHTNESS] == 255:
                kwargs[ATTR_BRIGHTNESS] = 254

            self.hass.async_add_job(
                self._api(
                    self._light_control.set_dimmer(kwargs[ATTR_BRIGHTNESS],
                                                   **keys)))
        else:
            self.hass.async_add_job(
                self._api(self._light_control.set_state(True)))
Exemplo n.º 34
0
    def turn_on(self, **kwargs):
        """Turn the device on."""
        transition = int(kwargs.get(ATTR_TRANSITION, 0) * 10)
        if ATTR_EFFECT in kwargs:
            self.play_effect(kwargs[ATTR_EFFECT], transition)
            return

        if ATTR_HS_COLOR in kwargs:
            self._rgb_color = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            self._luminary.set_rgb(*self._rgb_color, transition)

        if ATTR_COLOR_TEMP in kwargs:
            self._color_temp = kwargs[ATTR_COLOR_TEMP]
            self._luminary.set_temperature(
                int(color_util.color_temperature_mired_to_kelvin(self._color_temp)),
                transition,
            )

        self._is_on = True
        if ATTR_BRIGHTNESS in kwargs:
            self._brightness = kwargs[ATTR_BRIGHTNESS]
            self._luminary.set_luminance(int(self._brightness / 2.55), transition)
        else:
            self._luminary.set_onoff(True)
Exemplo n.º 35
0
    def turn_on(self, **kwargs):
        """Turn the light on."""
        if not self.is_on:
            self._lamp.switch(True)
        if ATTR_BRIGHTNESS in kwargs:
            brightness = int((kwargs[ATTR_BRIGHTNESS] / 255.0) * 200.0)
            self._lamp.brightness(brightness)
            return

        if ATTR_RGB_COLOR in kwargs:
            rgb = kwargs[ATTR_RGB_COLOR]
            self._lamp.rgb(*rgb)
            return

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            self._lamp.white(kelvin)
            return

        if ATTR_EFFECT in kwargs:
            effect = kwargs[ATTR_EFFECT]
            self._lamp.effect(effect)
            return
Exemplo n.º 36
0
    async def async_turn_on(self, **kwargs):
        """Instruct the light to turn on."""
        transition_time = None
        if ATTR_TRANSITION in kwargs:
            transition_time = int(kwargs[ATTR_TRANSITION]) * 10

        dimmer_command = None
        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS]
            if brightness > 254:
                brightness = 254
            elif brightness < 0:
                brightness = 0
            dimmer_data = {ATTR_DIMMER: brightness, ATTR_TRANSITION_TIME:
                           transition_time}
            dimmer_command = self._light_control.set_dimmer(**dimmer_data)
            transition_time = None
        else:
            dimmer_command = self._light_control.set_state(True)

        color_command = None
        if ATTR_HS_COLOR in kwargs and self._light_control.can_set_color:
            hue = int(kwargs[ATTR_HS_COLOR][0] *
                      (self._light_control.max_hue / 360))
            sat = int(kwargs[ATTR_HS_COLOR][1] *
                      (self._light_control.max_saturation / 100))
            color_data = {ATTR_HUE: hue, ATTR_SAT: sat, ATTR_TRANSITION_TIME:
                          transition_time}
            color_command = self._light_control.set_hsb(**color_data)
            transition_time = None

        temp_command = None
        if ATTR_COLOR_TEMP in kwargs and (self._light_control.can_set_temp or
                                          self._light_control.can_set_color):
            temp = kwargs[ATTR_COLOR_TEMP]
            # White Spectrum bulb
            if self._light_control.can_set_temp:
                if temp > self.max_mireds:
                    temp = self.max_mireds
                elif temp < self.min_mireds:
                    temp = self.min_mireds
                temp_data = {ATTR_COLOR_TEMP: temp, ATTR_TRANSITION_TIME:
                             transition_time}
                temp_command = self._light_control.set_color_temp(**temp_data)
                transition_time = None
            # Color bulb (CWS)
            # color_temp needs to be set with hue/saturation
            elif self._light_control.can_set_color:
                temp_k = color_util.color_temperature_mired_to_kelvin(temp)
                hs_color = color_util.color_temperature_to_hs(temp_k)
                hue = int(hs_color[0] * (self._light_control.max_hue / 360))
                sat = int(hs_color[1] *
                          (self._light_control.max_saturation / 100))
                color_data = {ATTR_HUE: hue, ATTR_SAT: sat,
                              ATTR_TRANSITION_TIME: transition_time}
                color_command = self._light_control.set_hsb(**color_data)
                transition_time = None

        # HSB can always be set, but color temp + brightness is bulb dependant
        command = dimmer_command
        if command is not None:
            command += color_command
        else:
            command = color_command

        if self._light_control.can_combine_commands:
            await self._api(command + temp_command)
        else:
            if temp_command is not None:
                await self._api(temp_command)
            if command is not None:
                await self._api(command)
Exemplo n.º 37
0
def ct_to_rgb(temp):
    """Convert color temperature (mireds) to RGB."""
    colorlist = list(
        color_temperature_to_rgb(color_temperature_mired_to_kelvin(temp)))
    return [int(val) for val in colorlist]
Exemplo n.º 38
0
def entity_to_device(entity: Entity, config: Config, units: UnitSystem):
    """Convert a hass entity into an google actions device."""
    entity_config = config.entity_config.get(entity.entity_id, {})
    google_domain = entity_config.get(CONF_TYPE)
    class_data = MAPPING_COMPONENT.get(
        google_domain or entity.domain)

    if class_data is None:
        return None

    device = {
        'id': entity.entity_id,
        'name': {},
        'attributes': {},
        'traits': [],
        'willReportState': False,
    }
    device['type'] = class_data[0]
    device['traits'].append(class_data[1])

    # handle custom names
    device['name']['name'] = entity_config.get(CONF_NAME) or entity.name

    # use aliases
    aliases = entity_config.get(CONF_ALIASES)
    if aliases:
        device['name']['nicknames'] = aliases

    # add trait if entity supports feature
    if class_data[2]:
        supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
        for feature, trait in class_data[2].items():
            if feature & supported > 0:
                device['traits'].append(trait)

                # Actions require this attributes for a device
                # supporting temperature
                # For IKEA trådfri, these attributes only seem to
                # be set only if the device is on?
                if trait == TRAIT_COLOR_TEMP:
                    if entity.attributes.get(
                            light.ATTR_MAX_MIREDS) is not None:
                        device['attributes']['temperatureMinK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MAX_MIREDS))))
                    if entity.attributes.get(
                            light.ATTR_MIN_MIREDS) is not None:
                        device['attributes']['temperatureMaxK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MIN_MIREDS))))

    if entity.domain == climate.DOMAIN:
        modes = []
        for mode in entity.attributes.get(climate.ATTR_OPERATION_LIST, []):
            if mode in CLIMATE_SUPPORTED_MODES:
                modes.append(mode)
            elif mode == climate.STATE_AUTO:
                modes.append(CLIMATE_MODE_HEATCOOL)

        device['attributes'] = {
            'availableThermostatModes': ','.join(modes),
            'thermostatTemperatureUnit':
            'F' if units.temperature_unit == TEMP_FAHRENHEIT else 'C',
        }
        _LOGGER.debug('Thermostat attributes %s', device['attributes'])

    if entity.domain == sensor.DOMAIN:
        if google_domain == climate.DOMAIN:
            unit_of_measurement = entity.attributes.get(
                ATTR_UNIT_OF_MEASUREMENT,
                units.temperature_unit
            )

            device['attributes'] = {
                'thermostatTemperatureUnit':
                'F' if unit_of_measurement == TEMP_FAHRENHEIT else 'C',
            }
            _LOGGER.debug('Sensor attributes %s', device['attributes'])

    return device
Exemplo n.º 39
0
 def test_should_return_25000_kelvin_when_input_is_40_mired(self):
     """Function should return 25000K if given 40 mired."""
     kelvin = color_util.color_temperature_mired_to_kelvin(40)
     self.assertEqual(25000, kelvin)
Exemplo n.º 40
0
def query_device(entity: Entity, units: UnitSystem) -> dict:
    """Take an entity and return a properly formatted device object."""
    def celsius(deg: Optional[float]) -> Optional[float]:
        """Convert a float to Celsius and rounds to one decimal place."""
        if deg is None:
            return None
        return round(METRIC_SYSTEM.temperature(deg, units.temperature_unit), 1)

    if entity.domain == climate.DOMAIN:
        mode = entity.attributes.get(climate.ATTR_OPERATION_MODE).lower()
        if mode not in CLIMATE_SUPPORTED_MODES:
            mode = 'on'
        response = {
            'thermostatMode':
            mode,
            'thermostatTemperatureSetpoint':
            celsius(entity.attributes.get(climate.ATTR_TEMPERATURE)),
            'thermostatTemperatureAmbient':
            celsius(entity.attributes.get(climate.ATTR_CURRENT_TEMPERATURE)),
            'thermostatTemperatureSetpointHigh':
            celsius(entity.attributes.get(climate.ATTR_TARGET_TEMP_HIGH)),
            'thermostatTemperatureSetpointLow':
            celsius(entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)),
            'thermostatHumidityAmbient':
            entity.attributes.get(climate.ATTR_CURRENT_HUMIDITY),
        }
        return {k: v for k, v in response.items() if v is not None}

    final_state = entity.state != STATE_OFF
    final_brightness = entity.attributes.get(light.ATTR_BRIGHTNESS,
                                             255 if final_state else 0)

    if entity.domain == media_player.DOMAIN:
        level = entity.attributes.get(media_player.ATTR_MEDIA_VOLUME_LEVEL,
                                      1.0 if final_state else 0.0)
        # Convert 0.0-1.0 to 0-255
        final_brightness = round(min(1.0, level) * 255)

    if final_brightness is None:
        final_brightness = 255 if final_state else 0

    final_brightness = 100 * (final_brightness / 255)

    query_response = {
        "on": final_state,
        "online": True,
        "brightness": int(final_brightness)
    }

    supported_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
    if supported_features & \
       (light.SUPPORT_COLOR_TEMP | light.SUPPORT_RGB_COLOR):
        query_response["color"] = {}

        if entity.attributes.get(light.ATTR_COLOR_TEMP) is not None:
            query_response["color"]["temperature"] = \
                int(round(color.color_temperature_mired_to_kelvin(
                    entity.attributes.get(light.ATTR_COLOR_TEMP))))

        if entity.attributes.get(light.ATTR_COLOR_NAME) is not None:
            query_response["color"]["name"] = \
                entity.attributes.get(light.ATTR_COLOR_NAME)

        if entity.attributes.get(light.ATTR_RGB_COLOR) is not None:
            color_rgb = entity.attributes.get(light.ATTR_RGB_COLOR)
            if color_rgb is not None:
                query_response["color"]["spectrumRGB"] = \
                    int(color.color_rgb_to_hex(
                        color_rgb[0], color_rgb[1], color_rgb[2]), 16)

    return query_response
Exemplo n.º 41
0
def entity_to_device(entity: Entity, units: UnitSystem):
    """Convert a hass entity into an google actions device."""
    class_data = MAPPING_COMPONENT.get(
        entity.attributes.get(ATTR_GOOGLE_ASSISTANT_TYPE) or entity.domain)
    if class_data is None:
        return None

    device = {
        'id': entity.entity_id,
        'name': {},
        'attributes': {},
        'traits': [],
        'willReportState': False,
    }
    device['type'] = class_data[0]
    device['traits'].append(class_data[1])

    # handle custom names
    device['name']['name'] = \
        entity.attributes.get(ATTR_GOOGLE_ASSISTANT_NAME) or \
        entity.attributes.get(CONF_FRIENDLY_NAME)

    # use aliases
    aliases = entity.attributes.get(CONF_ALIASES)
    if aliases:
        if isinstance(aliases, list):
            device['name']['nicknames'] = aliases
        else:
            _LOGGER.warning("%s must be a list", CONF_ALIASES)

    # add trait if entity supports feature
    if class_data[2]:
        supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
        for feature, trait in class_data[2].items():
            if feature & supported > 0:
                device['traits'].append(trait)

                # Actions require this attributes for a device
                # supporting temperature
                # For IKEA trådfri, these attributes only seem to
                # be set only if the device is on?
                if trait == TRAIT_COLOR_TEMP:
                    if entity.attributes.get(
                            light.ATTR_MAX_MIREDS) is not None:
                        device['attributes']['temperatureMinK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MAX_MIREDS))))
                    if entity.attributes.get(
                            light.ATTR_MIN_MIREDS) is not None:
                        device['attributes']['temperatureMaxK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MIN_MIREDS))))

    if entity.domain == climate.DOMAIN:
        modes = ','.join(
            m.lower() for m in entity.attributes.get(
                climate.ATTR_OPERATION_LIST, [])
            if m.lower() in CLIMATE_SUPPORTED_MODES)
        device['attributes'] = {
            'availableThermostatModes': modes,
            'thermostatTemperatureUnit':
            'F' if units.temperature_unit == TEMP_FAHRENHEIT else 'C',
        }
        _LOGGER.debug('Thermostat attributes %s', device['attributes'])
    return device
Exemplo n.º 42
0
def query_device(entity: Entity, units: UnitSystem) -> dict:
    """Take an entity and return a properly formatted device object."""
    def celsius(deg: Optional[float]) -> Optional[float]:
        """Convert a float to Celsius and rounds to one decimal place."""
        if deg is None:
            return None
        return round(METRIC_SYSTEM.temperature(deg, units.temperature_unit), 1)
    if entity.domain == climate.DOMAIN:
        mode = entity.attributes.get(climate.ATTR_OPERATION_MODE).lower()
        if mode not in CLIMATE_SUPPORTED_MODES:
            mode = 'on'
        response = {
            'thermostatMode': mode,
            'thermostatTemperatureSetpoint':
            celsius(entity.attributes.get(climate.ATTR_TEMPERATURE)),
            'thermostatTemperatureAmbient':
            celsius(entity.attributes.get(climate.ATTR_CURRENT_TEMPERATURE)),
            'thermostatTemperatureSetpointHigh':
            celsius(entity.attributes.get(climate.ATTR_TARGET_TEMP_HIGH)),
            'thermostatTemperatureSetpointLow':
            celsius(entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)),
            'thermostatHumidityAmbient':
            entity.attributes.get(climate.ATTR_CURRENT_HUMIDITY),
        }
        return {k: v for k, v in response.items() if v is not None}

    final_state = entity.state != STATE_OFF
    final_brightness = entity.attributes.get(light.ATTR_BRIGHTNESS, 255
                                             if final_state else 0)

    if entity.domain == media_player.DOMAIN:
        level = entity.attributes.get(media_player.ATTR_MEDIA_VOLUME_LEVEL, 1.0
                                      if final_state else 0.0)
        # Convert 0.0-1.0 to 0-255
        final_brightness = round(min(1.0, level) * 255)

    if final_brightness is None:
        final_brightness = 255 if final_state else 0

    final_brightness = 100 * (final_brightness / 255)

    query_response = {
        "on": final_state,
        "online": True,
        "brightness": int(final_brightness)
    }

    supported_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
    if supported_features & \
       (light.SUPPORT_COLOR_TEMP | light.SUPPORT_RGB_COLOR):
        query_response["color"] = {}

        if entity.attributes.get(light.ATTR_COLOR_TEMP) is not None:
            query_response["color"]["temperature"] = \
                int(round(color.color_temperature_mired_to_kelvin(
                    entity.attributes.get(light.ATTR_COLOR_TEMP))))

        if entity.attributes.get(light.ATTR_COLOR_NAME) is not None:
            query_response["color"]["name"] = \
                entity.attributes.get(light.ATTR_COLOR_NAME)

        if entity.attributes.get(light.ATTR_RGB_COLOR) is not None:
            color_rgb = entity.attributes.get(light.ATTR_RGB_COLOR)
            if color_rgb is not None:
                query_response["color"]["spectrumRGB"] = \
                    int(color.color_rgb_to_hex(
                        color_rgb[0], color_rgb[1], color_rgb[2]), 16)

    return query_response
Exemplo n.º 43
0
        #
        # We previously had a problem with the brightness
        # sometimes reporting as 0 when an effect was in progress,
        # however this has since been resolved in the upstream library
        return max(MIN_RGB_BRIGHTNESS, brightness)

    async def _async_set_mode(self, **kwargs: Any) -> None:
        """Set an effect or color mode."""
        brightness = self._async_brightness(**kwargs)
        # Handle switch to Effect Mode
        if effect := kwargs.get(ATTR_EFFECT):
            await self._async_set_effect(effect, brightness)
            return
        # Handle switch to CCT Color Mode
        if color_temp_mired := kwargs.get(ATTR_COLOR_TEMP):
            color_temp_kelvin = color_temperature_mired_to_kelvin(
                color_temp_mired)
            if (ATTR_BRIGHTNESS not in kwargs
                    and self.color_mode in MULTI_BRIGHTNESS_COLOR_MODES):
                # When switching to color temp from RGBWW or RGB&W mode,
                # we do not want the overall brightness of the RGB channels
                brightness = max(MIN_CCT_BRIGHTNESS, *self._device.rgb)
            await self._device.async_set_white_temp(color_temp_kelvin,
                                                    brightness)
            return
        # Handle switch to RGB Color Mode
        if rgb := kwargs.get(ATTR_RGB_COLOR):
            if not self._device.requires_turn_on:
                rgb = _min_rgb_brightness(rgb)
            red, green, blue = rgb
            await self._device.async_set_levels(red,
                                                green,
Exemplo n.º 44
0
def test_color_temperature_mired_to_kelvin():
    """Test color_temperature_mired_to_kelvin."""
    assert color_util.color_temperature_mired_to_kelvin(40) == 25000
    assert color_util.color_temperature_mired_to_kelvin(200) == 5000
    with pytest.raises(ZeroDivisionError):
        assert color_util.color_temperature_mired_to_kelvin(0)
Exemplo n.º 45
0
async def test_services(hass: HomeAssistant, caplog):
    """Test Yeelight services."""
    mocked_bulb = _mocked_bulb()
    with patch(f"{MODULE}.Bulb", return_value=mocked_bulb):
        await async_setup_component(hass, DOMAIN, YAML_CONFIGURATION)
        await hass.async_block_till_done()

    async def _async_test_service(service,
                                  data,
                                  method,
                                  payload=None,
                                  domain=DOMAIN):
        err_count = len(
            [x for x in caplog.records if x.levelno == logging.ERROR])

        # success
        mocked_method = MagicMock()
        setattr(type(mocked_bulb), method, mocked_method)
        await hass.services.async_call(domain, service, data, blocking=True)
        if payload is None:
            mocked_method.assert_called_once()
        elif type(payload) == list:
            mocked_method.assert_called_once_with(*payload)
        else:
            mocked_method.assert_called_once_with(**payload)
        assert (len([x for x in caplog.records
                     if x.levelno == logging.ERROR]) == err_count)

        # failure
        mocked_method = MagicMock(side_effect=BulbException)
        setattr(type(mocked_bulb), method, mocked_method)
        await hass.services.async_call(domain, service, data, blocking=True)
        assert (len([x for x in caplog.records
                     if x.levelno == logging.ERROR]) == err_count + 1)

    # turn_on
    brightness = 100
    color_temp = 200
    transition = 1
    await hass.services.async_call(
        "light",
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_BRIGHTNESS: brightness,
            ATTR_COLOR_TEMP: color_temp,
            ATTR_FLASH: FLASH_LONG,
            ATTR_EFFECT: EFFECT_STOP,
            ATTR_TRANSITION: transition,
        },
        blocking=True,
    )
    mocked_bulb.turn_on.assert_called_once_with(
        duration=transition * 1000,
        light_type=LightType.Main,
        power_mode=PowerMode.NORMAL,
    )
    mocked_bulb.turn_on.reset_mock()
    mocked_bulb.start_music.assert_called_once()
    mocked_bulb.set_brightness.assert_called_once_with(
        brightness / 255 * 100,
        duration=transition * 1000,
        light_type=LightType.Main)
    mocked_bulb.set_color_temp.assert_called_once_with(
        color_temperature_mired_to_kelvin(color_temp),
        duration=transition * 1000,
        light_type=LightType.Main,
    )
    mocked_bulb.start_flow.assert_called_once()  # flash
    mocked_bulb.stop_flow.assert_called_once_with(light_type=LightType.Main)

    # turn_on nightlight
    await _async_test_service(
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: ENTITY_NIGHTLIGHT},
        "turn_on",
        payload={
            "duration": DEFAULT_TRANSITION,
            "light_type": LightType.Main,
            "power_mode": PowerMode.MOONLIGHT,
        },
        domain="light",
    )

    # turn_off
    await _async_test_service(
        SERVICE_TURN_OFF,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_TRANSITION: transition
        },
        "turn_off",
        domain="light",
        payload={
            "duration": transition * 1000,
            "light_type": LightType.Main
        },
    )

    # set_mode
    mode = "rgb"
    await _async_test_service(
        SERVICE_SET_MODE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MODE: "rgb"
        },
        "set_power_mode",
        [PowerMode[mode.upper()]],
    )

    # start_flow
    await _async_test_service(
        SERVICE_START_FLOW,
        {
            ATTR_ENTITY_ID:
            ENTITY_LIGHT,
            ATTR_TRANSITIONS: [{
                YEELIGHT_TEMPERATURE_TRANSACTION: [1900, 2000, 60]
            }],
        },
        "start_flow",
    )

    # set_color_scene
    await _async_test_service(
        SERVICE_SET_COLOR_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_RGB_COLOR: [10, 20, 30],
            ATTR_BRIGHTNESS: 50,
        },
        "set_scene",
        [SceneClass.COLOR, 10, 20, 30, 50],
    )

    # set_hsv_scene
    await _async_test_service(
        SERVICE_SET_HSV_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_HS_COLOR: [180, 50],
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.HSV, 180, 50, 50],
    )

    # set_color_temp_scene
    await _async_test_service(
        SERVICE_SET_COLOR_TEMP_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_KELVIN: 4000,
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.CT, 4000, 50],
    )

    # set_color_flow_scene
    await _async_test_service(
        SERVICE_SET_COLOR_FLOW_SCENE,
        {
            ATTR_ENTITY_ID:
            ENTITY_LIGHT,
            ATTR_TRANSITIONS: [{
                YEELIGHT_TEMPERATURE_TRANSACTION: [1900, 2000, 60]
            }],
        },
        "set_scene",
    )

    # set_auto_delay_off_scene
    await _async_test_service(
        SERVICE_SET_AUTO_DELAY_OFF_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MINUTES: 1,
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.AUTO_DELAY_OFF, 50, 1],
    )

    # test _cmd wrapper error handler
    err_count = len([x for x in caplog.records if x.levelno == logging.ERROR])
    type(mocked_bulb).turn_on = MagicMock()
    type(mocked_bulb).set_brightness = MagicMock(side_effect=BulbException)
    await hass.services.async_call(
        "light",
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_BRIGHTNESS: 50
        },
        blocking=True,
    )
    assert (len([x for x in caplog.records
                 if x.levelno == logging.ERROR]) == err_count + 1)
Exemplo n.º 46
0
    async def async_turn_on(self, **kwargs):
        """Forward the turn_on command to all lights in the light group."""
        data = {ATTR_ENTITY_ID: self._entity_ids}
        emulate_color_temp_entity_ids = []

        if ATTR_BRIGHTNESS in kwargs:
            data[ATTR_BRIGHTNESS] = kwargs[ATTR_BRIGHTNESS]

        if ATTR_HS_COLOR in kwargs:
            data[ATTR_HS_COLOR] = kwargs[ATTR_HS_COLOR]

        if ATTR_RGB_COLOR in kwargs:
            data[ATTR_RGB_COLOR] = kwargs[ATTR_RGB_COLOR]

        if ATTR_RGBW_COLOR in kwargs:
            data[ATTR_RGBW_COLOR] = kwargs[ATTR_RGBW_COLOR]

        if ATTR_RGBWW_COLOR in kwargs:
            data[ATTR_RGBWW_COLOR] = kwargs[ATTR_RGBWW_COLOR]

        if ATTR_XY_COLOR in kwargs:
            data[ATTR_XY_COLOR] = kwargs[ATTR_XY_COLOR]

        if ATTR_COLOR_TEMP in kwargs:
            data[ATTR_COLOR_TEMP] = kwargs[ATTR_COLOR_TEMP]

            # Create a new entity list to mutate
            updated_entities = list(self._entity_ids)

            # Walk through initial entity ids, split entity lists by support
            for entity_id in self._entity_ids:
                state = self.hass.states.get(entity_id)
                if not state:
                    continue
                support = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES)
                # Only pass color temperature to supported entity_ids
                if color_supported(
                        support) and not color_temp_supported(support):
                    emulate_color_temp_entity_ids.append(entity_id)
                    updated_entities.remove(entity_id)
                    data[ATTR_ENTITY_ID] = updated_entities

        if ATTR_WHITE_VALUE in kwargs:
            data[ATTR_WHITE_VALUE] = kwargs[ATTR_WHITE_VALUE]

        if ATTR_EFFECT in kwargs:
            data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]

        if ATTR_TRANSITION in kwargs:
            data[ATTR_TRANSITION] = kwargs[ATTR_TRANSITION]

        if ATTR_FLASH in kwargs:
            data[ATTR_FLASH] = kwargs[ATTR_FLASH]

        if not emulate_color_temp_entity_ids:
            await self.hass.services.async_call(
                light.DOMAIN,
                light.SERVICE_TURN_ON,
                data,
                blocking=True,
                context=self._context,
            )
            return

        emulate_color_temp_data = data.copy()
        temp_k = color_util.color_temperature_mired_to_kelvin(
            emulate_color_temp_data[ATTR_COLOR_TEMP])
        hs_color = color_util.color_temperature_to_hs(temp_k)
        emulate_color_temp_data[ATTR_HS_COLOR] = hs_color
        del emulate_color_temp_data[ATTR_COLOR_TEMP]

        emulate_color_temp_data[ATTR_ENTITY_ID] = emulate_color_temp_entity_ids

        await asyncio.gather(
            self.hass.services.async_call(
                light.DOMAIN,
                light.SERVICE_TURN_ON,
                data,
                blocking=True,
                context=self._context,
            ),
            self.hass.services.async_call(
                light.DOMAIN,
                light.SERVICE_TURN_ON,
                emulate_color_temp_data,
                blocking=True,
                context=self._context,
            ),
        )
Exemplo n.º 47
0
 def test_should_return_5000_kelvin_when_input_is_200_mired(self):
     """Function should return 5000K if given 200 mired."""
     kelvin = color_util.color_temperature_mired_to_kelvin(200)
     assert 5000 == kelvin
Exemplo n.º 48
0
 def test_should_return_5000_kelvin_when_input_is_200_mired(self):
     """Function should return 5000K if given 200 mired."""
     kelvin = color_util.color_temperature_mired_to_kelvin(200)
     self.assertEqual(5000, kelvin)
Exemplo n.º 49
0
 async def async_set_color_temp(self, value: float):
     """Set the color temperature of the device."""
     kelvin = color_util.color_temperature_mired_to_kelvin(value)
     kelvin = max(min(kelvin, 30000.0), 1.0)
     await self._device.set_color_temperature(kelvin, set_status=True)
Exemplo n.º 50
0
 async def async_set_color_temp(self, value: float):
     """Set the color temperature of the device."""
     kelvin = color_util.color_temperature_mired_to_kelvin(value)
     kelvin = max(min(kelvin, 30000.0), 1.0)
     await self._device.set_color_temperature(
         kelvin, set_status=True)
Exemplo n.º 51
0
    async def async_turn_on(self, **kwargs: Any) -> None:
        """Turn the light on."""
        brightness = kwargs.get(ATTR_BRIGHTNESS)
        mireds = kwargs.get(ATTR_COLOR_TEMP)
        rgb = kwargs.get(ATTR_RGB_COLOR)
        rgbw = kwargs.get(ATTR_RGBW_COLOR)
        hs_color = kwargs.get(ATTR_HS_COLOR)
        xy_color = kwargs.get(ATTR_XY_COLOR)

        if (not self.is_on and brightness is None and mireds is None
                and rgb is None and rgbw is None and hs_color is None
                and xy_color is None):
            await self._device.set_on()
            return

        async def set_color(rgb: tuple[int, int, int], white: int | None,
                            brightness: int | None) -> None:
            """Set color of light. Normalize colors for brightness when not writable."""
            if self._device.brightness.writable:
                # let the KNX light controller handle brightness
                await self._device.set_color(rgb, white)
                if brightness:
                    await self._device.set_brightness(brightness)
                return

            if brightness is None:
                # normalize for brightness if brightness is derived from color
                brightness = self.brightness or 255
            rgb = cast(
                Tuple[int, int, int],
                tuple(color * brightness // 255 for color in rgb),
            )
            white = white * brightness // 255 if white is not None else None
            await self._device.set_color(rgb, white)

        # return after RGB(W) color has changed as it implicitly sets the brightness
        if rgbw is not None:
            await set_color(rgbw[:3], rgbw[3], brightness)
            return
        if rgb is not None:
            await set_color(rgb, None, brightness)
            return

        if mireds is not None:
            kelvin = int(color_util.color_temperature_mired_to_kelvin(mireds))
            kelvin = min(self._max_kelvin, max(self._min_kelvin, kelvin))

            if self._device.supports_color_temperature:
                await self._device.set_color_temperature(kelvin)
            elif self._device.supports_tunable_white:
                relative_ct = int(255 * (kelvin - self._min_kelvin) /
                                  (self._max_kelvin - self._min_kelvin))
                await self._device.set_tunable_white(relative_ct)

        if xy_color is not None:
            await self._device.set_xyy_color(
                XYYColor(color=xy_color, brightness=brightness))
            return

        if hs_color is not None:
            # round so only one telegram will be sent if the other matches state
            hue = round(hs_color[0])
            sat = round(hs_color[1])
            await self._device.set_hs_color((hue, sat))

        if brightness is not None:
            # brightness: 1..255; 0 brightness will call async_turn_off()
            if self._device.brightness.writable:
                await self._device.set_brightness(brightness)
                return
            # brightness without color in kwargs; set via color
            if self.color_mode == COLOR_MODE_XY:
                await self._device.set_xyy_color(
                    XYYColor(brightness=brightness))
                return
            # default to white if color not known for RGB(W)
            if self.color_mode == COLOR_MODE_RGBW:
                _rgbw = self.rgbw_color
                if not _rgbw or not any(_rgbw):
                    _rgbw = (0, 0, 0, 255)
                await set_color(_rgbw[:3], _rgbw[3], brightness)
                return
            if self.color_mode == COLOR_MODE_RGB:
                _rgb = self.rgb_color
                if not _rgb or not any(_rgb):
                    _rgb = (255, 255, 255)
                await set_color(_rgb, None, brightness)
                return
Exemplo n.º 52
0
def ct_to_hs(temp):
    """Convert color temperature (mireds) to hs."""
    colorlist = list(
        color_util.color_temperature_to_hs(
            color_util.color_temperature_mired_to_kelvin(temp)))
    return [int(val) for val in colorlist]
Exemplo n.º 53
0
    async def async_turn_on(self, **kwargs):
        """Instruct the light to turn on."""
        transition_time = None
        if ATTR_TRANSITION in kwargs:
            transition_time = int(kwargs[ATTR_TRANSITION]) * 10

        dimmer_command = None
        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS]
            brightness = min(brightness, 254)
            dimmer_data = {
                ATTR_DIMMER: brightness,
                ATTR_TRANSITION_TIME: transition_time,
            }
            dimmer_command = self._device_control.set_dimmer(**dimmer_data)
            transition_time = None
        else:
            dimmer_command = self._device_control.set_state(True)

        color_command = None
        if ATTR_HS_COLOR in kwargs and self._device_control.can_set_color:
            hue = int(kwargs[ATTR_HS_COLOR][0] *
                      (self._device_control.max_hue / 360))
            sat = int(kwargs[ATTR_HS_COLOR][1] *
                      (self._device_control.max_saturation / 100))
            color_data = {
                ATTR_HUE: hue,
                ATTR_SAT: sat,
                ATTR_TRANSITION_TIME: transition_time,
            }
            color_command = self._device_control.set_hsb(**color_data)
            transition_time = None

        temp_command = None
        if ATTR_COLOR_TEMP in kwargs and (self._device_control.can_set_temp or
                                          self._device_control.can_set_color):
            temp = kwargs[ATTR_COLOR_TEMP]
            # White Spectrum bulb
            if self._device_control.can_set_temp:
                if temp > self.max_mireds:
                    temp = self.max_mireds
                elif temp < self.min_mireds:
                    temp = self.min_mireds
                temp_data = {
                    ATTR_COLOR_TEMP: temp,
                    ATTR_TRANSITION_TIME: transition_time,
                }
                temp_command = self._device_control.set_color_temp(**temp_data)
                transition_time = None
            # Color bulb (CWS)
            # color_temp needs to be set with hue/saturation
            elif self._device_control.can_set_color:
                temp_k = color_util.color_temperature_mired_to_kelvin(temp)
                hs_color = color_util.color_temperature_to_hs(temp_k)
                hue = int(hs_color[0] * (self._device_control.max_hue / 360))
                sat = int(hs_color[1] *
                          (self._device_control.max_saturation / 100))
                color_data = {
                    ATTR_HUE: hue,
                    ATTR_SAT: sat,
                    ATTR_TRANSITION_TIME: transition_time,
                }
                color_command = self._device_control.set_hsb(**color_data)
                transition_time = None

        # HSB can always be set, but color temp + brightness is bulb dependent
        command = dimmer_command
        if command is not None:
            command += color_command
        else:
            command = color_command

        if self._device_control.can_combine_commands:
            await self._api(command + temp_command)
        else:
            if temp_command is not None:
                await self._api(temp_command)
            if command is not None:
                await self._api(command)
Exemplo n.º 54
0
 async def async_turn_on(self, **kwargs: Any) -> None:
     """Turn on the light."""
     if (color_temp := kwargs.get(ATTR_COLOR_TEMP)) is not None:
         self._device.light_color_temperature = color_temperature_mired_to_kelvin(
             color_temp)
Exemplo n.º 55
0
    async def async_turn_on(self, **kwargs: Any) -> None:
        """Turn on light."""
        if self.block.type == "relay":
            self.control_result = await self.set_state(turn="on")
            self.async_write_ha_state()
            return

        set_mode = None
        supported_color_modes = self._attr_supported_color_modes
        params: dict[str, Any] = {"turn": "on"}

        if ATTR_TRANSITION in kwargs:
            params["transition"] = min(int(kwargs[ATTR_TRANSITION] * 1000),
                                       MAX_TRANSITION_TIME)

        if ATTR_BRIGHTNESS in kwargs and brightness_supported(
                supported_color_modes):
            brightness_pct = int(100 * (kwargs[ATTR_BRIGHTNESS] + 1) / 255)
            if hasattr(self.block, "gain"):
                params["gain"] = brightness_pct
            if hasattr(self.block, "brightness"):
                params["brightness"] = brightness_pct

        if ATTR_COLOR_TEMP in kwargs and ColorMode.COLOR_TEMP in supported_color_modes:
            color_temp = color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP])
            color_temp = min(self._max_kelvin, max(self._min_kelvin,
                                                   color_temp))
            # Color temperature change - used only in white mode, switch device mode to white
            set_mode = "white"
            params["temp"] = int(color_temp)

        if ATTR_RGB_COLOR in kwargs and ColorMode.RGB in supported_color_modes:
            # Color channels change - used only in color mode, switch device mode to color
            set_mode = "color"
            (params["red"], params["green"],
             params["blue"]) = kwargs[ATTR_RGB_COLOR]

        if ATTR_RGBW_COLOR in kwargs and ColorMode.RGBW in supported_color_modes:
            # Color channels change - used only in color mode, switch device mode to color
            set_mode = "color"
            (params["red"], params["green"], params["blue"],
             params["white"]) = kwargs[ATTR_RGBW_COLOR]

        if ATTR_EFFECT in kwargs and ATTR_COLOR_TEMP not in kwargs:
            # Color effect change - used only in color mode, switch device mode to color
            set_mode = "color"
            if self.wrapper.model == "SHBLB-1":
                effect_dict = SHBLB_1_RGB_EFFECTS
            else:
                effect_dict = STANDARD_RGB_EFFECTS
            if kwargs[ATTR_EFFECT] in effect_dict.values():
                params["effect"] = [
                    k for k, v in effect_dict.items()
                    if v == kwargs[ATTR_EFFECT]
                ][0]
            else:
                LOGGER.error(
                    "Effect '%s' not supported by device %s",
                    kwargs[ATTR_EFFECT],
                    self.wrapper.model,
                )

        if (set_mode and set_mode != self.mode
                and self.wrapper.model in DUAL_MODE_LIGHT_MODELS):
            params["mode"] = set_mode

        self.control_result = await self.set_state(**params)
        self.async_write_ha_state()
Exemplo n.º 56
0
    async def async_handle_light_on_service(light, call):
        """Handle turning a light on.

        If brightness is set to 0, this service will turn the light off.
        """
        params = dict(call.data["params"])

        # Only process params once we processed brightness step
        if params and (ATTR_BRIGHTNESS_STEP in params
                       or ATTR_BRIGHTNESS_STEP_PCT in params):
            brightness = light.brightness if light.is_on else 0

            if ATTR_BRIGHTNESS_STEP in params:
                brightness += params.pop(ATTR_BRIGHTNESS_STEP)

            else:
                brightness += round(
                    params.pop(ATTR_BRIGHTNESS_STEP_PCT) / 100 * 255)

            params[ATTR_BRIGHTNESS] = max(0, min(255, brightness))

            preprocess_turn_on_alternatives(hass, params)

        if (not params or
                not light.is_on) or (params and ATTR_TRANSITION not in params):
            profiles.apply_default(light.entity_id, light.is_on, params)

        legacy_supported_color_modes = (
            light._light_internal_supported_color_modes  # pylint: disable=protected-access
        )
        supported_color_modes = light.supported_color_modes
        # Backwards compatibility: if an RGBWW color is specified, convert to RGB + W
        # for legacy lights
        if ATTR_RGBW_COLOR in params:
            if (ColorMode.RGBW in legacy_supported_color_modes
                    and not supported_color_modes):
                rgbw_color = params.pop(ATTR_RGBW_COLOR)
                params[ATTR_RGB_COLOR] = rgbw_color[0:3]
                params[ATTR_WHITE_VALUE] = rgbw_color[3]

        # If a color temperature is specified, emulate it if not supported by the light
        if ATTR_COLOR_TEMP in params:
            if (supported_color_modes
                    and ColorMode.COLOR_TEMP not in supported_color_modes
                    and ColorMode.RGBWW in supported_color_modes):
                color_temp = params.pop(ATTR_COLOR_TEMP)
                brightness = params.get(ATTR_BRIGHTNESS, light.brightness)
                params[
                    ATTR_RGBWW_COLOR] = color_util.color_temperature_to_rgbww(
                        color_temp, brightness, light.min_mireds,
                        light.max_mireds)
            elif ColorMode.COLOR_TEMP not in legacy_supported_color_modes:
                color_temp = params.pop(ATTR_COLOR_TEMP)
                if color_supported(legacy_supported_color_modes):
                    temp_k = color_util.color_temperature_mired_to_kelvin(
                        color_temp)
                    params[ATTR_HS_COLOR] = color_util.color_temperature_to_hs(
                        temp_k)

        # If a color is specified, convert to the color space supported by the light
        # Backwards compatibility: Fall back to hs color if light.supported_color_modes
        # is not implemented
        if not supported_color_modes:
            if (rgb_color := params.pop(ATTR_RGB_COLOR, None)) is not None:
                params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
            elif (xy_color := params.pop(ATTR_XY_COLOR, None)) is not None:
                params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
Exemplo n.º 57
0
def entity_to_device(entity: Entity, units: UnitSystem):
    """Convert a hass entity into an google actions device."""
    class_data = MAPPING_COMPONENT.get(
        entity.attributes.get(ATTR_GOOGLE_ASSISTANT_TYPE) or entity.domain)
    if class_data is None:
        return None

    device = {
        'id': entity.entity_id,
        'name': {},
        'attributes': {},
        'traits': [],
        'willReportState': False,
    }
    device['type'] = class_data[0]
    device['traits'].append(class_data[1])

    # handle custom names
    device['name']['name'] = \
        entity.attributes.get(ATTR_GOOGLE_ASSISTANT_NAME) or \
        entity.attributes.get(CONF_FRIENDLY_NAME)

    # use aliases
    aliases = entity.attributes.get(CONF_ALIASES)
    if aliases:
        if isinstance(aliases, list):
            device['name']['nicknames'] = aliases
        else:
            _LOGGER.warning("%s must be a list", CONF_ALIASES)

    # add trait if entity supports feature
    if class_data[2]:
        supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
        for feature, trait in class_data[2].items():
            if feature & supported > 0:
                device['traits'].append(trait)

                # Actions require this attributes for a device
                # supporting temperature
                # For IKEA trådfri, these attributes only seem to
                # be set only if the device is on?
                if trait == TRAIT_COLOR_TEMP:
                    if entity.attributes.get(
                            light.ATTR_MAX_MIREDS) is not None:
                        device['attributes']['temperatureMinK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MAX_MIREDS))))
                    if entity.attributes.get(
                            light.ATTR_MIN_MIREDS) is not None:
                        device['attributes']['temperatureMaxK'] =  \
                            int(round(color.color_temperature_mired_to_kelvin(
                                entity.attributes.get(light.ATTR_MIN_MIREDS))))

    if entity.domain == climate.DOMAIN:
        modes = ','.join(
            m.lower()
            for m in entity.attributes.get(climate.ATTR_OPERATION_LIST, [])
            if m.lower() in CLIMATE_SUPPORTED_MODES)
        device['attributes'] = {
            'availableThermostatModes':
            modes,
            'thermostatTemperatureUnit':
            'F' if units.temperature_unit == TEMP_FAHRENHEIT else 'C',
        }
        _LOGGER.debug('Thermostat attributes %s', device['attributes'])
    return device
Exemplo n.º 58
0
class Light(HomeAccessory):
    """Generate a Light accessory for a light entity.

    Currently supports: state, brightness, color temperature, rgb_color.
    """
    def __init__(self, *args):
        """Initialize a new Light accessory object."""
        super().__init__(*args, category=CATEGORY_LIGHTBULB)

        self.chars = []
        self._event_timer = None
        self._pending_events = {}

        state = self.hass.states.get(self.entity_id)
        attributes = state.attributes
        self.color_modes = color_modes = (
            attributes.get(ATTR_SUPPORTED_COLOR_MODES) or [])
        self._previous_color_mode = attributes.get(ATTR_COLOR_MODE)
        self.color_supported = color_supported(color_modes)
        self.color_temp_supported = color_temp_supported(color_modes)
        self.rgbw_supported = COLOR_MODE_RGBW in color_modes
        self.rgbww_supported = COLOR_MODE_RGBWW in color_modes
        self.white_supported = COLOR_MODE_WHITE in color_modes
        self.brightness_supported = brightness_supported(color_modes)

        if self.brightness_supported:
            self.chars.append(CHAR_BRIGHTNESS)

        if self.color_supported:
            self.chars.extend([CHAR_HUE, CHAR_SATURATION])

        if self.color_temp_supported or COLOR_MODES_WITH_WHITES.intersection(
                self.color_modes):
            self.chars.append(CHAR_COLOR_TEMPERATURE)

        serv_light = self.add_preload_service(SERV_LIGHTBULB, self.chars)
        self.char_on = serv_light.configure_char(CHAR_ON, value=0)

        if self.brightness_supported:
            # Initial value is set to 100 because 0 is a special value (off). 100 is
            # an arbitrary non-zero value. It is updated immediately by async_update_state
            # to set to the correct initial value.
            self.char_brightness = serv_light.configure_char(CHAR_BRIGHTNESS,
                                                             value=100)

        if CHAR_COLOR_TEMPERATURE in self.chars:
            self.min_mireds = math.floor(
                attributes.get(ATTR_MIN_MIREDS, DEFAULT_MIN_MIREDS))
            self.max_mireds = math.ceil(
                attributes.get(ATTR_MAX_MIREDS, DEFAULT_MAX_MIREDS))
            if not self.color_temp_supported and not self.rgbww_supported:
                self.max_mireds = self.min_mireds
            self.char_color_temp = serv_light.configure_char(
                CHAR_COLOR_TEMPERATURE,
                value=self.min_mireds,
                properties={
                    PROP_MIN_VALUE: self.min_mireds,
                    PROP_MAX_VALUE: self.max_mireds,
                },
            )

        if self.color_supported:
            self.char_hue = serv_light.configure_char(CHAR_HUE, value=0)
            self.char_saturation = serv_light.configure_char(CHAR_SATURATION,
                                                             value=75)

        self.async_update_state(state)
        serv_light.setter_callback = self._set_chars

    def _set_chars(self, char_values):
        _LOGGER.debug("Light _set_chars: %s", char_values)
        # Newest change always wins
        if CHAR_COLOR_TEMPERATURE in self._pending_events and (
                CHAR_SATURATION in char_values or CHAR_HUE in char_values):
            del self._pending_events[CHAR_COLOR_TEMPERATURE]
        for char in (CHAR_HUE, CHAR_SATURATION):
            if char in self._pending_events and CHAR_COLOR_TEMPERATURE in char_values:
                del self._pending_events[char]

        self._pending_events.update(char_values)
        if self._event_timer:
            self._event_timer()
        self._event_timer = async_call_later(self.hass,
                                             CHANGE_COALESCE_TIME_WINDOW,
                                             self._async_send_events)

    @callback
    def _async_send_events(self, *_):
        """Process all changes at once."""
        _LOGGER.debug("Coalesced _set_chars: %s", self._pending_events)
        char_values = self._pending_events
        self._pending_events = {}
        events = []
        service = SERVICE_TURN_ON
        params = {ATTR_ENTITY_ID: self.entity_id}

        if CHAR_ON in char_values:
            if not char_values[CHAR_ON]:
                service = SERVICE_TURN_OFF
            events.append(f"Set state to {char_values[CHAR_ON]}")

        brightness_pct = None
        if CHAR_BRIGHTNESS in char_values:
            if char_values[CHAR_BRIGHTNESS] == 0:
                events[-1] = "Set state to 0"
                service = SERVICE_TURN_OFF
            else:
                brightness_pct = char_values[CHAR_BRIGHTNESS]
            events.append(f"brightness at {char_values[CHAR_BRIGHTNESS]}%")

        if service == SERVICE_TURN_OFF:
            self.async_call_service(DOMAIN, service,
                                    {ATTR_ENTITY_ID: self.entity_id},
                                    ", ".join(events))
            return

        # Handle white channels
        if CHAR_COLOR_TEMPERATURE in char_values:
            temp = char_values[CHAR_COLOR_TEMPERATURE]
            events.append(f"color temperature at {temp}")
            bright_val = round(
                ((brightness_pct or self.char_brightness.value) * 255) / 100)
            if self.color_temp_supported:
                params[ATTR_COLOR_TEMP] = temp
            elif self.rgbww_supported:
                params[ATTR_RGBWW_COLOR] = color_temperature_to_rgbww(
                    temp, bright_val, self.min_mireds, self.max_mireds)
            elif self.rgbw_supported:
                params[ATTR_RGBW_COLOR] = (*(0, ) * 3, bright_val)
            elif self.white_supported:
                params[ATTR_WHITE] = bright_val

        elif CHAR_HUE in char_values or CHAR_SATURATION in char_values:
            hue_sat = (
                char_values.get(CHAR_HUE, self.char_hue.value),
                char_values.get(CHAR_SATURATION, self.char_saturation.value),
            )
            _LOGGER.debug("%s: Set hs_color to %s", self.entity_id, hue_sat)
            events.append(f"set color at {hue_sat}")
            params[ATTR_HS_COLOR] = hue_sat

        if (brightness_pct and ATTR_RGBWW_COLOR not in params
                and ATTR_RGBW_COLOR not in params):
            params[ATTR_BRIGHTNESS_PCT] = brightness_pct

        _LOGGER.debug("Calling light service with params: %s -> %s",
                      char_values, params)
        self.async_call_service(DOMAIN, service, params, ", ".join(events))

    @callback
    def async_update_state(self, new_state):
        """Update light after state change."""
        # Handle State
        state = new_state.state
        attributes = new_state.attributes
        color_mode = attributes.get(ATTR_COLOR_MODE)
        self.char_on.set_value(int(state == STATE_ON))
        color_mode_changed = self._previous_color_mode != color_mode
        self._previous_color_mode = color_mode

        # Handle Brightness
        if (self.brightness_supported
                and (brightness := attributes.get(ATTR_BRIGHTNESS)) is not None
                and isinstance(brightness, (int, float))):
            brightness = round(brightness / 255 * 100, 0)
            # The homeassistant component might report its brightness as 0 but is
            # not off. But 0 is a special value in homekit. When you turn on a
            # homekit accessory it will try to restore the last brightness state
            # which will be the last value saved by char_brightness.set_value.
            # But if it is set to 0, HomeKit will update the brightness to 100 as
            # it thinks 0 is off.
            #
            # Therefore, if the the brightness is 0 and the device is still on,
            # the brightness is mapped to 1 otherwise the update is ignored in
            # order to avoid this incorrect behavior.
            if brightness == 0 and state == STATE_ON:
                brightness = 1
            self.char_brightness.set_value(brightness)
            if color_mode_changed:
                self.char_brightness.notify()

        # Handle Color - color must always be set before color temperature
        # or the iOS UI will not display it correctly.
        if self.color_supported:
            if color_temp := attributes.get(ATTR_COLOR_TEMP):
                hue, saturation = color_temperature_to_hs(
                    color_temperature_mired_to_kelvin(color_temp))
            elif color_mode == COLOR_MODE_WHITE:
                hue, saturation = 0, 0
            else:
                hue, saturation = attributes.get(ATTR_HS_COLOR, (None, None))
            if isinstance(hue,
                          (int, float)) and isinstance(saturation,
                                                       (int, float)):
                self.char_hue.set_value(round(hue, 0))
                self.char_saturation.set_value(round(saturation, 0))
                if color_mode_changed:
                    # If the color temp changed, be sure to force the color to update
                    self.char_hue.notify()
                    self.char_saturation.notify()