Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 35 additions & 21 deletions homeassistant/components/light/zha.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@

DEFAULT_DURATION = 0.5

CAPABILITIES_COLOR_XY = 0x08
CAPABILITIES_COLOR_TEMP = 0x10

UNSUPPORTED_ATTRIBUTE = 0x86


@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
Expand All @@ -32,9 +37,36 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
except (AttributeError, KeyError):
pass

if discovery_info.get('color_capabilities') is None:
# ZCL Version 4 devices don't support the color_capabilities attribute.
# In this version XY support is mandatory, but we need to probe to
# determine if the device supports color temperature.
discovery_info['color_capabilities'] = CAPABILITIES_COLOR_XY
result = yield from safe_read(
endpoint.light_color, ['color_temperature'])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks any lights which do not have a light_color attribute. I'm putting a fix together now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah damn. My mistake.

Probably what we should do is move most of this logic out of the constructor and into setup. Then this could be properly nested under the color cluster logic:

https://github.com/home-assistant/home-assistant/blob/079d4039a10b819a0378580f7cb749959fe8ed43/homeassistant/components/light/zha.py#L83-L96

if result.get('color_temperature') is not UNSUPPORTED_ATTRIBUTE:
discovery_info['color_capabilities'] |= CAPABILITIES_COLOR_TEMP

async_add_devices([Light(**discovery_info)], update_before_add=True)


@asyncio.coroutine
def safe_read(cluster, attributes):
"""Swallow all exceptions from network read.

If we throw during initialization, setup fails. Rather have an
entity that exists, but is in a maybe wrong state, than no entity.
"""
try:
result, _ = yield from cluster.read_attributes(
attributes,
allow_cache=False,
)
return result
except Exception: # pylint: disable=broad-except
return {}


class Light(zha.Entity, light.Light):
"""Representation of a ZHA or ZLL light."""

Expand All @@ -54,11 +86,11 @@ def __init__(self, **kwargs):
self._supported_features |= light.SUPPORT_TRANSITION
self._brightness = 0
if zcl_clusters.lighting.Color.cluster_id in self._in_clusters:
color_capabilities = kwargs.get('color_capabilities', 0x10)
if color_capabilities & 0x10:
color_capabilities = kwargs['color_capabilities']
if color_capabilities & CAPABILITIES_COLOR_TEMP:
self._supported_features |= light.SUPPORT_COLOR_TEMP

if color_capabilities & 0x08:
if color_capabilities & CAPABILITIES_COLOR_XY:
self._supported_features |= light.SUPPORT_XY_COLOR
self._supported_features |= light.SUPPORT_RGB_COLOR
self._xy_color = (1.0, 1.0)
Expand Down Expand Up @@ -142,24 +174,6 @@ def supported_features(self):
@asyncio.coroutine
def async_update(self):
"""Retrieve latest state."""
_LOGGER.debug("%s async_update", self.entity_id)

@asyncio.coroutine
def safe_read(cluster, attributes):
"""Swallow all exceptions from network read.

If we throw during initialization, setup fails. Rather have an
entity that exists, but is in a maybe wrong state, than no entity.
"""
try:
result, _ = yield from cluster.read_attributes(
attributes,
allow_cache=False,
)
return result
except Exception: # pylint: disable=broad-except
return {}

result = yield from safe_read(self._endpoint.on_off, ['on_off'])
self._state = result.get('on_off', self._state)

Expand Down