├── .gitignore ├── LICENSE ├── README.md └── aurora.py /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Anthony Bryan 4 | Original version at: https://github.com/software-2/ha-aurora 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ha-aurora 2 | Nanoleaf Aurora component for Home Assistant 3 | 4 | ### Alpha Release ### 5 | 6 | Please be aware that this component is still in development. It would be of immense help to me if you could provice feedback, submit bugs, etc. If you work for Nanoleaf, you should send me some more lights to develop with. 7 | 8 | During this time, interfaces and features are subject to change without concern for backwards compatibility. (Meaning I might break your scripts.) 9 | 10 | ### Prerequisites ### 11 | 12 | I believe Home Assistant should automatically grab the Nanoleaf library. Please let me know if it doesn't. If you do need to manually get it, instructions are on [the GitHub Project](https://github.com/software-2/nanoleaf). 13 | 14 | If you don't have an API token, you'll need to generate one using the above library's setup tools. 15 | 16 | ## Install ## 17 | 18 | Copy `aurora.py` into `.homeassistant\custom_components\light` 19 | 20 | ## Setup ## 21 | 22 | Add the following to your `configuration.yaml` file. If you have multiple auroras, add one for each light controller. 23 | 24 | ```yaml 25 | light: 26 | - platform: aurora 27 | host: 192.168.1.113 28 | api_key: 5GPFfAketAKeYq7hC6IsFaKeGTJ6YlUaI7d 29 | name: myAurora 30 | ``` 31 | 32 | I strongly suggest assigning a static IP to your Auroras. Improvements to the Nanoleaf library are planned to find devices with changing IPs, but for now make sure you use a static IP. 33 | 34 | ### Supported Features ### 35 | 36 | * Effects saved to the device 37 | * Color 38 | * Brightness 39 | * Color Temperature 40 | 41 | ### Planned Improvements ### 42 | 43 | * Extra effects built into the library that don't need to be saved to the device's limited storage 44 | * Better device discovery (No IP needed) 45 | 46 | -------------------------------------------------------------------------------- /aurora.py: -------------------------------------------------------------------------------- 1 | from nanoleaf import Aurora 2 | import logging 3 | import voluptuous as vol 4 | 5 | # For instructions or bug reports, please visit 6 | # https://github.com/software-2/ha-aurora 7 | 8 | from homeassistant.components.light import ( 9 | ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, ATTR_COLOR_TEMP, SUPPORT_COLOR_TEMP, ATTR_RGB_COLOR, SUPPORT_RGB_COLOR, Light, PLATFORM_SCHEMA, ATTR_EFFECT, ATTR_EFFECT_LIST, SUPPORT_EFFECT ) 10 | from homeassistant.const import CONF_HOST, CONF_API_KEY, CONF_NAME 11 | import homeassistant.helpers.config_validation as cv 12 | 13 | REQUIREMENTS = ['nanoleaf==0.4.0'] 14 | 15 | SUPPORT_AURORA = ( SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP ) 16 | 17 | 18 | _LOGGER = logging.getLogger(__name__) 19 | 20 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ 21 | vol.Required(CONF_HOST): cv.string, 22 | vol.Required(CONF_API_KEY): cv.string, 23 | vol.Optional(CONF_NAME, default='Aurora'): cv.string, 24 | }) 25 | 26 | 27 | def setup_platform(hass, config, add_devices, discovery_info=None): 28 | host = config.get(CONF_HOST) 29 | apikey = config.get(CONF_API_KEY) 30 | name = config.get(CONF_NAME) 31 | 32 | my_aurora = Aurora(host, apikey) 33 | my_aurora.hass_name = name 34 | 35 | if my_aurora.on is None: 36 | _LOGGER.error("Could not connect to Nanoleaf Aurora: " + name) 37 | 38 | add_devices([AuroraLight(my_aurora)]) 39 | 40 | 41 | # TODO: https://github.com/home-assistant/home-assistant/pull/7596 42 | # Remove ATTR_BRIGHTNESS and replace with ATTR_BRIGHTNESS_PCT 43 | # And switch to kelvin 44 | def brightness_scale_nanoleaf_to_hass(range_value): 45 | # Hass uses 0-255, Aurora uses 0-100 46 | return range_value * 2.55 47 | 48 | def brightness_scale_hass_to_nanoleaf(range_value): 49 | return int(range_value / 2.55) 50 | 51 | def color_temp_scale_nanoleaf_to_hass(range_value): 52 | # Hass uses 154-500, Aurora uses 1200-6500 53 | return ((range_value - 1200) / 5300) * 346 + 154 54 | 55 | def color_temp_scale_hass_to_nanoleaf(range_value): 56 | return int(((range_value - 154) / 346) * 5300 + 1200) 57 | 58 | class AuroraLight(Light): 59 | """Representation of a Nanoleaf Aurora inside Home Assistant.""" 60 | 61 | def __init__(self, light): 62 | """Initialize an Aurora.""" 63 | self._light = light 64 | self._name = light.hass_name 65 | self._state = light.on 66 | self._brightness = brightness_scale_nanoleaf_to_hass(light.brightness) 67 | self._effect = light.effect 68 | self._effects_list = light.effects_list 69 | self._color_temp = color_temp_scale_nanoleaf_to_hass(light.color_temperature) 70 | self._rgb_color = light.rgb 71 | 72 | @property 73 | def name(self): 74 | """Return the display name of this light.""" 75 | return self._name 76 | 77 | @property 78 | def brightness(self): 79 | """Return the brightness of the light.""" 80 | return self._brightness 81 | 82 | @property 83 | def effect_list(self): 84 | """Return the list of supported effects.""" 85 | return self._effects_list 86 | 87 | @property 88 | def effect(self): 89 | """Return the current effect.""" 90 | return self._effect 91 | 92 | @property 93 | def is_on(self): 94 | """Return true if light is on.""" 95 | return self._state 96 | 97 | @property 98 | def color_temp(self): 99 | """Return the current color temperature""" 100 | return self._color_temp 101 | 102 | @property 103 | def rgb_color(self): 104 | """Return the color in RGB""" 105 | return self._rgb_color 106 | 107 | @property 108 | def supported_features(self): 109 | """Flag supported features.""" 110 | return SUPPORT_AURORA 111 | 112 | def turn_on(self, **kwargs): 113 | """Instruct the light to turn on.""" 114 | self._light.on = True 115 | 116 | if ATTR_BRIGHTNESS in kwargs: 117 | new_brightness = brightness_scale_hass_to_nanoleaf(kwargs.get(ATTR_BRIGHTNESS, 255)) 118 | print("BRIGHTNESS: " + str(new_brightness)) 119 | self._light.brightness = new_brightness 120 | 121 | if ATTR_EFFECT in kwargs: 122 | new_effect = kwargs[ATTR_EFFECT] 123 | print("EFFECT: " + str(new_effect)) 124 | self._light.effect = new_effect 125 | 126 | if ATTR_COLOR_TEMP in kwargs: 127 | new_color_temp = color_temp_scale_hass_to_nanoleaf(kwargs.get(ATTR_COLOR_TEMP, 100)) 128 | print("COLOR TEMP: " + str(new_color_temp)) 129 | self._light.color_temperature = new_color_temp 130 | 131 | if ATTR_RGB_COLOR in kwargs: 132 | new_rgb_color = kwargs[ATTR_RGB_COLOR] 133 | print("COLOR RGB: " + str(new_rgb_color)) 134 | self._light.rgb = new_rgb_color 135 | 136 | def turn_off(self, **kwargs): 137 | """Instruct the light to turn off.""" 138 | self._light.on = False 139 | 140 | def update(self): 141 | """Fetch new state data for this light. 142 | 143 | This is the only method that should fetch new data for Home Assistant. 144 | """ 145 | self._state = self._light.on 146 | self._brightness = brightness_scale_nanoleaf_to_hass(self._light.brightness) 147 | self._effect = self._light.effect 148 | self._effects_list = self._light.effects_list 149 | self._color_temp = color_temp_scale_nanoleaf_to_hass(self._light.color_temperature) 150 | self._rgb_color = self._rgb_color 151 | 152 | 153 | --------------------------------------------------------------------------------