"""Test Z-Wave lights.""" from unittest.mock import patch, MagicMock import homeassistant.components.zwave from homeassistant.components.zwave import const from homeassistant.components.light import ( zwave, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_RGB_COLOR) from tests.mock.zwave import ( MockNode, MockValue, MockEntityValues, value_changed) class MockLightValues(MockEntityValues): """Mock Z-Wave light values.""" def __init__(self, **kwargs): """Initialize the mock zwave values.""" self.color = None self.color_channels = None super().__init__(**kwargs) def test_get_device_detects_dimmer(mock_openzwave): """Test get_device returns a color light.""" node = MockNode() value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveDimmer) assert device.supported_features == zwave.SUPPORT_ZWAVE_DIMMER def test_get_device_detects_colorlight(mock_openzwave): """Test get_device returns a color light.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveColorLight) assert device.supported_features == zwave.SUPPORT_ZWAVE_COLOR def test_get_device_detects_zw098(mock_openzwave): """Test get_device returns a zw098 color light.""" node = MockNode(manufacturer_id='0086', product_id='0062', command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert isinstance(device, zwave.ZwaveColorLight) assert device.supported_features == zwave.SUPPORT_ZWAVE_COLORTEMP def test_dimmer_turn_on(mock_openzwave): """Test turning on a dimmable Z-Wave light.""" node = MockNode() value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) device.turn_on() assert node.set_dimmer.called value_id, brightness = node.set_dimmer.mock_calls[0][1] assert value_id == value.value_id assert brightness == 255 node.reset_mock() device.turn_on(**{ATTR_BRIGHTNESS: 120}) assert node.set_dimmer.called value_id, brightness = node.set_dimmer.mock_calls[0][1] assert value_id == value.value_id assert brightness == 46 # int(120 / 255 * 99) def test_dimmer_turn_off(mock_openzwave): """Test turning off a dimmable Z-Wave light.""" node = MockNode() value = MockValue(data=46, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) device.turn_off() assert node.set_dimmer.called value_id, brightness = node.set_dimmer.mock_calls[0][1] assert value_id == value.value_id assert brightness == 0 def test_dimmer_value_changed(mock_openzwave): """Test value changed for dimmer lights.""" node = MockNode() value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert not device.is_on value.data = 46 value_changed(value) assert device.is_on assert device.brightness == 118 def test_dimmer_refresh_value(mock_openzwave): """Test value changed for dimmer lights.""" node = MockNode() value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={ homeassistant.components.zwave.CONF_REFRESH_VALUE: True, homeassistant.components.zwave.CONF_REFRESH_DELAY: 5, }) assert not device.is_on with patch.object(zwave, 'Timer', MagicMock()) as mock_timer: value.data = 46 value_changed(value) assert not device.is_on assert mock_timer.called assert len(mock_timer.mock_calls) == 2 timeout, callback = mock_timer.mock_calls[0][1][:2] assert timeout == 5 assert mock_timer().start.called assert len(mock_timer().start.mock_calls) == 1 with patch.object(zwave, 'Timer', MagicMock()) as mock_timer_2: value_changed(value) assert not device.is_on assert mock_timer().cancel.called assert len(mock_timer_2.mock_calls) == 2 timeout, callback = mock_timer_2.mock_calls[0][1][:2] assert timeout == 5 assert mock_timer_2().start.called assert len(mock_timer_2().start.mock_calls) == 1 callback() assert device.is_on assert device.brightness == 118 def test_set_rgb_color(mock_openzwave): """Test setting zwave light color.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB only color_channels = MockValue(data=0x1c, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert color.data == b'#0000000000' device.turn_on(**{ATTR_RGB_COLOR: (200, 150, 100)}) assert color.data == b'#c896640000' def test_set_rgbw_color(mock_openzwave): """Test setting zwave light color.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGBW color_channels = MockValue(data=0x1d, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert color.data == b'#0000000000' device.turn_on(**{ATTR_RGB_COLOR: (200, 150, 100)}) assert color.data == b'#c86400c800' def test_zw098_set_color_temp(mock_openzwave): """Test setting zwave light color.""" node = MockNode(manufacturer_id='0086', product_id='0062', command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB, warm white, cold white color_channels = MockValue(data=0x1f, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert color.data == b'#0000000000' device.turn_on(**{ATTR_COLOR_TEMP: 200}) assert color.data == b'#00000000ff' device.turn_on(**{ATTR_COLOR_TEMP: 400}) assert color.data == b'#000000ff00' def test_rgb_not_supported(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts color temperature only color_channels = MockValue(data=0x01, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color is None def test_no_color_value(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) values = MockLightValues(primary=value) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color is None def test_no_color_channels_value(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) values = MockLightValues(primary=value, color=color) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color is None def test_rgb_value_changed(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB only color_channels = MockValue(data=0x1c, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color == [0, 0, 0] color.data = b'#c896640000' value_changed(color) assert device.rgb_color == [200, 150, 100] def test_rgbww_value_changed(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB, Warm White color_channels = MockValue(data=0x1d, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color == [0, 0, 0] color.data = b'#c86400c800' value_changed(color) assert device.rgb_color == [200, 150, 100] def test_rgbcw_value_changed(mock_openzwave): """Test value changed for rgb lights.""" node = MockNode(command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB, Cold White color_channels = MockValue(data=0x1e, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert device.rgb_color == [0, 0, 0] color.data = b'#c86400c800' value_changed(color) assert device.rgb_color == [200, 150, 100] def test_ct_value_changed(mock_openzwave): """Test value changed for zw098 lights.""" node = MockNode(manufacturer_id='0086', product_id='0062', command_classes=[const.COMMAND_CLASS_SWITCH_COLOR]) value = MockValue(data=0, node=node) color = MockValue(data=b'#0000000000', node=node) # Suppoorts RGB, Cold White color_channels = MockValue(data=0x1f, node=node) values = MockLightValues(primary=value, color=color, color_channels=color_channels) device = zwave.get_device(node=node, values=values, node_config={}) assert device.color_temp == zwave.TEMP_MID_HASS color.data = b'#000000ff00' value_changed(color) assert device.color_temp == zwave.TEMP_WARM_HASS color.data = b'#00000000ff' value_changed(color) assert device.color_temp == zwave.TEMP_COLD_HASS