mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
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:
parent
3f3518e29d
commit
6795627734
@ -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
|
||||||
|
@ -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={
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user