mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Make ozw CCT use device attributes instead of hard coded values (#38054)
This commit is contained in:
parent
86fc977ff5
commit
0780650015
@ -114,7 +114,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
|
||||
# Filter out CommandClasses we're definitely not interested in.
|
||||
if value.command_class in [
|
||||
CommandClass.CONFIGURATION,
|
||||
CommandClass.VERSION,
|
||||
CommandClass.MANUFACTURER_SPECIFIC,
|
||||
]:
|
||||
|
@ -250,6 +250,16 @@ DISCOVERY_SCHEMAS = (
|
||||
const.DISC_INDEX: ValueIndex.SWITCH_COLOR_CHANNELS,
|
||||
const.DISC_OPTIONAL: True,
|
||||
},
|
||||
"min_kelvin": {
|
||||
const.DISC_COMMAND_CLASS: (CommandClass.CONFIGURATION,),
|
||||
const.DISC_INDEX: 81, # PR for upstream to add SWITCH_COLOR_CT_WARM
|
||||
const.DISC_OPTIONAL: True,
|
||||
},
|
||||
"max_kelvin": {
|
||||
const.DISC_COMMAND_CLASS: (CommandClass.CONFIGURATION,),
|
||||
const.DISC_INDEX: 82, # PR for upstream to add SWITCH_COLOR_CT_COLD
|
||||
const.DISC_OPTIONAL: True,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ # All other text/numeric sensors
|
||||
|
@ -30,9 +30,6 @@ COLOR_CHANNEL_COLD_WHITE = 0x02
|
||||
COLOR_CHANNEL_RED = 0x04
|
||||
COLOR_CHANNEL_GREEN = 0x08
|
||||
COLOR_CHANNEL_BLUE = 0x10
|
||||
TEMP_COLOR_MAX = 500 # mired equivalent to 2000K
|
||||
TEMP_COLOR_MIN = 154 # mired equivalent to 6500K
|
||||
TEMP_COLOR_DIFF = TEMP_COLOR_MAX - TEMP_COLOR_MIN
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
@ -71,6 +68,9 @@ class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
self._white = None
|
||||
self._ct = None
|
||||
self._supported_features = SUPPORT_BRIGHTNESS
|
||||
self._min_mireds = 153 # 6500K as a safe default
|
||||
self._max_mireds = 370 # 2700K as a safe default
|
||||
|
||||
# make sure that supported features is correctly set
|
||||
self.on_value_update()
|
||||
|
||||
@ -136,6 +136,16 @@ class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
"""Return the color temperature."""
|
||||
return self._ct
|
||||
|
||||
@property
|
||||
def min_mireds(self):
|
||||
"""Return the coldest color_temp that this light supports."""
|
||||
return self._min_mireds
|
||||
|
||||
@property
|
||||
def max_mireds(self):
|
||||
"""Return the warmest color_temp that this light supports."""
|
||||
return self._max_mireds
|
||||
|
||||
@callback
|
||||
def async_set_duration(self, **kwargs):
|
||||
"""Set the transition time for the brightness value.
|
||||
@ -209,7 +219,11 @@ class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
0,
|
||||
min(
|
||||
255,
|
||||
round((TEMP_COLOR_MAX - round(color_temp)) / TEMP_COLOR_DIFF * 255),
|
||||
round(
|
||||
(self._max_mireds - color_temp)
|
||||
/ (self._max_mireds - self._min_mireds)
|
||||
* 255
|
||||
),
|
||||
),
|
||||
)
|
||||
warm = 255 - cold
|
||||
@ -241,16 +255,26 @@ class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
# Color Data String
|
||||
data = self.values.color.data[ATTR_VALUE]
|
||||
|
||||
# RGB is always present in the openzwave color data string.
|
||||
# RGB is always present in the OpenZWave color data string.
|
||||
rgb = [int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)]
|
||||
self._hs = color_util.color_RGB_to_hs(*rgb)
|
||||
|
||||
# Parse remaining color channels. Openzwave appends white channels
|
||||
# Parse remaining color channels. OpenZWave appends white channels
|
||||
# that are present.
|
||||
index = 7
|
||||
temp_warm = 0
|
||||
temp_cold = 0
|
||||
|
||||
# Update color temp limits.
|
||||
if self.values.min_kelvin:
|
||||
self._max_mireds = color_util.color_temperature_kelvin_to_mired(
|
||||
self.values.min_kelvin.data[ATTR_VALUE]
|
||||
)
|
||||
if self.values.max_kelvin:
|
||||
self._min_mireds = color_util.color_temperature_kelvin_to_mired(
|
||||
self.values.max_kelvin.data[ATTR_VALUE]
|
||||
)
|
||||
|
||||
# Warm white
|
||||
if self._color_channels & COLOR_CHANNEL_WARM_WHITE:
|
||||
self._white = int(data[index : index + 2], 16)
|
||||
@ -264,13 +288,12 @@ class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
temp_cold = self._white
|
||||
|
||||
# Calculate color temps based on white LED status
|
||||
if temp_cold > 0:
|
||||
self._ct = round(TEMP_COLOR_MAX - ((temp_cold / 255) * TEMP_COLOR_DIFF))
|
||||
# Only used if CW channel missing
|
||||
elif temp_warm > 0:
|
||||
self._ct = round(TEMP_COLOR_MAX - temp_warm)
|
||||
if temp_cold or temp_warm:
|
||||
self._ct = round(
|
||||
self._max_mireds
|
||||
- ((temp_cold / 255) * (self._max_mireds - self._min_mireds))
|
||||
)
|
||||
|
||||
# If no rgb channels supported, report None.
|
||||
if not (
|
||||
self._color_channels & COLOR_CHANNEL_RED
|
||||
or self._color_channels & COLOR_CHANNEL_GREEN
|
||||
|
@ -284,7 +284,7 @@ async def test_light(hass, light_data, light_msg, light_rgb_msg, sent_messages):
|
||||
assert state.attributes["xy_color"] == (0.519, 0.429)
|
||||
|
||||
# Test setting color temp
|
||||
new_color = 465
|
||||
new_color = 200
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
@ -298,14 +298,14 @@ async def test_light(hass, light_data, light_msg, light_rgb_msg, sent_messages):
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#000000e51a", "ValueIDKey": 659341335}
|
||||
assert msg["payload"] == {"Value": "#00000037c8", "ValueIDKey": 659341335}
|
||||
|
||||
# Feedback on state
|
||||
light_msg.decode()
|
||||
light_msg.payload["Value"] = byte_to_zwave_brightness(255)
|
||||
light_msg.encode()
|
||||
light_rgb_msg.decode()
|
||||
light_rgb_msg.payload["Value"] = "#000000e51a"
|
||||
light_rgb_msg.payload["Value"] = "#00000037c8"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
@ -314,7 +314,7 @@ async def test_light(hass, light_data, light_msg, light_rgb_msg, sent_messages):
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["color_temp"] == 465
|
||||
assert state.attributes["color_temp"] == 200
|
||||
|
||||
# Test setting invalid color temp
|
||||
new_color = 120
|
||||
@ -347,7 +347,7 @@ async def test_light(hass, light_data, light_msg, light_rgb_msg, sent_messages):
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["color_temp"] == 154
|
||||
assert state.attributes["color_temp"] == 153
|
||||
|
||||
|
||||
async def test_no_rgb_light(hass, light_no_rgb_data, light_no_rgb_msg, sent_messages):
|
||||
@ -486,6 +486,9 @@ async def test_wc_light(hass, light_wc_data, light_msg, light_rgb_msg, sent_mess
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
assert state.attributes["min_mireds"] == 153
|
||||
assert state.attributes["max_mireds"] == 370
|
||||
|
||||
# Turn on the light
|
||||
new_color = 190
|
||||
await hass.services.async_call(
|
||||
@ -497,14 +500,14 @@ async def test_wc_light(hass, light_wc_data, light_msg, light_rgb_msg, sent_mess
|
||||
assert len(sent_messages) == 2
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#0000001be4", "ValueIDKey": 659341335}
|
||||
assert msg["payload"] == {"Value": "#0000002bd4", "ValueIDKey": 659341335}
|
||||
|
||||
# Feedback on state
|
||||
light_msg.decode()
|
||||
light_msg.payload["Value"] = byte_to_zwave_brightness(255)
|
||||
light_msg.encode()
|
||||
light_rgb_msg.decode()
|
||||
light_rgb_msg.payload["Value"] = "#0000001be4"
|
||||
light_rgb_msg.payload["Value"] = "#0000002bd4"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
@ -513,7 +516,7 @@ async def test_wc_light(hass, light_wc_data, light_msg, light_rgb_msg, sent_mess
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["color_temp"] == 191
|
||||
assert state.attributes["color_temp"] == 190
|
||||
|
||||
|
||||
async def test_new_ozw_light(hass, light_new_ozw_data, light_msg, sent_messages):
|
||||
|
Loading…
x
Reference in New Issue
Block a user