From 645cd89406ad31a93d44f7a19ebbaf75229e8d9d Mon Sep 17 00:00:00 2001
From: Michael Auchter
Date: Sun, 27 Sep 2015 15:35:47 -0500
Subject: [PATCH 1/5] limitlessled: fix docstring
---
homeassistant/components/light/limitlessled.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py
index 9096bb32a10..631fcbed64e 100644
--- a/homeassistant/components/light/limitlessled.py
+++ b/homeassistant/components/light/limitlessled.py
@@ -89,7 +89,7 @@ class LimitlessLED(Light):
@property
def should_poll(self):
- """ No polling needed for a demo light. """
+ """ No polling needed. """
return False
@property
From 34531895a014545bdd46a0a32f552718f4b0ad99 Mon Sep 17 00:00:00 2001
From: Michael Auchter
Date: Sun, 27 Sep 2015 16:16:58 -0500
Subject: [PATCH 2/5] limitlessled: Use LedControllerPool
This change is in preparation for adapting this component to support multiple
LimitlessLED bridges. Ultimately LedControllerPool helps to maintain the
mandatory 100ms pauses across multiple controllers so messages are reliably
received.
---
.../components/light/limitlessled.py | 22 +++++++++++--------
requirements_all.txt | 2 +-
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py
index 631fcbed64e..082a36faa4f 100644
--- a/homeassistant/components/light/limitlessled.py
+++ b/homeassistant/components/light/limitlessled.py
@@ -33,32 +33,34 @@ from homeassistant.components.light import (Light, ATTR_BRIGHTNESS,
from homeassistant.util.color import color_RGB_to_xy
_LOGGER = logging.getLogger(__name__)
-REQUIREMENTS = ['ledcontroller==1.0.7']
+REQUIREMENTS = ['ledcontroller==1.1.0']
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Gets the LimitlessLED lights. """
import ledcontroller
- led = ledcontroller.LedController(config['host'])
+ pool = ledcontroller.LedControllerPool([config['host']])
lights = []
for i in range(1, 5):
if 'group_%d_name' % (i) in config:
- lights.append(LimitlessLED(led, i, config['group_%d_name' % (i)]))
+ lights.append(LimitlessLED(pool, 0, i, config['group_%d_name' % (i)]))
add_devices_callback(lights)
+# pylint: disable=too-many-instance-attributes
class LimitlessLED(Light):
""" Represents a LimitlessLED light """
- def __init__(self, led, group, name):
- self.led = led
+ def __init__(self, pool, controller_id, group, name):
+ self.pool = pool
+ self.controller_id = controller_id
self.group = group
# LimitlessLEDs don't report state, we have track it ourselves.
- self.led.off(self.group)
+ self.pool.execute(self.controller_id, "off", self.group)
self._name = name or DEVICE_DEFAULT_NAME
self._state = False
@@ -132,12 +134,14 @@ class LimitlessLED(Light):
if ATTR_XY_COLOR in kwargs:
self._xy_color = kwargs[ATTR_XY_COLOR]
- self.led.set_color(self._xy_to_led_color(self._xy_color), self.group)
- self.led.set_brightness(self._brightness / 255.0, self.group)
+ self.pool.execute(self.controller_id, "set_color",
+ self._xy_to_led_color(self._xy_color), self.group)
+ self.pool.execute(self.controller_id, "set_brightness",
+ self._brightness / 255.0, self.group)
self.update_ha_state()
def turn_off(self, **kwargs):
""" Turn the device off. """
self._state = False
- self.led.off(self.group)
+ self.pool.execute(self.controller_id, "off", self.group)
self.update_ha_state()
diff --git a/requirements_all.txt b/requirements_all.txt
index 4610100b161..5ff29e9d8a5 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -14,7 +14,7 @@ astral==0.8.1
phue==0.8
# Limitlessled/Easybulb/Milight library (lights.limitlessled)
-ledcontroller==1.0.7
+ledcontroller==1.1.0
# Chromecast bindings (media_player.cast)
pychromecast==0.6.12
From ab80af099c165af45d08b447074f89bcf2137a02 Mon Sep 17 00:00:00 2001
From: Michael Auchter
Date: Sun, 27 Sep 2015 16:46:08 -0500
Subject: [PATCH 3/5] limitlessled: Add support for multiple bridges
This adds support for a controlling multiple Limitless LED bridges.
---
.../components/light/limitlessled.py | 25 ++++++++++++-------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py
index 082a36faa4f..c77c1319724 100644
--- a/homeassistant/components/light/limitlessled.py
+++ b/homeassistant/components/light/limitlessled.py
@@ -19,11 +19,14 @@ configuration.yaml file.
light:
platform: limitlessled
- host: 192.168.1.10
- group_1_name: Living Room
- group_2_name: Bedroom
- group_3_name: Office
- group_4_name: Kitchen
+ bridges:
+ - host: 192.168.1.10
+ group_1_name: Living Room
+ group_2_name: Bedroom
+ group_3_name: Office
+ group_4_name: Kitchen
+ - host: 192.168.1.11
+ group_2_name: Basement
"""
import logging
@@ -40,12 +43,16 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Gets the LimitlessLED lights. """
import ledcontroller
- pool = ledcontroller.LedControllerPool([config['host']])
+ for bridge_id, bridge in enumerate(bridges):
+ bridge['id'] = bridge_id
+
+ pool = ledcontroller.LedControllerPool([x['host'] for x in bridges])
lights = []
- for i in range(1, 5):
- if 'group_%d_name' % (i) in config:
- lights.append(LimitlessLED(pool, 0, i, config['group_%d_name' % (i)]))
+ for bridge in bridges:
+ for i in range(1, 5):
+ if 'group_%d_name' % (i) in bridge:
+ lights.append(LimitlessLED(pool, bridge['id'], i, bridge['group_%d_name' % (i)]))
add_devices_callback(lights)
From ea7ca48ba2700dd2c12e85715ce6f3f8a2364987 Mon Sep 17 00:00:00 2001
From: Michael Auchter
Date: Sun, 27 Sep 2015 16:59:02 -0500
Subject: [PATCH 4/5] limitlessled: Add support for previous configuration
format
Quick hack that preserves functionality of existing configuration formats to
ease upgrades.
---
homeassistant/components/light/limitlessled.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py
index c77c1319724..e6045add119 100644
--- a/homeassistant/components/light/limitlessled.py
+++ b/homeassistant/components/light/limitlessled.py
@@ -43,6 +43,9 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Gets the LimitlessLED lights. """
import ledcontroller
+ # Handle old configuration format:
+ bridges = config.get('bridges', [config])
+
for bridge_id, bridge in enumerate(bridges):
bridge['id'] = bridge_id
From 52ebb2fb3bd22ff4b5c217b4ee9583a7a0461583 Mon Sep 17 00:00:00 2001
From: Michael Auchter
Date: Sun, 27 Sep 2015 17:22:38 -0500
Subject: [PATCH 5/5] limitlessled: Add support for White Limitless LED bulbs
LimitlessLED bulbs actually come in three flavors: RGB, RGBW, and White. The
ledcontroller library used to control these bulbs only supports RGBW and White
bulbs. This changelist adds support for the White bulb variant.
The White bulbs are a bit annoying in that they don't support absolute
brightness or color temperature adjustments; they only support a relative
"increase" or "decrease" adjustment. This, along with the unreliable, one-way
communication medium that requires repeats to be "sure" that the bulb received a
command, makes implementing brightness control difficult. So, for now, these
bulbs are more limited than the RGBW variants and only support On/Off control.
---
.../components/light/limitlessled.py | 83 ++++++++++++++-----
1 file changed, 60 insertions(+), 23 deletions(-)
diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py
index e6045add119..ba8b8235260 100644
--- a/homeassistant/components/light/limitlessled.py
+++ b/homeassistant/components/light/limitlessled.py
@@ -24,6 +24,7 @@ light:
group_1_name: Living Room
group_2_name: Bedroom
group_3_name: Office
+ group_3_type: white
group_4_name: Kitchen
- host: 192.168.1.11
group_2_name: Basement
@@ -54,26 +55,70 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
lights = []
for bridge in bridges:
for i in range(1, 5):
- if 'group_%d_name' % (i) in bridge:
- lights.append(LimitlessLED(pool, bridge['id'], i, bridge['group_%d_name' % (i)]))
+ name_key = 'group_%d_name' % i
+ if name_key in bridge:
+ group_type = bridge.get('group_%d_type' % i, 'rgbw')
+ lights.append(LimitlessLED.factory(pool, bridge['id'], i,
+ bridge[name_key],
+ group_type))
add_devices_callback(lights)
-# pylint: disable=too-many-instance-attributes
class LimitlessLED(Light):
""" Represents a LimitlessLED light """
- def __init__(self, pool, controller_id, group, name):
+ @staticmethod
+ def factory(pool, controller_id, group, name, group_type):
+ ''' Construct a Limitless LED of the appropriate type '''
+ if group_type == 'white':
+ return WhiteLimitlessLED(pool, controller_id, group, name)
+ elif group_type == 'rgbw':
+ return RGBWLimitlessLED(pool, controller_id, group, name)
+
+ # pylint: disable=too-many-arguments
+ def __init__(self, pool, controller_id, group, name, group_type):
self.pool = pool
self.controller_id = controller_id
self.group = group
+ self.pool.execute(self.controller_id, "set_group_type", self.group,
+ group_type)
+
# LimitlessLEDs don't report state, we have track it ourselves.
self.pool.execute(self.controller_id, "off", self.group)
self._name = name or DEVICE_DEFAULT_NAME
self._state = False
+
+ @property
+ def should_poll(self):
+ """ No polling needed. """
+ return False
+
+ @property
+ def name(self):
+ """ Returns the name of the device if any. """
+ return self._name
+
+ @property
+ def is_on(self):
+ """ True if device is on. """
+ return self._state
+
+ def turn_off(self, **kwargs):
+ """ Turn the device off. """
+ self._state = False
+ self.pool.execute(self.controller_id, "off", self.group)
+ self.update_ha_state()
+
+
+class RGBWLimitlessLED(LimitlessLED):
+ """ Represents a RGBW LimitlessLED light """
+
+ def __init__(self, pool, controller_id, group, name):
+ super().__init__(pool, controller_id, group, name, 'rgbw')
+
self._brightness = 100
self._xy_color = color_RGB_to_xy(255, 255, 255)
@@ -99,16 +144,6 @@ class LimitlessLED(Light):
((0xE6, 0xE6, 0xFA), 'lavendar'),
]]
- @property
- def should_poll(self):
- """ No polling needed. """
- return False
-
- @property
- def name(self):
- """ Returns the name of the device if any. """
- return self._name
-
@property
def brightness(self):
return self._brightness
@@ -129,11 +164,6 @@ class LimitlessLED(Light):
# First candidate in the sorted list is closest to desired color:
return sorted(candidates)[0][1]
- @property
- def is_on(self):
- """ True if device is on. """
- return self._state
-
def turn_on(self, **kwargs):
""" Turn the device on. """
self._state = True
@@ -150,8 +180,15 @@ class LimitlessLED(Light):
self._brightness / 255.0, self.group)
self.update_ha_state()
- def turn_off(self, **kwargs):
- """ Turn the device off. """
- self._state = False
- self.pool.execute(self.controller_id, "off", self.group)
+
+class WhiteLimitlessLED(LimitlessLED):
+ """ Represents a White LimitlessLED light """
+
+ def __init__(self, pool, controller_id, group, name):
+ super().__init__(pool, controller_id, group, name, 'white')
+
+ def turn_on(self, **kwargs):
+ """ Turn the device on. """
+ self._state = True
+ self.pool.execute(self.controller_id, "on", self.group)
self.update_ha_state()