mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Refactor ZHA light state restoration after a restart (#42726)
* Restore ZHA light state and level * Restore state and color temp from zigpy cache
This commit is contained in:
parent
3f12648212
commit
9ccc49411a
@ -167,6 +167,11 @@ class LevelControlChannel(ZigbeeChannel):
|
|||||||
CURRENT_LEVEL = 0
|
CURRENT_LEVEL = 0
|
||||||
REPORT_CONFIG = ({"attr": "current_level", "config": REPORT_CONFIG_ASAP},)
|
REPORT_CONFIG = ({"attr": "current_level", "config": REPORT_CONFIG_ASAP},)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_level(self) -> Optional[int]:
|
||||||
|
"""Return cached value of the current_level attribute."""
|
||||||
|
return self.cluster.get("current_level")
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def cluster_command(self, tsn, command_id, args):
|
def cluster_command(self, tsn, command_id, args):
|
||||||
"""Handle commands received to this cluster."""
|
"""Handle commands received to this cluster."""
|
||||||
@ -248,6 +253,11 @@ class OnOffChannel(ZigbeeChannel):
|
|||||||
self._state = None
|
self._state = None
|
||||||
self._off_listener = None
|
self._off_listener = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def on_off(self) -> Optional[bool]:
|
||||||
|
"""Return cached value of on/off attribute."""
|
||||||
|
return self.cluster.get("on_off")
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def cluster_command(self, tsn, command_id, args):
|
def cluster_command(self, tsn, command_id, args):
|
||||||
"""Handle commands received to this cluster."""
|
"""Handle commands received to this cluster."""
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Lighting channels module for Zigbee Home Automation."""
|
"""Lighting channels module for Zigbee Home Automation."""
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import zigpy.zcl.clusters.lighting as lighting
|
import zigpy.zcl.clusters.lighting as lighting
|
||||||
|
|
||||||
from .. import registries, typing as zha_typing
|
from .. import registries, typing as zha_typing
|
||||||
@ -41,14 +43,34 @@ class ColorChannel(ZigbeeChannel):
|
|||||||
self._max_mireds = 500
|
self._max_mireds = 500
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_mireds(self):
|
def color_loop_active(self) -> Optional[int]:
|
||||||
"""Return the coldest color_temp that this channel supports."""
|
"""Return cached value of the color_loop_active attribute."""
|
||||||
return self._min_mireds
|
return self.cluster.get("color_loop_active")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max_mireds(self):
|
def color_temperature(self) -> Optional[int]:
|
||||||
|
"""Return cached value of color temperature."""
|
||||||
|
return self.cluster.get("color_temperature")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_x(self) -> Optional[int]:
|
||||||
|
"""Return cached value of the current_x attribute."""
|
||||||
|
return self.cluster.get("current_x")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_y(self) -> Optional[int]:
|
||||||
|
"""Return cached value of the current_y attribute."""
|
||||||
|
return self.cluster.get("current_y")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_mireds(self) -> int:
|
||||||
|
"""Return the coldest color_temp that this channel supports."""
|
||||||
|
return self.cluster.get("color_temp_physical_min", self._min_mireds)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_mireds(self) -> int:
|
||||||
"""Return the warmest color_temp that this channel supports."""
|
"""Return the warmest color_temp that this channel supports."""
|
||||||
return self._max_mireds
|
return self.cluster.get("color_temp_physical_max", self._max_mireds)
|
||||||
|
|
||||||
def get_color_capabilities(self):
|
def get_color_capabilities(self):
|
||||||
"""Return the color capabilities."""
|
"""Return the color capabilities."""
|
||||||
@ -74,8 +96,6 @@ class ColorChannel(ZigbeeChannel):
|
|||||||
]
|
]
|
||||||
results = await self.get_attributes(attributes, from_cache=from_cache)
|
results = await self.get_attributes(attributes, from_cache=from_cache)
|
||||||
capabilities = results.get("color_capabilities")
|
capabilities = results.get("color_capabilities")
|
||||||
self._min_mireds = results.get("color_temp_physical_min", 153)
|
|
||||||
self._max_mireds = results.get("color_temp_physical_max", 500)
|
|
||||||
|
|
||||||
if capabilities is None:
|
if capabilities is None:
|
||||||
# ZCL Version 4 devices don't support the color_capabilities
|
# ZCL Version 4 devices don't support the color_capabilities
|
||||||
|
@ -328,6 +328,7 @@ class Light(BaseLight, ZhaEntity):
|
|||||||
"""Initialize the ZHA light."""
|
"""Initialize the ZHA light."""
|
||||||
super().__init__(unique_id, zha_device, channels, **kwargs)
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
||||||
self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
|
self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
|
||||||
|
self._state = bool(self._on_off_channel.on_off)
|
||||||
self._level_channel = self.cluster_channels.get(CHANNEL_LEVEL)
|
self._level_channel = self.cluster_channels.get(CHANNEL_LEVEL)
|
||||||
self._color_channel = self.cluster_channels.get(CHANNEL_COLOR)
|
self._color_channel = self.cluster_channels.get(CHANNEL_COLOR)
|
||||||
self._identify_channel = self.zha_device.channels.identify_ch
|
self._identify_channel = self.zha_device.channels.identify_ch
|
||||||
@ -340,20 +341,30 @@ class Light(BaseLight, ZhaEntity):
|
|||||||
if self._level_channel:
|
if self._level_channel:
|
||||||
self._supported_features |= light.SUPPORT_BRIGHTNESS
|
self._supported_features |= light.SUPPORT_BRIGHTNESS
|
||||||
self._supported_features |= light.SUPPORT_TRANSITION
|
self._supported_features |= light.SUPPORT_TRANSITION
|
||||||
self._brightness = 0
|
self._brightness = self._level_channel.current_level
|
||||||
|
|
||||||
if self._color_channel:
|
if self._color_channel:
|
||||||
color_capabilities = self._color_channel.get_color_capabilities()
|
color_capabilities = self._color_channel.get_color_capabilities()
|
||||||
if color_capabilities & CAPABILITIES_COLOR_TEMP:
|
if color_capabilities & CAPABILITIES_COLOR_TEMP:
|
||||||
self._supported_features |= light.SUPPORT_COLOR_TEMP
|
self._supported_features |= light.SUPPORT_COLOR_TEMP
|
||||||
|
self._color_temp = self._color_channel.color_temperature
|
||||||
|
|
||||||
if color_capabilities & CAPABILITIES_COLOR_XY:
|
if color_capabilities & CAPABILITIES_COLOR_XY:
|
||||||
self._supported_features |= light.SUPPORT_COLOR
|
self._supported_features |= light.SUPPORT_COLOR
|
||||||
|
curr_x = self._color_channel.current_x
|
||||||
|
curr_y = self._color_channel.current_y
|
||||||
|
if curr_x is not None and curr_y is not None:
|
||||||
|
self._hs_color = color_util.color_xy_to_hs(
|
||||||
|
float(curr_x / 65535), float(curr_y / 65535)
|
||||||
|
)
|
||||||
|
else:
|
||||||
self._hs_color = (0, 0)
|
self._hs_color = (0, 0)
|
||||||
|
|
||||||
if color_capabilities & CAPABILITIES_COLOR_LOOP:
|
if color_capabilities & CAPABILITIES_COLOR_LOOP:
|
||||||
self._supported_features |= light.SUPPORT_EFFECT
|
self._supported_features |= light.SUPPORT_EFFECT
|
||||||
effect_list.append(light.EFFECT_COLORLOOP)
|
effect_list.append(light.EFFECT_COLORLOOP)
|
||||||
|
if self._color_channel.color_loop_active == 1:
|
||||||
|
self._effect = light.EFFECT_COLORLOOP
|
||||||
|
|
||||||
if self._identify_channel:
|
if self._identify_channel:
|
||||||
self._supported_features |= light.SUPPORT_FLASH
|
self._supported_features |= light.SUPPORT_FLASH
|
||||||
|
Loading…
x
Reference in New Issue
Block a user