Add RGB light support to ozw (#37636)
This commit is contained in:
parent
93919dea88
commit
a6129467aa
10 changed files with 766 additions and 5 deletions
|
@ -194,6 +194,8 @@ DISCOVERY_SCHEMAS = (
|
|||
const.DISC_SPECIFIC_DEVICE_CLASS: (
|
||||
const_ozw.SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL,
|
||||
const_ozw.SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL,
|
||||
const_ozw.SPECIFIC_TYPE_COLOR_TUNABLE_BINARY,
|
||||
const_ozw.SPECIFIC_TYPE_COLOR_TUNABLE_MULTILEVEL,
|
||||
const_ozw.SPECIFIC_TYPE_NOT_USED,
|
||||
),
|
||||
const.DISC_VALUES: {
|
||||
|
|
|
@ -3,20 +3,37 @@ import logging
|
|||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_TEMP,
|
||||
ATTR_HS_COLOR,
|
||||
ATTR_TRANSITION,
|
||||
ATTR_WHITE_VALUE,
|
||||
DOMAIN as LIGHT_DOMAIN,
|
||||
SUPPORT_BRIGHTNESS,
|
||||
SUPPORT_COLOR,
|
||||
SUPPORT_COLOR_TEMP,
|
||||
SUPPORT_TRANSITION,
|
||||
SUPPORT_WHITE_VALUE,
|
||||
LightEntity,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
import homeassistant.util.color as color_util
|
||||
|
||||
from .const import DATA_UNSUBSCRIBE, DOMAIN
|
||||
from .entity import ZWaveDeviceEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_VALUE = "Value"
|
||||
COLOR_CHANNEL_WARM_WHITE = 0x01
|
||||
COLOR_CHANNEL_COLD_WHITE = 0x02
|
||||
COLOR_CHANNEL_RED = 0x04
|
||||
COLOR_CHANNEL_GREEN = 0x08
|
||||
COLOR_CHANNEL_BLUE = 0x10
|
||||
TEMP_COLOR_MAX = 500 # mireds (inverted)
|
||||
TEMP_COLOR_MIN = 154
|
||||
TEMP_COLOR_DIFF = TEMP_COLOR_MAX - TEMP_COLOR_MIN
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Light from Config Entry."""
|
||||
|
@ -24,7 +41,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
@callback
|
||||
def async_add_light(values):
|
||||
"""Add Z-Wave Light."""
|
||||
light = ZwaveDimmer(values)
|
||||
light = ZwaveLight(values)
|
||||
|
||||
async_add_entities([light])
|
||||
|
||||
hass.data[DOMAIN][config_entry.entry_id][DATA_UNSUBSCRIBE].append(
|
||||
|
@ -42,12 +60,16 @@ def byte_to_zwave_brightness(value):
|
|||
return 0
|
||||
|
||||
|
||||
class ZwaveDimmer(ZWaveDeviceEntity, LightEntity):
|
||||
"""Representation of a Z-Wave dimmer."""
|
||||
class ZwaveLight(ZWaveDeviceEntity, LightEntity):
|
||||
"""Representation of a Z-Wave light."""
|
||||
|
||||
def __init__(self, values):
|
||||
"""Initialize the light."""
|
||||
super().__init__(values)
|
||||
self._color_channels = None
|
||||
self._hs = None
|
||||
self._white = None
|
||||
self._ct = None
|
||||
self._supported_features = SUPPORT_BRIGHTNESS
|
||||
# make sure that supported features is correctly set
|
||||
self.on_value_update()
|
||||
|
@ -55,10 +77,29 @@ class ZwaveDimmer(ZWaveDeviceEntity, LightEntity):
|
|||
@callback
|
||||
def on_value_update(self):
|
||||
"""Call when the underlying value(s) is added or updated."""
|
||||
self._supported_features = SUPPORT_BRIGHTNESS
|
||||
if self.values.dimming_duration is not None:
|
||||
self._supported_features |= SUPPORT_TRANSITION
|
||||
|
||||
if self.values.color is None and self.values.color_channels is None:
|
||||
return
|
||||
|
||||
if self.values.color is not None:
|
||||
self._supported_features |= SUPPORT_COLOR
|
||||
|
||||
# Support Color Temp if both white channels
|
||||
if (self.values.color_channels.value & COLOR_CHANNEL_WARM_WHITE) and (
|
||||
self.values.color_channels.value & COLOR_CHANNEL_COLD_WHITE
|
||||
):
|
||||
self._supported_features |= SUPPORT_COLOR_TEMP
|
||||
|
||||
# Support White value if only a single white channel
|
||||
if ((self.values.color_channels.value & COLOR_CHANNEL_WARM_WHITE) != 0) ^ (
|
||||
(self.values.color_channels.value & COLOR_CHANNEL_COLD_WHITE) != 0
|
||||
):
|
||||
self._supported_features |= SUPPORT_WHITE_VALUE
|
||||
|
||||
self._calculate_rgb_values()
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255.
|
||||
|
@ -81,6 +122,21 @@ class ZwaveDimmer(ZWaveDeviceEntity, LightEntity):
|
|||
"""Flag supported features."""
|
||||
return self._supported_features
|
||||
|
||||
@property
|
||||
def hs_color(self):
|
||||
"""Return the hs color."""
|
||||
return self._hs
|
||||
|
||||
@property
|
||||
def white_value(self):
|
||||
"""Return the white value of this light between 0..255."""
|
||||
return self._white
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature."""
|
||||
return self._ct
|
||||
|
||||
@callback
|
||||
def async_set_duration(self, **kwargs):
|
||||
"""Set the transition time for the brightness value.
|
||||
|
@ -118,6 +174,34 @@ class ZwaveDimmer(ZWaveDeviceEntity, LightEntity):
|
|||
"""Turn the device on."""
|
||||
self.async_set_duration(**kwargs)
|
||||
|
||||
rgbw = None
|
||||
white = kwargs.get(ATTR_WHITE_VALUE)
|
||||
hs_color = kwargs.get(ATTR_HS_COLOR)
|
||||
color_temp = kwargs.get(ATTR_COLOR_TEMP)
|
||||
|
||||
if hs_color is not None:
|
||||
rgbw = "#"
|
||||
for colorval in color_util.color_hs_to_RGB(*hs_color):
|
||||
rgbw += f"{colorval:02x}"
|
||||
rgbw += "0000"
|
||||
# white LED must be off in order for color to work
|
||||
|
||||
elif white is not None:
|
||||
if self._color_channels & COLOR_CHANNEL_WARM_WHITE:
|
||||
rgbw = f"#000000{white:02x}00"
|
||||
else:
|
||||
rgbw = f"#00000000{white:02x}"
|
||||
|
||||
elif color_temp is not None:
|
||||
cold = round((TEMP_COLOR_MAX - round(color_temp)) / TEMP_COLOR_DIFF * 255)
|
||||
warm = 255 - cold
|
||||
if warm < 0:
|
||||
warm = 0
|
||||
rgbw = f"#000000{warm:02x}{cold:02x}"
|
||||
|
||||
if rgbw and self.values.color:
|
||||
self.values.color.send_value(rgbw)
|
||||
|
||||
# Zwave multilevel switches use a range of [0, 99] to control
|
||||
# brightness. Level 255 means to set it to previous value.
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
|
@ -133,3 +217,47 @@ class ZwaveDimmer(ZWaveDeviceEntity, LightEntity):
|
|||
self.async_set_duration(**kwargs)
|
||||
|
||||
self.values.primary.send_value(0)
|
||||
|
||||
def _calculate_rgb_values(self):
|
||||
# Color Channels
|
||||
self._color_channels = self.values.color_channels.data[ATTR_VALUE]
|
||||
|
||||
# Color Data String
|
||||
data = self.values.color.data[ATTR_VALUE]
|
||||
|
||||
# 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
|
||||
# that are present.
|
||||
index = 7
|
||||
temp_warm = 0
|
||||
temp_cold = 0
|
||||
|
||||
# Warm white
|
||||
if self._color_channels & COLOR_CHANNEL_WARM_WHITE:
|
||||
self._white = int(data[index : index + 2], 16)
|
||||
temp_warm = self._white
|
||||
|
||||
index += 2
|
||||
|
||||
# Cold white
|
||||
if self._color_channels & COLOR_CHANNEL_COLD_WHITE:
|
||||
self._white = int(data[index : index + 2], 16)
|
||||
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 no rgb channels supported, report None.
|
||||
if not (
|
||||
self._color_channels & COLOR_CHANNEL_RED
|
||||
or self._color_channels & COLOR_CHANNEL_GREEN
|
||||
or self._color_channels & COLOR_CHANNEL_BLUE
|
||||
):
|
||||
self._hs = None
|
||||
|
|
|
@ -27,6 +27,30 @@ def light_data_fixture():
|
|||
return load_fixture("ozw/light_network_dump.csv")
|
||||
|
||||
|
||||
@pytest.fixture(name="light_no_rgb_data", scope="session")
|
||||
def light_no_rgb_data_fixture():
|
||||
"""Load light dimmer MQTT data and return it."""
|
||||
return load_fixture("ozw/light_no_rgb_network_dump.csv")
|
||||
|
||||
|
||||
@pytest.fixture(name="light_no_ww_data", scope="session")
|
||||
def light_no_ww_data_fixture():
|
||||
"""Load light dimmer MQTT data and return it."""
|
||||
return load_fixture("ozw/light_no_ww_network_dump.csv")
|
||||
|
||||
|
||||
@pytest.fixture(name="light_no_cw_data", scope="session")
|
||||
def light_no_cw_data_fixture():
|
||||
"""Load light dimmer MQTT data and return it."""
|
||||
return load_fixture("ozw/light_no_cw_network_dump.csv")
|
||||
|
||||
|
||||
@pytest.fixture(name="light_wc_data", scope="session")
|
||||
def light_wc_only_data_fixture():
|
||||
"""Load light dimmer MQTT data and return it."""
|
||||
return load_fixture("ozw/light_wc_network_dump.csv")
|
||||
|
||||
|
||||
@pytest.fixture(name="cover_data", scope="session")
|
||||
def cover_data_fixture():
|
||||
"""Load cover MQTT data and return it."""
|
||||
|
@ -87,6 +111,28 @@ async def light_msg_fixture(hass):
|
|||
return message
|
||||
|
||||
|
||||
@pytest.fixture(name="light_no_rgb_msg")
|
||||
async def light_no_rgb_msg_fixture(hass):
|
||||
"""Return a mock MQTT msg with a light actuator message."""
|
||||
light_json = json.loads(
|
||||
await hass.async_add_executor_job(load_fixture, "ozw/light_no_rgb.json")
|
||||
)
|
||||
message = MQTTMessage(topic=light_json["topic"], payload=light_json["payload"])
|
||||
message.encode()
|
||||
return message
|
||||
|
||||
|
||||
@pytest.fixture(name="light_rgb_msg")
|
||||
async def light_rgb_msg_fixture(hass):
|
||||
"""Return a mock MQTT msg with a light actuator message."""
|
||||
light_json = json.loads(
|
||||
await hass.async_add_executor_job(load_fixture, "ozw/light_rgb.json")
|
||||
)
|
||||
message = MQTTMessage(topic=light_json["topic"], payload=light_json["payload"])
|
||||
message.encode()
|
||||
return message
|
||||
|
||||
|
||||
@pytest.fixture(name="switch_msg")
|
||||
async def switch_msg_fixture(hass):
|
||||
"""Return a mock MQTT msg with a switch actuator message."""
|
||||
|
|
|
@ -4,7 +4,7 @@ from homeassistant.components.ozw.light import byte_to_zwave_brightness
|
|||
from .common import setup_ozw
|
||||
|
||||
|
||||
async def test_light(hass, light_data, light_msg, sent_messages):
|
||||
async def test_light(hass, light_data, light_msg, light_rgb_msg, sent_messages):
|
||||
"""Test setting up config entry."""
|
||||
receive_message = await setup_ozw(hass, fixture=light_data)
|
||||
|
||||
|
@ -149,3 +149,335 @@ async def test_light(hass, light_data, light_msg, sent_messages):
|
|||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Test setting color_name
|
||||
new_color = "blue"
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "color_name": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 9
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#0000ff0000", "ValueIDKey": 659341335}
|
||||
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": 255, "ValueIDKey": 659128337}
|
||||
|
||||
# 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"] = "#0000ff0000"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["rgb_color"] == (0, 0, 255)
|
||||
|
||||
# Test setting hs_color
|
||||
new_color = [300, 70]
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "hs_color": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 11
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": 255, "ValueIDKey": 659128337}
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#ff4cff0000", "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"] = "#ff4cff0000"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["hs_color"] == (300.0, 70.196)
|
||||
|
||||
# Test setting rgb_color
|
||||
new_color = [255, 154, 0]
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "rgb_color": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 13
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": 255, "ValueIDKey": 659128337}
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#ff99000000", "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"] = "#ff99000000"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["rgb_color"] == (255, 153, 0)
|
||||
|
||||
# Test setting xy_color
|
||||
new_color = [0.52, 0.43]
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "xy_color": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 15
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": 255, "ValueIDKey": 659128337}
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#ffbb370000", "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"] = "#ffbb370000"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["xy_color"] == (0.519, 0.429)
|
||||
|
||||
# Test setting color temp
|
||||
new_color = 465
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "color_temp": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 17
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": 255, "ValueIDKey": 659128337}
|
||||
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#000000e51a", "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.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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
|
||||
|
||||
|
||||
async def test_no_rgb_light(hass, light_no_rgb_data, light_no_rgb_msg, sent_messages):
|
||||
"""Test setting up config entry."""
|
||||
receive_message = await setup_ozw(hass, fixture=light_no_rgb_data)
|
||||
|
||||
# Test loaded no RGBW support (dimmer only)
|
||||
state = hass.states.get("light.master_bedroom_l_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Turn on the light
|
||||
new_brightness = 44
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.master_bedroom_l_level", "brightness": new_brightness},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 1
|
||||
msg = sent_messages[-1]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {
|
||||
"Value": byte_to_zwave_brightness(new_brightness),
|
||||
"ValueIDKey": 38371345,
|
||||
}
|
||||
|
||||
# Feedback on state
|
||||
|
||||
light_no_rgb_msg.decode()
|
||||
light_no_rgb_msg.payload["Value"] = byte_to_zwave_brightness(new_brightness)
|
||||
light_no_rgb_msg.encode()
|
||||
receive_message(light_no_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.master_bedroom_l_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["brightness"] == new_brightness
|
||||
|
||||
|
||||
async def test_no_ww_light(
|
||||
hass, light_no_ww_data, light_msg, light_rgb_msg, sent_messages
|
||||
):
|
||||
"""Test setting up config entry."""
|
||||
receive_message = await setup_ozw(hass, fixture=light_no_ww_data)
|
||||
|
||||
# Test loaded no ww support
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Turn on the light
|
||||
white_color = 190
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "light.led_bulb_6_multi_colour_level",
|
||||
"white_value": white_color,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 2
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#00000000be", "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"] = "#00000000be"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["white_value"] == 190
|
||||
|
||||
|
||||
async def test_no_cw_light(
|
||||
hass, light_no_cw_data, light_msg, light_rgb_msg, sent_messages
|
||||
):
|
||||
"""Test setting up config entry."""
|
||||
receive_message = await setup_ozw(hass, fixture=light_no_cw_data)
|
||||
|
||||
# Test loaded no cw support
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Turn on the light
|
||||
white_color = 190
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "light.led_bulb_6_multi_colour_level",
|
||||
"white_value": white_color,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 2
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#000000be00", "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"] = "#000000be00"
|
||||
light_rgb_msg.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes["white_value"] == 190
|
||||
|
||||
|
||||
async def test_wc_light(hass, light_wc_data, light_msg, light_rgb_msg, sent_messages):
|
||||
"""Test setting up config entry."""
|
||||
receive_message = await setup_ozw(hass, fixture=light_wc_data)
|
||||
|
||||
# Test loaded only white LED support
|
||||
state = hass.states.get("light.led_bulb_6_multi_colour_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Turn on the light
|
||||
new_color = 190
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.led_bulb_6_multi_colour_level", "color_temp": new_color},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(sent_messages) == 2
|
||||
msg = sent_messages[-2]
|
||||
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
|
||||
assert msg["payload"] == {"Value": "#0000001be4", "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.encode()
|
||||
receive_message(light_msg)
|
||||
receive_message(light_rgb_msg)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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
|
||||
|
|
54
tests/fixtures/ozw/light_no_cw_network_dump.csv
vendored
Normal file
54
tests/fixtures/ozw/light_no_cw_network_dump.csv
vendored
Normal file
File diff suppressed because one or more lines are too long
25
tests/fixtures/ozw/light_no_rgb.json
vendored
Normal file
25
tests/fixtures/ozw/light_no_rgb.json
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"topic": "OpenZWave/1/node/2/instance/1/commandclass/38/value/38371345/",
|
||||
"payload": {
|
||||
"Label": "Level",
|
||||
"Value": 0,
|
||||
"Units": "",
|
||||
"Min": 0,
|
||||
"Max": 255,
|
||||
"Type": "Byte",
|
||||
"Instance": 1,
|
||||
"CommandClass": "COMMAND_CLASS_SWITCH_MULTILEVEL",
|
||||
"Index": 0,
|
||||
"Node": 2,
|
||||
"Genre": "User",
|
||||
"Help": "The Current Level of the Device",
|
||||
"ValueIDKey": 38371345,
|
||||
"ReadOnly": false,
|
||||
"WriteOnly": false,
|
||||
"ValueSet": false,
|
||||
"ValuePolled": false,
|
||||
"ChangeVerified": false,
|
||||
"Event": "valueAdded",
|
||||
"TimeStamp": 1579566891
|
||||
}
|
||||
}
|
41
tests/fixtures/ozw/light_no_rgb_network_dump.csv
vendored
Normal file
41
tests/fixtures/ozw/light_no_rgb_network_dump.csv
vendored
Normal file
File diff suppressed because one or more lines are too long
54
tests/fixtures/ozw/light_no_ww_network_dump.csv
vendored
Normal file
54
tests/fixtures/ozw/light_no_ww_network_dump.csv
vendored
Normal file
File diff suppressed because one or more lines are too long
25
tests/fixtures/ozw/light_rgb.json
vendored
Normal file
25
tests/fixtures/ozw/light_rgb.json
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"topic": "OpenZWave/1/node/39/instance/1/commandclass/51/value/659341335/",
|
||||
"payload": {
|
||||
"Label": "Color",
|
||||
"Value": "#000000FF00",
|
||||
"Units": "#RRGGBBWWCW",
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Type": "String",
|
||||
"Instance": 1,
|
||||
"CommandClass": "COMMAND_CLASS_COLOR",
|
||||
"Index": 0,
|
||||
"Node": 39,
|
||||
"Genre": "User",
|
||||
"Help": "Color (in RGB format)",
|
||||
"ValueIDKey": 659341335,
|
||||
"ReadOnly": false,
|
||||
"WriteOnly": false,
|
||||
"ValueSet": false,
|
||||
"ValuePolled": false,
|
||||
"ChangeVerified": false,
|
||||
"Event": "valueAdded",
|
||||
"TimeStamp": 1579566891
|
||||
}
|
||||
}
|
54
tests/fixtures/ozw/light_wc_network_dump.csv
vendored
Normal file
54
tests/fixtures/ozw/light_wc_network_dump.csv
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue