1 """Support for Osram Lightify."""
3 from __future__
import annotations
9 from lightify
import Lightify
10 import voluptuous
as vol
19 PLATFORM_SCHEMA
as LIGHT_PLATFORM_SCHEMA,
32 _LOGGER = logging.getLogger(__name__)
34 CONF_ALLOW_LIGHTIFY_NODES =
"allow_lightify_nodes"
35 CONF_ALLOW_LIGHTIFY_GROUPS =
"allow_lightify_groups"
36 CONF_ALLOW_LIGHTIFY_SENSORS =
"allow_lightify_sensors"
37 CONF_ALLOW_LIGHTIFY_SWITCHES =
"allow_lightify_switches"
38 CONF_INTERVAL_LIGHTIFY_STATUS =
"interval_lightify_status"
39 CONF_INTERVAL_LIGHTIFY_CONF =
"interval_lightify_conf"
41 DEFAULT_ALLOW_LIGHTIFY_NODES =
True
42 DEFAULT_ALLOW_LIGHTIFY_GROUPS =
True
43 DEFAULT_ALLOW_LIGHTIFY_SENSORS =
True
44 DEFAULT_ALLOW_LIGHTIFY_SWITCHES =
True
45 DEFAULT_INTERVAL_LIGHTIFY_STATUS = 5
46 DEFAULT_INTERVAL_LIGHTIFY_CONF = 3600
48 PLATFORM_SCHEMA = LIGHT_PLATFORM_SCHEMA.extend(
50 vol.Required(CONF_HOST): cv.string,
52 CONF_ALLOW_LIGHTIFY_NODES, default=DEFAULT_ALLOW_LIGHTIFY_NODES
55 CONF_ALLOW_LIGHTIFY_GROUPS, default=DEFAULT_ALLOW_LIGHTIFY_GROUPS
58 CONF_ALLOW_LIGHTIFY_SENSORS, default=DEFAULT_ALLOW_LIGHTIFY_SENSORS
61 CONF_ALLOW_LIGHTIFY_SWITCHES, default=DEFAULT_ALLOW_LIGHTIFY_SWITCHES
64 CONF_INTERVAL_LIGHTIFY_STATUS, default=DEFAULT_INTERVAL_LIGHTIFY_STATUS
67 CONF_INTERVAL_LIGHTIFY_CONF, default=DEFAULT_INTERVAL_LIGHTIFY_CONF
72 DEFAULT_BRIGHTNESS = 2
79 add_entities: AddEntitiesCallback,
80 discovery_info: DiscoveryInfoType |
None =
None,
82 """Set up the Osram Lightify lights."""
83 host = config[CONF_HOST]
85 bridge = Lightify(host, log_level=logging.NOTSET)
87 _LOGGER.exception(
"Error connecting to bridge %s", host)
94 """Set up the Lightify bridge."""
97 groups_last_updated = [0]
100 """Update the lights objects with the latest info from the bridge."""
102 new_lights = bridge.update_all_light_status(
103 config[CONF_INTERVAL_LIGHTIFY_STATUS]
105 lights_changed = bridge.lights_changed()
107 _LOGGER.error(
"Timeout during updating of lights")
110 _LOGGER.error(
"OSError during updating of lights")
113 if new_lights
and config[CONF_ALLOW_LIGHTIFY_NODES]:
115 for addr, light
in new_lights.items():
117 light.devicetype().name ==
"SENSOR"
118 and not config[CONF_ALLOW_LIGHTIFY_SENSORS]
120 light.devicetype().name ==
"SWITCH"
121 and not config[CONF_ALLOW_LIGHTIFY_SWITCHES]
125 if addr
not in lights:
127 light, update_lights, lights_changed
129 lights[addr] = osram_light
130 new_entities.append(osram_light)
132 lights[addr].update_luminary(light)
136 return lights_changed
139 """Update the groups objects with the latest info from the bridge."""
140 lights_changed = update_lights()
143 bridge.update_scene_list(config[CONF_INTERVAL_LIGHTIFY_CONF])
144 new_groups = bridge.update_group_list(config[CONF_INTERVAL_LIGHTIFY_CONF])
145 groups_updated = bridge.groups_updated()
147 _LOGGER.error(
"Timeout during updating of scenes/groups")
150 _LOGGER.error(
"OSError during updating of scenes/groups")
154 new_groups = {group.idx(): group
for group
in new_groups.values()}
156 for idx, group
in new_groups.items():
157 if idx
not in groups:
159 group, update_groups, groups_updated
161 groups[idx] = osram_group
162 new_entities.append(osram_group)
164 groups[idx].update_luminary(group)
168 if groups_updated > groups_last_updated[0]:
169 groups_last_updated[0] = groups_updated
170 for idx, osram_group
in groups.items():
171 if idx
not in new_groups:
172 osram_group.update_static_attributes()
174 return max(lights_changed, groups_updated)
177 if config[CONF_ALLOW_LIGHTIFY_GROUPS]:
182 """Representation of Luminary Lights and Groups."""
184 def __init__(self, luminary, update_func, changed):
185 """Initialize a Luminary Light."""
205 """Get a unique ID (not implemented)."""
206 raise NotImplementedError
209 """Get supported color modes."""
210 color_modes: set[ColorMode] = set()
212 color_modes.add(ColorMode.COLOR_TEMP)
215 color_modes.add(ColorMode.HS)
218 color_modes.add(ColorMode.BRIGHTNESS)
221 color_modes.add(ColorMode.ONOFF)
226 """Get list of supported features."""
229 features = features | LightEntityFeature.TRANSITION
232 features = features | LightEntityFeature.TRANSITION
236 features | LightEntityFeature.TRANSITION | LightEntityFeature.EFFECT
242 """Get list of supported effects."""
245 effects.append(EFFECT_RANDOM)
251 """Return the name of the luminary."""
256 """Return last hs color value set."""
257 return color_util.color_RGB_to_hs(*self.
_rgb_color_rgb_color)
261 """Return the color temperature."""
266 """Return brightness of the luminary (0..255)."""
271 """Return True if the device is on."""
276 """List of supported effects."""
281 """Return the coldest color_temp that this light supports."""
286 """Return the warmest color_temp that this light supports."""
291 """Return a unique ID."""
296 """Return device specific state attributes."""
301 """Return True if entity is available."""
305 """Play selected effect."""
306 if effect == EFFECT_RANDOM:
308 random.randrange(0, 256),
309 random.randrange(0, 256),
310 random.randrange(0, 256),
319 """Turn the device on."""
320 transition =
int(kwargs.get(ATTR_TRANSITION, 0) * 10)
321 if ATTR_EFFECT
in kwargs:
322 self.
play_effectplay_effect(kwargs[ATTR_EFFECT], transition)
325 if ATTR_HS_COLOR
in kwargs:
326 self.
_rgb_color_rgb_color = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
329 if ATTR_COLOR_TEMP
in kwargs:
330 self.
_color_temp_color_temp = kwargs[ATTR_COLOR_TEMP]
332 int(color_util.color_temperature_mired_to_kelvin(self.
_color_temp_color_temp)),
337 if ATTR_BRIGHTNESS
in kwargs:
338 self.
_brightness_brightness = kwargs[ATTR_BRIGHTNESS]
344 """Turn the device off."""
346 if ATTR_TRANSITION
in kwargs:
347 transition =
int(kwargs[ATTR_TRANSITION] * 10)
349 self.
_luminary_luminary.set_luminance(0, transition)
354 """Update internal luminary object."""
359 """Update static attributes of the luminary."""
365 self.
_min_mireds_min_mireds = color_util.color_temperature_kelvin_to_mired(
366 self.
_luminary_luminary.max_temp()
or DEFAULT_KELVIN
368 self.
_max_mireds_max_mireds = color_util.color_temperature_kelvin_to_mired(
369 self.
_luminary_luminary.min_temp()
or DEFAULT_KELVIN
376 """Update dynamic attributes of the luminary."""
383 self.
_color_temp_color_temp = color_util.color_temperature_kelvin_to_mired(
384 self.
_luminary_luminary.temp()
or DEFAULT_KELVIN
398 """Synchronize state with bridge."""
406 """Representation of an Osram Lightify Light."""
409 """Get a unique ID."""
413 """Update static attributes of the luminary."""
417 f
"{self._luminary.type_id()} ({self._luminary.devicename()})"
421 if self.
_luminary_luminary.devicetype().name ==
"SENSOR":
422 attrs[
"sensor_values"] = self.
_luminary_luminary.raw_values()
428 """Representation of an Osram Lightify Group."""
431 """Get a unique ID for the group."""
439 return f
"{self._luminary.lights()}"
442 """Get list of supported features."""
445 features |= LightEntityFeature.EFFECT
450 """Get list of supported effects."""
452 effects.extend(self.
_luminary_luminary.scenes())
453 return sorted(effects)
456 """Play selected effect."""
460 if effect
in self.
_luminary_luminary.scenes():
461 self.
_luminary_luminary.activate_scene(effect)
467 """Update static attributes of the luminary."""
LightEntityFeature supported_features(self)
LightEntityFeature _get_supported_features(self)
def __init__(self, luminary, update_func, changed)
_attr_supported_color_modes
set[ColorMode] _get_supported_color_modes(self)
def play_effect(self, effect, transition)
def update_dynamic_attributes(self)
None turn_off(self, **Any kwargs)
def extra_state_attributes(self)
def update_luminary(self, luminary)
def _get_effect_list(self)
None update_static_attributes(self)
None turn_on(self, **Any kwargs)
def play_effect(self, effect, transition)
def update_static_attributes(self)
def _get_effect_list(self)
LightEntityFeature _get_supported_features(self)
def update_static_attributes(self)
None add_entities(AsusWrtRouter router, AddEntitiesCallback async_add_entities, set[str] tracked)
bool brightness_supported(Iterable[ColorMode|str]|None color_modes)
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
def setup_bridge(bridge, add_entities, config)