def test_color_xy_brightness_to_RGB(self): """Test color_xy_brightness_to_RGB.""" assert (0, 0, 0) == \ color_util.color_xy_brightness_to_RGB(1, 1, 0) assert (194, 186, 169) == \ color_util.color_xy_brightness_to_RGB(.35, .35, 128) assert (255, 243, 222) == \ color_util.color_xy_brightness_to_RGB(.35, .35, 255) assert (255, 0, 60) == \ color_util.color_xy_brightness_to_RGB(1, 0, 255) assert (0, 255, 0) == \ color_util.color_xy_brightness_to_RGB(0, 1, 255) assert (0, 63, 255) == \ color_util.color_xy_brightness_to_RGB(0, 0, 255) assert (255, 0, 3) == \ color_util.color_xy_brightness_to_RGB(1, 0, 255, GAMUT) assert (82, 255, 0) == \ color_util.color_xy_brightness_to_RGB(0, 1, 255, GAMUT) assert (9, 85, 255) == \ color_util.color_xy_brightness_to_RGB(0, 0, 255, GAMUT)
def test_color_xy_brightness_to_RGB(self): """ Test color_RGB_to_xy. """ self.assertEqual((0, 0, 0), color_util.color_xy_brightness_to_RGB(1, 1, 0)) self.assertEqual((255, 235, 214), color_util.color_xy_brightness_to_RGB(.35, .35, 255)) self.assertEqual((255, 0, 45), color_util.color_xy_brightness_to_RGB(1, 0, 255)) self.assertEqual((0, 255, 0), color_util.color_xy_brightness_to_RGB(0, 1, 255)) self.assertEqual((0, 83, 255), color_util.color_xy_brightness_to_RGB(0, 0, 255))
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()
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()
def test_color_xy_brightness_to_RGB(): """Test color_xy_brightness_to_RGB.""" assert color_util.color_xy_brightness_to_RGB(1, 1, 0) == (0, 0, 0) assert color_util.color_xy_brightness_to_RGB(0.35, 0.35, 128) == (194, 186, 169) assert color_util.color_xy_brightness_to_RGB(0.35, 0.35, 255) == (255, 243, 222) assert color_util.color_xy_brightness_to_RGB(1, 0, 255) == (255, 0, 60) assert color_util.color_xy_brightness_to_RGB(0, 1, 255) == (0, 255, 0) assert color_util.color_xy_brightness_to_RGB(0, 0, 255) == (0, 63, 255) assert color_util.color_xy_brightness_to_RGB(1, 0, 255, GAMUT) == (255, 0, 3) assert color_util.color_xy_brightness_to_RGB(0, 1, 255, GAMUT) == (82, 255, 0) assert color_util.color_xy_brightness_to_RGB(0, 0, 255, GAMUT) == (9, 85, 255)
def turn_on(self, **kwargs) -> None: """Turn the bulb on.""" import yeelight brightness = kwargs.get(ATTR_BRIGHTNESS) colortemp = kwargs.get(ATTR_COLOR_TEMP) rgb = kwargs.get(ATTR_RGB_COLOR) flash = kwargs.get(ATTR_FLASH) effect = kwargs.get(ATTR_EFFECT) xy_color = kwargs.get(ATTR_XY_COLOR) duration = int(self.config[CONF_TRANSITION]) # in ms if ATTR_TRANSITION in kwargs: # passed kwarg overrides config duration = int(kwargs.get(ATTR_TRANSITION) * 1000) # kwarg in s try: self._bulb.turn_on(duration=duration) except yeelight.BulbException as ex: _LOGGER.error("Unable to turn the bulb on: %s", ex) return if self.config[CONF_MODE_MUSIC] and not self._bulb.music_mode: try: self.set_music_mode(self.config[CONF_MODE_MUSIC]) except yeelight.BulbException as ex: _LOGGER.error( "Unable to turn on music mode," "consider disabling it: %s", ex) if xy_color and brightness: rgb = color_xy_brightness_to_RGB(xy_color[0], xy_color[1], brightness) try: # values checked for none in methods self.set_rgb(rgb, duration) self.set_colortemp(colortemp, duration) self.set_brightness(brightness, duration) self.set_flash(flash) self.set_effect(effect) except yeelight.BulbException as ex: _LOGGER.error("Unable to set bulb properties: %s", ex) return # save the current state if we had a manual change. if self.config[CONF_SAVE_ON_CHANGE] and (brightness or colortemp or rgb): try: self.set_default() except yeelight.BulbException as ex: _LOGGER.error("Unable to set the defaults: %s", ex) return
def turn_on(self, **kwargs) -> None: """Turn the bulb on.""" import yeelight brightness = kwargs.get(ATTR_BRIGHTNESS) colortemp = kwargs.get(ATTR_COLOR_TEMP) rgb = kwargs.get(ATTR_RGB_COLOR) flash = kwargs.get(ATTR_FLASH) effect = kwargs.get(ATTR_EFFECT) xy_color = kwargs.get(ATTR_XY_COLOR) duration = int(self.config[CONF_TRANSITION]) # in ms if ATTR_TRANSITION in kwargs: # passed kwarg overrides config duration = int(kwargs.get(ATTR_TRANSITION) * 1000) # kwarg in s try: self._bulb.turn_on(duration=duration) except yeelight.BulbException as ex: _LOGGER.error("Unable to turn the bulb on: %s", ex) return if self.config[CONF_MODE_MUSIC] and not self._bulb.music_mode: try: self.set_music_mode(self.config[CONF_MODE_MUSIC]) except yeelight.BulbException as ex: _LOGGER.error("Unable to turn on music mode," "consider disabling it: %s", ex) if xy_color and brightness: rgb = color_xy_brightness_to_RGB(xy_color[0], xy_color[1], brightness) try: # values checked for none in methods self.set_rgb(rgb, duration) self.set_colortemp(colortemp, duration) self.set_brightness(brightness, duration) self.set_flash(flash) self.set_effect(effect) except yeelight.BulbException as ex: _LOGGER.error("Unable to set bulb properties: %s", ex) return # save the current state if we had a manual change. if self.config[CONF_SAVE_ON_CHANGE] and (brightness or colortemp or rgb): try: self.set_default() except yeelight.BulbException as ex: _LOGGER.error("Unable to set the defaults: %s", ex) return
def state_attributes(self): """ Returns optional state attributes. """ data = {} if self.is_on: for prop, attr in PROP_TO_ATTR.items(): value = getattr(self, prop) if value: data[attr] = value if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \ ATTR_BRIGHTNESS in data: data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB( data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1], data[ATTR_BRIGHTNESS]) return data
def state_attributes(self): """Return optional state attributes.""" data = {} if self.is_on: for prop, attr in PROP_TO_ATTR.items(): value = getattr(self, prop) if value is not None: data[attr] = value if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \ ATTR_BRIGHTNESS in data: data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB( data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1], data[ATTR_BRIGHTNESS]) return data
def state_attributes(self): """Return optional state attributes.""" data = {} if self.is_on: for prop, attr in PROP_TO_ATTR.items(): value = getattr(self, prop) if value is not None: data[attr] = value if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \ ATTR_BRIGHTNESS in data: data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB( data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1], data[ATTR_BRIGHTNESS]) else: data[ATTR_SUPPORTED_FEATURES] = self.supported_features return data
def state_attributes(self): """Return optional state attributes.""" data = {} if self.is_on: for prop, attr in list(PROP_TO_ATTR.items()): value = getattr(self, prop) if value is not None: data[attr] = value if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \ ATTR_BRIGHTNESS in data: data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB( data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1], data[ATTR_BRIGHTNESS]) else: data[ATTR_SUPPORTED_FEATURES] = self.supported_features return data
def state_attributes(self): """Return optional state attributes.""" data = {} if self.supported_features & SUPPORT_COLOR_TEMP: data[ATTR_MIN_MIREDS] = self.min_mireds data[ATTR_MAX_MIREDS] = self.max_mireds if self.is_on: for prop, attr in PROP_TO_ATTR.items(): value = getattr(self, prop) if value is not None: data[attr] = value if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \ ATTR_BRIGHTNESS in data: data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB( data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1], data[ATTR_BRIGHTNESS]) return data
def test_color_xy_brightness_to_RGB(self): """Test color_xy_brightness_to_RGB.""" self.assertEqual((0, 0, 0), color_util.color_xy_brightness_to_RGB(1, 1, 0)) self.assertEqual((194, 186, 169), color_util.color_xy_brightness_to_RGB(.35, .35, 128)) self.assertEqual((255, 243, 222), color_util.color_xy_brightness_to_RGB(.35, .35, 255)) self.assertEqual((255, 0, 60), color_util.color_xy_brightness_to_RGB(1, 0, 255)) self.assertEqual((0, 255, 0), color_util.color_xy_brightness_to_RGB(0, 1, 255)) self.assertEqual((0, 63, 255), color_util.color_xy_brightness_to_RGB(0, 0, 255))
def put(self, request, username, entity_number): """Process a request to set the state of an individual light.""" config = self.config hass = request.app['hass'] entity_id = config.number_to_entity_id(entity_number) if entity_id is None: _LOGGER.error('Unknown entity number: %s', entity_number) return self.json_message('Entity not found', HTTP_NOT_FOUND) entity = hass.states.get(entity_id) if entity is None: _LOGGER.error('Entity not found: %s', entity_id) return self.json_message('Entity not found', HTTP_NOT_FOUND) if not config.is_entity_exposed(entity): _LOGGER.error('Entity not exposed: %s', entity_id) return web.Response(text="Entity not exposed", status=404) try: request_json = yield from request.json() except ValueError: _LOGGER.error('Received invalid json') return self.json_message('Invalid JSON', HTTP_BAD_REQUEST) # Parse the request into requested "on" status and brightness parsed = parse_hue_api_put_light_body(request_json, entity) if parsed is None: _LOGGER.error('Unable to parse data: %s', request_json) return web.Response(text="Bad request", status=400) result, brightness, color, color_temp = parsed # Choose general HA domain domain = core.DOMAIN # Entity needs separate call to turn on turn_on_needed = False # Convert the resulting "on" status into the service we need to call service = SERVICE_TURN_ON if result else SERVICE_TURN_OFF # Construct what we need to send to the service data = {ATTR_ENTITY_ID: entity_id} # Make sure the entity actually supports brightness entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) if entity.domain == "light": if entity_features & SUPPORT_BRIGHTNESS: if brightness is not None: data[ATTR_BRIGHTNESS] = brightness if entity_features & SUPPORT_XY_COLOR: if color is not None: data[ATTR_XY_COLOR] = color elif entity_features & SUPPORT_RGB_COLOR: if color is not None: if brightness is not None: final_brightness = brightness else: final_brightness = entity.attributes.get( ATTR_BRIGHTNESS, 255 if result else 0) data[ATTR_RGB_COLOR] = \ color_util.color_xy_brightness_to_RGB(color[0], color[1], final_brightness) if entity_features & SUPPORT_COLOR_TEMP: if color_temp is not None: data[ATTR_COLOR_TEMP] = color_temp # If the requested entity is a script add some variables elif entity.domain == "script": data['variables'] = { 'requested_state': STATE_ON if result else STATE_OFF } if brightness is not None: data['variables']['requested_level'] = brightness # If the requested entity is a media player, convert to volume elif entity.domain == "media_player": if entity_features & SUPPORT_VOLUME_SET: if brightness is not None: turn_on_needed = True domain = entity.domain service = SERVICE_VOLUME_SET # Convert 0-100 to 0.0-1.0 data[ATTR_MEDIA_VOLUME_LEVEL] = brightness / 100.0 # If the requested entity is a cover, convert to open_cover/close_cover elif entity.domain == "cover": domain = entity.domain if service == SERVICE_TURN_ON: service = SERVICE_OPEN_COVER else: service = SERVICE_CLOSE_COVER # If the requested entity is a fan, convert to speed elif entity.domain == "fan": if entity_features & SUPPORT_SET_SPEED: if brightness is not None: domain = entity.domain # Convert 0-100 to a fan speed if brightness == 0: data[ATTR_SPEED] = SPEED_OFF elif brightness <= 33.3 and brightness > 0: data[ATTR_SPEED] = SPEED_LOW elif brightness <= 66.6 and brightness > 33.3: data[ATTR_SPEED] = SPEED_MEDIUM elif brightness <= 100 and brightness > 66.6: data[ATTR_SPEED] = SPEED_HIGH if entity.domain in config.off_maps_to_on_domains: # Map the off command to on service = SERVICE_TURN_ON # Caching is required because things like scripts and scenes won't # report as "off" to Alexa if an "off" command is received, because # they'll map to "on". Thus, instead of reporting its actual # status, we report what Alexa will want to see, which is the same # as the actual requested command. config.cached_states[entity_id] = (result, brightness) # Separate call to turn on needed if turn_on_needed: hass.async_add_job( hass.services.async_call(core.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True)) hass.async_add_job( hass.services.async_call(domain, service, data, blocking=True)) json_response = \ [create_hue_success_response(entity_id, HUE_API_STATE_ON, result)] if brightness is not None: json_response.append( create_hue_success_response(entity_id, HUE_API_STATE_BRI, brightness)) if color is not None: json_response.append( create_hue_success_response(entity_id, HUE_API_STATE_XY, color)) if color_temp is not None: json_response.append( create_hue_success_response(entity_id, HUE_API_STATE_CT, color_temp)) return self.json(json_response)