mirror of https://github.com/home-assistant/core
1359 lines
46 KiB
Python
1359 lines
46 KiB
Python
"""Test KNX light."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
import pytest
|
|
from xknx.core import XknxConnectionState
|
|
from xknx.devices.light import Light as XknxLight
|
|
|
|
from homeassistant.components.knx.const import CONF_STATE_ADDRESS, KNX_ADDRESS, Platform
|
|
from homeassistant.components.knx.schema import LightSchema
|
|
from homeassistant.components.light import (
|
|
ATTR_BRIGHTNESS,
|
|
ATTR_COLOR_NAME,
|
|
ATTR_COLOR_TEMP_KELVIN,
|
|
ATTR_HS_COLOR,
|
|
ATTR_RGBW_COLOR,
|
|
ColorMode,
|
|
)
|
|
from homeassistant.const import CONF_NAME, STATE_OFF, STATE_ON, EntityCategory
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from . import KnxEntityGenerator
|
|
from .conftest import KNXTestKit
|
|
|
|
from tests.common import async_fire_time_changed
|
|
|
|
|
|
async def test_light_simple(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test simple KNX light."""
|
|
test_address = "1/1/1"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: {
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
}
|
|
}
|
|
)
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_OFF,
|
|
supported_color_modes=[ColorMode.ONOFF],
|
|
)
|
|
# turn on light
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_address, True)
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
color_mode=ColorMode.ONOFF,
|
|
)
|
|
# turn off light
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_address, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# receive ON telegram
|
|
await knx.receive_write(test_address, True)
|
|
knx.assert_state("light.test", STATE_ON)
|
|
|
|
# receive OFF telegram
|
|
await knx.receive_write(test_address, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
# switch does not respond to read by default
|
|
await knx.receive_read(test_address)
|
|
await knx.assert_telegram_count(0)
|
|
|
|
|
|
async def test_light_brightness(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test dimmable KNX light."""
|
|
test_address = "1/1/1"
|
|
test_brightness = "1/1/2"
|
|
test_brightness_state = "1/1/3"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: {
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
}
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_brightness_state)
|
|
knx.xknx.connection_manager.connection_state_changed(XknxConnectionState.CONNECTED)
|
|
# turn on light via brightness
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 80},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_brightness, (80,))
|
|
# state is still OFF until controller reports otherwise
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
await knx.receive_write(test_address, True)
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=80,
|
|
supported_color_modes=[ColorMode.BRIGHTNESS],
|
|
color_mode=ColorMode.BRIGHTNESS,
|
|
)
|
|
# receive brightness changes from KNX
|
|
await knx.receive_write(test_brightness_state, (255,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255)
|
|
await knx.receive_write(test_brightness, (128,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=128)
|
|
# turn off light via brightness
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 0},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_address, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
|
|
async def test_light_color_temp_absolute(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light color temperature adjustable in Kelvin."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_brightness = "1/1/3"
|
|
test_brightness_state = "1/1/4"
|
|
test_ct = "1/1/5"
|
|
test_ct_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
LightSchema.CONF_COLOR_TEMP_ADDRESS: test_ct,
|
|
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS: test_ct_state,
|
|
LightSchema.CONF_COLOR_TEMP_MODE: "absolute",
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_brightness_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_brightness_state, (255,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_ct_state)
|
|
await knx.receive_response(test_ct_state, (0x0A, 0x8C)) # 2700 Kelvin - 370 Mired
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.COLOR_TEMP],
|
|
color_mode=ColorMode.COLOR_TEMP,
|
|
color_temp=370,
|
|
color_temp_kelvin=2700,
|
|
)
|
|
# change color temperature from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_TEMP_KELVIN: 4000}, # 4000 - 0x0FA0
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_ct, (0x0F, 0xA0))
|
|
knx.assert_state("light.test", STATE_ON, color_temp=250)
|
|
# change color temperature from KNX
|
|
await knx.receive_write(test_ct_state, (0x17, 0x70)) # 6000 Kelvin - 166 Mired
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
color_temp=166,
|
|
color_temp_kelvin=6000,
|
|
)
|
|
|
|
|
|
async def test_light_color_temp_relative(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light color temperature adjustable in percent."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_brightness = "1/1/3"
|
|
test_brightness_state = "1/1/4"
|
|
test_ct = "1/1/5"
|
|
test_ct_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
LightSchema.CONF_COLOR_TEMP_ADDRESS: test_ct,
|
|
LightSchema.CONF_COLOR_TEMP_STATE_ADDRESS: test_ct_state,
|
|
LightSchema.CONF_COLOR_TEMP_MODE: "relative",
|
|
LightSchema.CONF_MIN_KELVIN: 3000,
|
|
LightSchema.CONF_MAX_KELVIN: 4000,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_brightness_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_brightness_state, (255,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_ct_state)
|
|
await knx.receive_response(test_ct_state, (0xFF,)) # 100 % - 4000 K - 250 Mired
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.COLOR_TEMP],
|
|
color_mode=ColorMode.COLOR_TEMP,
|
|
color_temp=250,
|
|
color_temp_kelvin=4000,
|
|
)
|
|
# change color temperature from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": "light.test",
|
|
ATTR_COLOR_TEMP_KELVIN: 3333, # 3333 Kelvin - 33.3 % - 0x55
|
|
},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_ct, (0x55,))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
color_temp=300,
|
|
color_temp_kelvin=3333,
|
|
)
|
|
# change color temperature from KNX
|
|
await knx.receive_write(test_ct_state, (0xE6,)) # 3901 Kelvin - 90.1 % - 256 Mired
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
color_temp=256,
|
|
color_temp_kelvin=3901,
|
|
)
|
|
|
|
|
|
async def test_light_hs_color(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with hs color."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_brightness = "1/1/3"
|
|
test_brightness_state = "1/1/4"
|
|
test_hue = "1/1/5"
|
|
test_hue_state = "1/1/6"
|
|
test_sat = "1/1/7"
|
|
test_sat_state = "1/1/8"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
LightSchema.CONF_HUE_ADDRESS: test_hue,
|
|
LightSchema.CONF_HUE_STATE_ADDRESS: test_hue_state,
|
|
LightSchema.CONF_SATURATION_ADDRESS: test_sat,
|
|
LightSchema.CONF_SATURATION_STATE_ADDRESS: test_sat_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_brightness_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_brightness_state, (255,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_hue_state)
|
|
await knx.assert_read(test_sat_state)
|
|
await knx.receive_response(test_hue_state, (0xFF,))
|
|
await knx.receive_response(test_sat_state, (0xFF,))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.HS],
|
|
color_mode=ColorMode.HS,
|
|
hs_color=(360, 100),
|
|
)
|
|
# change color from HA - only hue
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "blue"}, # hue: 240, sat: 100
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_hue, (0xAA,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, hs_color=(240, 100))
|
|
|
|
# change color from HA - only saturation
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": "light.test",
|
|
ATTR_HS_COLOR: (240, 50),
|
|
}, # hue: 60, sat: 12.157
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_sat, (0x80,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, hs_color=(240, 50))
|
|
|
|
# change color from HA - hue and sat
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"}, # hue: 330, sat: 59
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_hue, (0xEA,))
|
|
await knx.assert_write(test_sat, (0x96,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, hs_color=(330, 59))
|
|
|
|
# change color and brightness from KNX
|
|
await knx.receive_write(test_brightness, (0xB2,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=178, hs_color=(330, 59))
|
|
await knx.receive_write(test_hue, (0x7D,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=178, hs_color=(176, 59))
|
|
await knx.receive_write(test_sat, (0xD1,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=178, hs_color=(176, 82))
|
|
|
|
|
|
async def test_light_xyy_color(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with xyy color."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_xyy = "1/1/5"
|
|
test_xyy_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_XYY_ADDRESS: test_xyy,
|
|
LightSchema.CONF_XYY_STATE_ADDRESS: test_xyy_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_xyy_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_xyy_state, (0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x03))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=204,
|
|
supported_color_modes=[ColorMode.XY],
|
|
color_mode=ColorMode.XY,
|
|
xy_color=(0.8, 0.8),
|
|
)
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 139, ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_xyy, (179, 116, 76, 139, 139, 3))
|
|
knx.assert_state("light.test", STATE_ON, brightness=139, xy_color=(0.701, 0.299))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 255},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_xyy, (0, 0, 0, 0, 255, 1))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, xy_color=(0.701, 0.299))
|
|
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_xyy, (120, 16, 63, 59, 0, 2))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, xy_color=(0.469, 0.247))
|
|
|
|
# change color and brightness from KNX
|
|
await knx.receive_write(test_xyy, (0x85, 0x1E, 0x4F, 0x5C, 0x19, 0x03))
|
|
knx.assert_state("light.test", STATE_ON, brightness=25, xy_color=(0.52, 0.31))
|
|
# change brightness from KNX
|
|
await knx.receive_write(test_xyy, (0x00, 0x00, 0x00, 0x00, 0x80, 0x01))
|
|
knx.assert_state("light.test", STATE_ON, brightness=128, xy_color=(0.52, 0.31))
|
|
# change color from KNX
|
|
await knx.receive_write(test_xyy, (0x2E, 0x14, 0x40, 0x00, 0x00, 0x02))
|
|
knx.assert_state("light.test", STATE_ON, brightness=128, xy_color=(0.18, 0.25))
|
|
|
|
|
|
async def test_light_xyy_color_with_brightness(
|
|
hass: HomeAssistant, knx: KNXTestKit
|
|
) -> None:
|
|
"""Test KNX light with xyy color and explicit brightness address."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_brightness = "1/1/3"
|
|
test_brightness_state = "1/1/4"
|
|
test_xyy = "1/1/5"
|
|
test_xyy_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
LightSchema.CONF_XYY_ADDRESS: test_xyy,
|
|
LightSchema.CONF_XYY_STATE_ADDRESS: test_xyy_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_brightness_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_brightness_state, (255,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_xyy_state)
|
|
await knx.receive_response(test_xyy_state, (0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x03))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255, # brightness form xyy_color ignored when extra brightness GA is used
|
|
supported_color_modes=[ColorMode.XY],
|
|
color_mode=ColorMode.XY,
|
|
xy_color=(0.8, 0.8),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_xyy, (179, 116, 76, 139, 0, 2))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, xy_color=(0.701, 0.299))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 139},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_brightness, (0x8B,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=139, xy_color=(0.701, 0.299))
|
|
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 255, ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_xyy, (120, 16, 63, 59, 255, 3))
|
|
# brightness relies on brightness_state GA
|
|
await knx.receive_write(test_brightness_state, (255,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, xy_color=(0.469, 0.247))
|
|
|
|
# change color and brightness from KNX
|
|
await knx.receive_write(test_xyy, (0x85, 0x1E, 0x4F, 0x5C, 0x00, 0x02))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, xy_color=(0.52, 0.31))
|
|
await knx.receive_write(test_brightness, (21,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=21, xy_color=(0.52, 0.31))
|
|
|
|
|
|
async def test_light_rgb_individual(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with rgb color in individual GAs."""
|
|
test_red = "1/1/3"
|
|
test_red_state = "1/1/4"
|
|
test_green = "1/1/5"
|
|
test_green_state = "1/1/6"
|
|
test_blue = "1/1/7"
|
|
test_blue_state = "1/1/8"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
LightSchema.CONF_INDIVIDUAL_COLORS: {
|
|
LightSchema.CONF_RED: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_red,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_red_state,
|
|
},
|
|
LightSchema.CONF_GREEN: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_green,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_green_state,
|
|
},
|
|
LightSchema.CONF_BLUE: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_blue,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_blue_state,
|
|
},
|
|
},
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_red_state)
|
|
await knx.assert_read(test_green_state)
|
|
await knx.receive_response(test_red_state, (255,))
|
|
await knx.receive_response(test_green_state, (255,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_blue_state)
|
|
await knx.receive_response(test_blue_state, (255,))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.RGB],
|
|
color_mode=ColorMode.RGB,
|
|
rgb_color=(255, 255, 255),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (255,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgb_color=(255, 0, 0))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 200},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (200,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=200, rgb_color=(255, 0, 0))
|
|
|
|
# change only color, keep brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (200,))
|
|
await knx.assert_write(test_green, (82,))
|
|
await knx.assert_write(test_blue, (141,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=200, rgb_color=(255, 105, 180))
|
|
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 100, ATTR_COLOR_NAME: "yellow"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (100,))
|
|
await knx.assert_write(test_green, (100,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=100, rgb_color=(255, 255, 0))
|
|
|
|
# turn OFF from KNX
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (0,))
|
|
await knx.receive_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# turn ON from KNX
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (180,))
|
|
await knx.receive_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgb_color=(0, 255, 0))
|
|
|
|
# turn OFF from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (0,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
# turn ON from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
# color will not be restored - defaults to white
|
|
await knx.assert_write(test_red, (255,))
|
|
await knx.assert_write(test_green, (255,))
|
|
await knx.assert_write(test_blue, (255,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgb_color=(255, 255, 255))
|
|
|
|
# turn ON with brightness only from HA - defaults to white
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (0,))
|
|
await knx.receive_write(test_blue, (0,))
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 45},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (45,))
|
|
await knx.assert_write(test_green, (45,))
|
|
await knx.assert_write(test_blue, (45,))
|
|
|
|
|
|
async def test_light_rgbw_individual(
|
|
hass: HomeAssistant, knx: KNXTestKit, freezer: FrozenDateTimeFactory
|
|
) -> None:
|
|
"""Test KNX light with rgbw color in individual GAs."""
|
|
test_red = "1/1/3"
|
|
test_red_state = "1/1/4"
|
|
test_green = "1/1/5"
|
|
test_green_state = "1/1/6"
|
|
test_blue = "1/1/7"
|
|
test_blue_state = "1/1/8"
|
|
test_white = "1/1/9"
|
|
test_white_state = "1/1/10"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
LightSchema.CONF_INDIVIDUAL_COLORS: {
|
|
LightSchema.CONF_RED: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_red,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_red_state,
|
|
},
|
|
LightSchema.CONF_GREEN: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_green,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_green_state,
|
|
},
|
|
LightSchema.CONF_BLUE: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_blue,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_blue_state,
|
|
},
|
|
LightSchema.CONF_WHITE: {
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_white,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_white_state,
|
|
},
|
|
},
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_red_state)
|
|
await knx.assert_read(test_green_state)
|
|
await knx.receive_response(test_red_state, (0,))
|
|
await knx.receive_response(test_green_state, (0,))
|
|
# # StateUpdater semaphore allows 2 concurrent requests
|
|
await knx.assert_read(test_blue_state)
|
|
await knx.assert_read(test_white_state)
|
|
await knx.receive_response(test_blue_state, (0,))
|
|
await knx.receive_response(test_white_state, (255,))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.RGBW],
|
|
color_mode=ColorMode.RGBW,
|
|
rgbw_color=(0, 0, 0, 255),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (255,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
await knx.assert_write(test_white, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgbw_color=(255, 0, 0, 0))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 200},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (200,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
await knx.assert_write(test_white, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=200, rgbw_color=(255, 0, 0, 0))
|
|
|
|
# change only color, keep brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (200,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (100,))
|
|
await knx.assert_write(test_white, (139,))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=200,
|
|
rgb_color=(255, 104, 179), # minor rounding error - expected (255, 105, 180)
|
|
rgbw_color=(255, 0, 127, 177), # expected (255, 0, 128, 178)
|
|
)
|
|
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 100, ATTR_COLOR_NAME: "yellow"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (100,))
|
|
await knx.assert_write(test_green, (100,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
await knx.assert_write(test_white, (0,))
|
|
knx.assert_state(
|
|
"light.test", STATE_ON, brightness=100, rgbw_color=(255, 255, 0, 0)
|
|
)
|
|
|
|
# turn OFF from KNX
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (0,))
|
|
# # individual color debounce takes 0.2 seconds if not all 4 addresses received
|
|
knx.assert_state("light.test", STATE_ON)
|
|
freezer.tick(timedelta(seconds=XknxLight.DEBOUNCE_TIMEOUT))
|
|
async_fire_time_changed(hass)
|
|
await knx.xknx.task_registry.block_till_done()
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# turn ON from KNX
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (180,))
|
|
await knx.receive_write(test_blue, (0,))
|
|
await knx.receive_write(test_white, (0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgbw_color=(0, 255, 0, 0))
|
|
|
|
# turn OFF from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (0,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
await knx.assert_write(test_white, (0,))
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
# turn ON from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
# color will not be restored - defaults to 100% on all channels
|
|
await knx.assert_write(test_red, (255,))
|
|
await knx.assert_write(test_green, (255,))
|
|
await knx.assert_write(test_blue, (255,))
|
|
await knx.assert_write(test_white, (255,))
|
|
knx.assert_state(
|
|
"light.test", STATE_ON, brightness=255, rgbw_color=(255, 255, 255, 255)
|
|
)
|
|
|
|
# turn ON with brightness only from HA - defaults to white
|
|
await knx.receive_write(test_red, (0,))
|
|
await knx.receive_write(test_green, (0,))
|
|
await knx.receive_write(test_blue, (0,))
|
|
await knx.receive_write(test_white, (0,))
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 45},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_red, (0,))
|
|
await knx.assert_write(test_green, (0,))
|
|
await knx.assert_write(test_blue, (0,))
|
|
await knx.assert_write(test_white, (45,))
|
|
|
|
|
|
async def test_light_rgb(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with rgb color."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_rgb = "1/1/5"
|
|
test_rgb_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_COLOR_ADDRESS: test_rgb,
|
|
LightSchema.CONF_COLOR_STATE_ADDRESS: test_rgb_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_rgb_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_rgb_state, (0xFF, 0xFF, 0xFF))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.RGB],
|
|
color_mode=ColorMode.RGB,
|
|
rgb_color=(255, 255, 255),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgb, (255, 0, 0))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgb_color=(255, 0, 0))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 200},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgb, (200, 0, 0))
|
|
knx.assert_state("light.test", STATE_ON, brightness=200, rgb_color=(255, 0, 0))
|
|
|
|
# change color, keep brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgb, (200, 82, 141))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=200,
|
|
rgb_color=(255, 105, 180),
|
|
)
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 100, ATTR_COLOR_NAME: "yellow"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgb, (100, 100, 0))
|
|
knx.assert_state("light.test", STATE_ON, brightness=100, rgb_color=(255, 255, 0))
|
|
|
|
# turn OFF from KNX
|
|
await knx.receive_write(test_address_state, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# receive color update from KNX - still OFF
|
|
await knx.receive_write(test_rgb, (0, 180, 0))
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# turn ON from KNX - include color update
|
|
await knx.receive_write(test_address_state, True)
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgb_color=(0, 255, 0))
|
|
|
|
# turn OFF from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_address, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
# turn ON from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
# color will be restored in no other state was received
|
|
await knx.assert_write(test_address, True)
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgb_color=(0, 255, 0))
|
|
|
|
|
|
async def test_light_rgbw(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with rgbw color."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_rgbw = "1/1/5"
|
|
test_rgbw_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_RGBW_ADDRESS: test_rgbw,
|
|
LightSchema.CONF_RGBW_STATE_ADDRESS: test_rgbw_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_rgbw_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_rgbw_state, (0xFF, 0x65, 0x66, 0x67, 0x00, 0x0F))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.RGBW],
|
|
color_mode=ColorMode.RGBW,
|
|
rgbw_color=(255, 101, 102, 103),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgbw_color=(255, 0, 0, 0))
|
|
|
|
# change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 200},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (0xC8, 0x00, 0x00, 0x00, 0x00, 0x0F))
|
|
knx.assert_state("light.test", STATE_ON, brightness=200, rgbw_color=(255, 0, 0, 0))
|
|
|
|
# change color, keep brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (200, 0, 100, 139, 0x00, 0x0F))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=200,
|
|
rgb_color=(255, 104, 179), # minor rounding error - expected (255, 105, 180)
|
|
rgbw_color=(255, 0, 127, 177), # expected (255, 0, 128, 178)
|
|
)
|
|
# change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 100, ATTR_COLOR_NAME: "yellow"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (100, 100, 0, 0, 0x00, 0x0F))
|
|
knx.assert_state(
|
|
"light.test", STATE_ON, brightness=100, rgbw_color=(255, 255, 0, 0)
|
|
)
|
|
|
|
# turn OFF from KNX
|
|
await knx.receive_write(test_address_state, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# receive color update from KNX - still OFF
|
|
await knx.receive_write(test_rgbw, (0, 180, 0, 0, 0x00, 0x0F))
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
# turn ON from KNX - include color update
|
|
await knx.receive_write(test_address_state, True)
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgbw_color=(0, 255, 0, 0))
|
|
|
|
# turn OFF from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_address, False)
|
|
knx.assert_state("light.test", STATE_OFF)
|
|
|
|
# turn ON from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test"},
|
|
blocking=True,
|
|
)
|
|
# color will be restored if no other state was received
|
|
await knx.assert_write(test_address, True)
|
|
knx.assert_state("light.test", STATE_ON, brightness=180, rgbw_color=(0, 255, 0, 0))
|
|
|
|
|
|
async def test_light_rgbw_brightness(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
|
"""Test KNX light with rgbw color with dedicated brightness."""
|
|
test_address = "1/1/1"
|
|
test_address_state = "1/1/2"
|
|
test_brightness = "1/1/3"
|
|
test_brightness_state = "1/1/4"
|
|
test_rgbw = "1/1/5"
|
|
test_rgbw_state = "1/1/6"
|
|
await knx.setup_integration(
|
|
{
|
|
LightSchema.PLATFORM: [
|
|
{
|
|
CONF_NAME: "test",
|
|
KNX_ADDRESS: test_address,
|
|
CONF_STATE_ADDRESS: test_address_state,
|
|
LightSchema.CONF_BRIGHTNESS_ADDRESS: test_brightness,
|
|
LightSchema.CONF_BRIGHTNESS_STATE_ADDRESS: test_brightness_state,
|
|
LightSchema.CONF_RGBW_ADDRESS: test_rgbw,
|
|
LightSchema.CONF_RGBW_STATE_ADDRESS: test_rgbw_state,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
# StateUpdater initialize state
|
|
await knx.assert_read(test_address_state)
|
|
await knx.assert_read(test_brightness_state)
|
|
await knx.receive_response(test_address_state, True)
|
|
await knx.receive_response(test_brightness_state, (0xFF,))
|
|
await knx.assert_read(test_rgbw_state)
|
|
await knx.receive_response(test_rgbw_state, (0xFF, 0x65, 0x66, 0x67, 0x00, 0x0F))
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
supported_color_modes=[ColorMode.RGBW],
|
|
color_mode=ColorMode.RGBW,
|
|
rgbw_color=(255, 101, 102, 103),
|
|
)
|
|
# change color from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_NAME: "red"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F))
|
|
knx.assert_state("light.test", STATE_ON, brightness=255, rgbw_color=(255, 0, 0, 0))
|
|
# # update from dedicated brightness state
|
|
await knx.receive_write(test_brightness_state, (0xF0,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=240, rgbw_color=(255, 0, 0, 0))
|
|
|
|
# single encoded brightness - at least one primary color = 255
|
|
# # change brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 128},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_brightness, (128,))
|
|
knx.assert_state("light.test", STATE_ON, brightness=128, rgbw_color=(255, 0, 0, 0))
|
|
# # change color and brightness from HA
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_BRIGHTNESS: 128, ATTR_COLOR_NAME: "hotpink"},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (255, 0, 128, 178, 0x00, 0x0F))
|
|
await knx.assert_write(test_brightness, (128,))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=128,
|
|
rgb_color=(255, 105, 180),
|
|
rgbw_color=(255, 0, 128, 178),
|
|
)
|
|
|
|
# doubly encoded brightness
|
|
# brightness is handled by dedicated brightness address only
|
|
# # from dedicated rgbw state
|
|
await knx.receive_write(test_rgbw_state, (0xC8, 0x00, 0x00, 0x00, 0x00, 0x0F))
|
|
knx.assert_state("light.test", STATE_ON, brightness=128, rgbw_color=(200, 0, 0, 0))
|
|
# # from HA - only color
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_RGBW_COLOR: (20, 30, 40, 50)},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (20, 30, 40, 50, 0x00, 0x0F))
|
|
knx.assert_state(
|
|
"light.test", STATE_ON, brightness=128, rgbw_color=(20, 30, 40, 50)
|
|
)
|
|
# # from HA - brightness and color
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": "light.test",
|
|
ATTR_BRIGHTNESS: 50,
|
|
ATTR_RGBW_COLOR: (100, 200, 55, 12),
|
|
},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write(test_rgbw, (100, 200, 55, 12, 0x00, 0x0F))
|
|
await knx.assert_write(test_brightness, (50,))
|
|
knx.assert_state(
|
|
"light.test", STATE_ON, brightness=50, rgbw_color=(100, 200, 55, 12)
|
|
)
|
|
|
|
|
|
async def test_light_ui_create(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
create_ui_entity: KnxEntityGenerator,
|
|
) -> None:
|
|
"""Test creating a light."""
|
|
await knx.setup_integration({})
|
|
await create_ui_entity(
|
|
platform=Platform.LIGHT,
|
|
entity_data={"name": "test"},
|
|
knx_data={
|
|
"ga_switch": {"write": "1/1/1", "state": "2/2/2"},
|
|
"_light_color_mode_schema": "default",
|
|
"sync_state": True,
|
|
},
|
|
)
|
|
# created entity sends read-request to KNX bus
|
|
await knx.assert_read("2/2/2")
|
|
await knx.receive_response("2/2/2", True)
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
supported_color_modes=[ColorMode.ONOFF],
|
|
color_mode=ColorMode.ONOFF,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("color_temp_mode", "raw_ct"),
|
|
[
|
|
("7.600", (0x10, 0x68)),
|
|
("9", (0x46, 0x69)),
|
|
("5.001", (0x74,)),
|
|
],
|
|
)
|
|
async def test_light_ui_color_temp(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
create_ui_entity: KnxEntityGenerator,
|
|
color_temp_mode: str,
|
|
raw_ct: tuple[int, ...],
|
|
) -> None:
|
|
"""Test creating a color-temp light."""
|
|
await knx.setup_integration({})
|
|
await create_ui_entity(
|
|
platform=Platform.LIGHT,
|
|
entity_data={"name": "test"},
|
|
knx_data={
|
|
"ga_switch": {"write": "1/1/1", "state": "2/2/2"},
|
|
"ga_color_temp": {
|
|
"write": "3/3/3",
|
|
"dpt": color_temp_mode,
|
|
},
|
|
"_light_color_mode_schema": "default",
|
|
"sync_state": True,
|
|
},
|
|
)
|
|
await knx.assert_read("2/2/2", True)
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{"entity_id": "light.test", ATTR_COLOR_TEMP_KELVIN: 4200},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write("3/3/3", raw_ct)
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
supported_color_modes=[ColorMode.COLOR_TEMP],
|
|
color_mode=ColorMode.COLOR_TEMP,
|
|
color_temp_kelvin=pytest.approx(4200, abs=1),
|
|
)
|
|
|
|
|
|
async def test_light_ui_multi_mode(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
create_ui_entity: KnxEntityGenerator,
|
|
) -> None:
|
|
"""Test creating a light with multiple color modes."""
|
|
await knx.setup_integration({})
|
|
await create_ui_entity(
|
|
platform=Platform.LIGHT,
|
|
entity_data={"name": "test"},
|
|
knx_data={
|
|
"color_temp_min": 2700,
|
|
"color_temp_max": 6000,
|
|
"_light_color_mode_schema": "default",
|
|
"ga_switch": {
|
|
"write": "1/1/1",
|
|
"passive": [],
|
|
"state": "2/2/2",
|
|
},
|
|
"sync_state": True,
|
|
"ga_brightness": {
|
|
"write": "0/6/0",
|
|
"state": "0/6/1",
|
|
"passive": [],
|
|
},
|
|
"ga_color_temp": {
|
|
"write": "0/6/2",
|
|
"dpt": "7.600",
|
|
"state": "0/6/3",
|
|
"passive": [],
|
|
},
|
|
"ga_color": {
|
|
"write": "0/6/4",
|
|
"dpt": "251.600",
|
|
"state": "0/6/5",
|
|
"passive": [],
|
|
},
|
|
},
|
|
)
|
|
await knx.assert_read("2/2/2", True)
|
|
await knx.assert_read("0/6/1", (0xFF,))
|
|
await knx.assert_read("0/6/5", (0xFF, 0x65, 0x66, 0x67, 0x00, 0x0F))
|
|
await knx.assert_read("0/6/3", (0x12, 0x34))
|
|
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": "light.test",
|
|
ATTR_COLOR_NAME: "hotpink",
|
|
},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write("0/6/4", (255, 0, 128, 178, 0, 15))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
color_temp_kelvin=None,
|
|
rgbw_color=(255, 0, 128, 178),
|
|
supported_color_modes=[
|
|
ColorMode.COLOR_TEMP,
|
|
ColorMode.RGBW,
|
|
],
|
|
color_mode=ColorMode.RGBW,
|
|
)
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": "light.test",
|
|
ATTR_COLOR_TEMP_KELVIN: 4200,
|
|
},
|
|
blocking=True,
|
|
)
|
|
await knx.assert_write("0/6/2", (0x10, 0x68))
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
brightness=255,
|
|
color_temp_kelvin=4200,
|
|
rgbw_color=None,
|
|
supported_color_modes=[
|
|
ColorMode.COLOR_TEMP,
|
|
ColorMode.RGBW,
|
|
],
|
|
color_mode=ColorMode.COLOR_TEMP,
|
|
)
|
|
|
|
|
|
async def test_light_ui_load(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
load_config_store: None,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""Test loading a light from storage."""
|
|
await knx.setup_integration({})
|
|
|
|
await knx.assert_read("1/0/21", response=True, ignore_order=True)
|
|
# unrelated switch in config store
|
|
await knx.assert_read("1/0/45", response=True, ignore_order=True)
|
|
|
|
knx.assert_state(
|
|
"light.test",
|
|
STATE_ON,
|
|
supported_color_modes=[ColorMode.ONOFF],
|
|
color_mode=ColorMode.ONOFF,
|
|
)
|
|
|
|
entity = entity_registry.async_get("light.test")
|
|
assert entity.entity_category is EntityCategory.CONFIG
|