Add ZHA StartUpColorTemperature configuration entity (#80853)

* Add ZHA start up color temperature entity

* Use device reported min max values

* Add color number test

* Fix code style
This commit is contained in:
Julian Löhr 2022-10-24 00:46:47 +02:00 committed by GitHub
parent 3f3518e29d
commit 6795627734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 140 additions and 1 deletions

View File

@ -44,6 +44,7 @@ class ColorChannel(ZigbeeChannel):
"color_temp_physical_max": True, "color_temp_physical_max": True,
"color_capabilities": True, "color_capabilities": True,
"color_loop_active": False, "color_loop_active": False,
"start_up_color_temperature": True,
} }
@cached_property @cached_property

View File

@ -19,6 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .core import discovery from .core import discovery
from .core.const import ( from .core.const import (
CHANNEL_ANALOG_OUTPUT, CHANNEL_ANALOG_OUTPUT,
CHANNEL_COLOR,
CHANNEL_INOVELLI, CHANNEL_INOVELLI,
CHANNEL_LEVEL, CHANNEL_LEVEL,
DATA_ZHA, DATA_ZHA,
@ -528,6 +529,31 @@ class StartUpCurrentLevelConfigurationEntity(
_attr_name = "Start-up current level" _attr_name = "Start-up current level"
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_COLOR)
class StartUpColorTemperatureConfigurationEntity(
ZHANumberConfigurationEntity, id_suffix="start_up_color_temperature"
):
"""Representation of a ZHA startup color temperature configuration entity."""
_attr_native_min_value: float = 153
_attr_native_max_value: float = 500
_zcl_attribute: str = "start_up_color_temperature"
_attr_name = "Start-up color temperature"
def __init__(
self,
unique_id: str,
zha_device: ZHADevice,
channels: list[ZigbeeChannel],
**kwargs: Any,
) -> None:
"""Init this ZHA startup color temperature entity."""
super().__init__(unique_id, zha_device, channels, **kwargs)
if self._channel:
self._attr_native_min_value: float = self._channel.min_mireds
self._attr_native_max_value: float = self._channel.max_mireds
@CONFIG_DIAGNOSTIC_MATCH( @CONFIG_DIAGNOSTIC_MATCH(
channel_names="tuya_manufacturer", channel_names="tuya_manufacturer",
manufacturers={ manufacturers={

View File

@ -5,6 +5,7 @@ import pytest
from zigpy.exceptions import ZigbeeException from zigpy.exceptions import ZigbeeException
from zigpy.profiles import zha from zigpy.profiles import zha
import zigpy.zcl.clusters.general as general import zigpy.zcl.clusters.general as general
import zigpy.zcl.clusters.lighting as lighting
import zigpy.zcl.foundation as zcl_f import zigpy.zcl.foundation as zcl_f
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN
@ -64,12 +65,13 @@ async def light(zigpy_device_mock):
{ {
1: { 1: {
SIG_EP_PROFILE: zha.PROFILE_ID, SIG_EP_PROFILE: zha.PROFILE_ID,
SIG_EP_TYPE: zha.DeviceType.ON_OFF_LIGHT, SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
SIG_EP_INPUT: [ SIG_EP_INPUT: [
general.Basic.cluster_id, general.Basic.cluster_id,
general.Identify.cluster_id, general.Identify.cluster_id,
general.OnOff.cluster_id, general.OnOff.cluster_id,
general.LevelControl.cluster_id, general.LevelControl.cluster_id,
lighting.Color.cluster_id,
], ],
SIG_EP_OUTPUT: [general.Ota.cluster_id], SIG_EP_OUTPUT: [general.Ota.cluster_id],
} }
@ -322,3 +324,113 @@ async def test_level_control_number(
attr: new_value, attr: new_value,
} }
assert hass.states.get(entity_id).state == str(initial_value) assert hass.states.get(entity_id).state == str(initial_value)
@pytest.mark.parametrize(
"attr, initial_value, new_value",
(("start_up_color_temperature", 500, 350),),
)
async def test_color_number(
hass, light, zha_device_joined, attr, initial_value, new_value
):
"""Test zha color number entities - new join."""
entity_registry = er.async_get(hass)
color_cluster = light.endpoints[1].light_color
color_cluster.PLUGGED_ATTR_READS = {
attr: initial_value,
}
zha_device = await zha_device_joined(light)
entity_id = await find_entity_id(
Platform.NUMBER,
zha_device,
hass,
qualifier=attr,
)
assert entity_id is not None
assert color_cluster.read_attributes.call_count == 3
assert (
call(
[
"color_temp_physical_min",
"color_temp_physical_max",
"color_capabilities",
"start_up_color_temperature",
],
allow_cache=True,
only_cache=False,
manufacturer=None,
)
in color_cluster.read_attributes.call_args_list
)
state = hass.states.get(entity_id)
assert state
assert state.state == str(initial_value)
entity_entry = entity_registry.async_get(entity_id)
assert entity_entry
assert entity_entry.entity_category == EntityCategory.CONFIG
# Test number set_value
await hass.services.async_call(
"number",
"set_value",
{
"entity_id": entity_id,
"value": new_value,
},
blocking=True,
)
assert color_cluster.write_attributes.call_count == 1
assert color_cluster.write_attributes.call_args[0][0] == {
attr: new_value,
}
state = hass.states.get(entity_id)
assert state
assert state.state == str(new_value)
color_cluster.read_attributes.reset_mock()
await async_setup_component(hass, "homeassistant", {})
await hass.async_block_till_done()
await hass.services.async_call(
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
)
# the mocking doesn't update the attr cache so this flips back to initial value
assert hass.states.get(entity_id).state == str(initial_value)
assert color_cluster.read_attributes.call_count == 1
assert (
call(
[
attr,
],
allow_cache=False,
only_cache=False,
manufacturer=None,
)
in color_cluster.read_attributes.call_args_list
)
color_cluster.write_attributes.reset_mock()
color_cluster.write_attributes.side_effect = ZigbeeException
await hass.services.async_call(
"number",
"set_value",
{
"entity_id": entity_id,
"value": new_value,
},
blocking=True,
)
assert color_cluster.write_attributes.call_count == 1
assert color_cluster.write_attributes.call_args[0][0] == {
attr: new_value,
}
assert hass.states.get(entity_id).state == str(initial_value)