mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Convert kulersky to use new async backend (#47403)
This commit is contained in:
parent
6debf52e9b
commit
7c08592b5a
@ -15,9 +15,7 @@ async def _async_has_devices(hass) -> bool:
|
|||||||
"""Return if there are devices that can be discovered."""
|
"""Return if there are devices that can be discovered."""
|
||||||
# Check if there are any devices that can be discovered in the network.
|
# Check if there are any devices that can be discovered in the network.
|
||||||
try:
|
try:
|
||||||
devices = await hass.async_add_executor_job(
|
devices = await pykulersky.discover()
|
||||||
pykulersky.discover_bluetooth_devices
|
|
||||||
)
|
|
||||||
except pykulersky.PykulerskyException as exc:
|
except pykulersky.PykulerskyException as exc:
|
||||||
_LOGGER.error("Unable to discover nearby Kuler Sky devices: %s", exc)
|
_LOGGER.error("Unable to discover nearby Kuler Sky devices: %s", exc)
|
||||||
return False
|
return False
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
"""Kuler Sky light platform."""
|
"""Kuler Sky light platform."""
|
||||||
import asyncio
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Callable, List
|
from typing import Callable, List
|
||||||
@ -17,6 +16,7 @@ from homeassistant.components.light import (
|
|||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
@ -30,14 +30,6 @@ SUPPORT_KULERSKY = SUPPORT_BRIGHTNESS | SUPPORT_COLOR | SUPPORT_WHITE_VALUE
|
|||||||
|
|
||||||
DISCOVERY_INTERVAL = timedelta(seconds=60)
|
DISCOVERY_INTERVAL = timedelta(seconds=60)
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
|
||||||
|
|
||||||
|
|
||||||
def check_light(light: pykulersky.Light):
|
|
||||||
"""Attempt to connect to this light and read the color."""
|
|
||||||
light.connect()
|
|
||||||
light.get_color()
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistantType,
|
hass: HomeAssistantType,
|
||||||
@ -47,45 +39,26 @@ async def async_setup_entry(
|
|||||||
"""Set up Kuler sky light devices."""
|
"""Set up Kuler sky light devices."""
|
||||||
if DOMAIN not in hass.data:
|
if DOMAIN not in hass.data:
|
||||||
hass.data[DOMAIN] = {}
|
hass.data[DOMAIN] = {}
|
||||||
if "devices" not in hass.data[DOMAIN]:
|
if "addresses" not in hass.data[DOMAIN]:
|
||||||
hass.data[DOMAIN]["devices"] = set()
|
hass.data[DOMAIN]["addresses"] = set()
|
||||||
if "discovery" not in hass.data[DOMAIN]:
|
|
||||||
hass.data[DOMAIN]["discovery"] = asyncio.Lock()
|
|
||||||
|
|
||||||
async def discover(*args):
|
async def discover(*args):
|
||||||
"""Attempt to discover new lights."""
|
"""Attempt to discover new lights."""
|
||||||
# Since discovery needs to connect to all discovered bluetooth devices, and
|
lights = await pykulersky.discover()
|
||||||
# only rules out devices after a timeout, it can potentially take a long
|
|
||||||
# time. If there's already a discovery running, just skip this poll.
|
|
||||||
if hass.data[DOMAIN]["discovery"].locked():
|
|
||||||
return
|
|
||||||
|
|
||||||
async with hass.data[DOMAIN]["discovery"]:
|
# Filter out already discovered lights
|
||||||
bluetooth_devices = await hass.async_add_executor_job(
|
new_lights = [
|
||||||
pykulersky.discover_bluetooth_devices
|
light
|
||||||
)
|
for light in lights
|
||||||
|
if light.address not in hass.data[DOMAIN]["addresses"]
|
||||||
|
]
|
||||||
|
|
||||||
# Filter out already connected lights
|
new_entities = []
|
||||||
new_devices = [
|
for light in new_lights:
|
||||||
device
|
hass.data[DOMAIN]["addresses"].add(light.address)
|
||||||
for device in bluetooth_devices
|
new_entities.append(KulerskyLight(light))
|
||||||
if device["address"] not in hass.data[DOMAIN]["devices"]
|
|
||||||
]
|
|
||||||
|
|
||||||
for device in new_devices:
|
async_add_entities(new_entities, update_before_add=True)
|
||||||
light = pykulersky.Light(device["address"], device["name"])
|
|
||||||
try:
|
|
||||||
# If the connection fails, either this is not a Kuler Sky
|
|
||||||
# light, or it's bluetooth connection is currently locked
|
|
||||||
# by another device. If the vendor's app is connected to
|
|
||||||
# the light when home assistant tries to connect, this
|
|
||||||
# connection will fail.
|
|
||||||
await hass.async_add_executor_job(check_light, light)
|
|
||||||
except pykulersky.PykulerskyException:
|
|
||||||
continue
|
|
||||||
# The light has successfully connected
|
|
||||||
hass.data[DOMAIN]["devices"].add(device["address"])
|
|
||||||
async_add_entities([KulerskyLight(light)], update_before_add=True)
|
|
||||||
|
|
||||||
# Start initial discovery
|
# Start initial discovery
|
||||||
hass.async_create_task(discover())
|
hass.async_create_task(discover())
|
||||||
@ -94,6 +67,11 @@ async def async_setup_entry(
|
|||||||
async_track_time_interval(hass, discover, DISCOVERY_INTERVAL)
|
async_track_time_interval(hass, discover, DISCOVERY_INTERVAL)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||||
|
"""Cleanup the Kuler sky integration."""
|
||||||
|
hass.data.pop(DOMAIN, None)
|
||||||
|
|
||||||
|
|
||||||
class KulerskyLight(LightEntity):
|
class KulerskyLight(LightEntity):
|
||||||
"""Representation of an Kuler Sky Light."""
|
"""Representation of an Kuler Sky Light."""
|
||||||
|
|
||||||
@ -103,21 +81,24 @@ class KulerskyLight(LightEntity):
|
|||||||
self._hs_color = None
|
self._hs_color = None
|
||||||
self._brightness = None
|
self._brightness = None
|
||||||
self._white_value = None
|
self._white_value = None
|
||||||
self._available = True
|
self._available = None
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
self.async_on_remove(
|
self.async_on_remove(
|
||||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.disconnect)
|
self.hass.bus.async_listen_once(
|
||||||
|
EVENT_HOMEASSISTANT_STOP, self.async_will_remove_from_hass
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self, *args) -> None:
|
||||||
"""Run when entity will be removed from hass."""
|
"""Run when entity will be removed from hass."""
|
||||||
await self.hass.async_add_executor_job(self.disconnect)
|
try:
|
||||||
|
await self._light.disconnect()
|
||||||
def disconnect(self, *args) -> None:
|
except pykulersky.PykulerskyException:
|
||||||
"""Disconnect the underlying device."""
|
_LOGGER.debug(
|
||||||
self._light.disconnect()
|
"Exception disconnected from %s", self._light.address, exc_info=True
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -168,7 +149,7 @@ class KulerskyLight(LightEntity):
|
|||||||
"""Return True if entity is available."""
|
"""Return True if entity is available."""
|
||||||
return self._available
|
return self._available
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs):
|
||||||
"""Instruct the light to turn on."""
|
"""Instruct the light to turn on."""
|
||||||
default_hs = (0, 0) if self._hs_color is None else self._hs_color
|
default_hs = (0, 0) if self._hs_color is None else self._hs_color
|
||||||
hue_sat = kwargs.get(ATTR_HS_COLOR, default_hs)
|
hue_sat = kwargs.get(ATTR_HS_COLOR, default_hs)
|
||||||
@ -187,28 +168,28 @@ class KulerskyLight(LightEntity):
|
|||||||
|
|
||||||
rgb = color_util.color_hsv_to_RGB(*hue_sat, brightness / 255 * 100)
|
rgb = color_util.color_hsv_to_RGB(*hue_sat, brightness / 255 * 100)
|
||||||
|
|
||||||
self._light.set_color(*rgb, white_value)
|
await self._light.set_color(*rgb, white_value)
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs):
|
||||||
"""Instruct the light to turn off."""
|
"""Instruct the light to turn off."""
|
||||||
self._light.set_color(0, 0, 0, 0)
|
await self._light.set_color(0, 0, 0, 0)
|
||||||
|
|
||||||
def update(self):
|
async def async_update(self):
|
||||||
"""Fetch new state data for this light."""
|
"""Fetch new state data for this light."""
|
||||||
try:
|
try:
|
||||||
if not self._light.connected:
|
if not self._available:
|
||||||
self._light.connect()
|
await self._light.connect()
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
r, g, b, w = self._light.get_color()
|
r, g, b, w = await self._light.get_color()
|
||||||
except pykulersky.PykulerskyException as exc:
|
except pykulersky.PykulerskyException as exc:
|
||||||
if self._available:
|
if self._available:
|
||||||
_LOGGER.warning("Unable to connect to %s: %s", self._light.address, exc)
|
_LOGGER.warning("Unable to connect to %s: %s", self._light.address, exc)
|
||||||
self._available = False
|
self._available = False
|
||||||
return
|
return
|
||||||
if not self._available:
|
if self._available is False:
|
||||||
_LOGGER.info("Reconnected to %s", self.entity_id)
|
_LOGGER.info("Reconnected to %s", self._light.address)
|
||||||
self._available = True
|
|
||||||
|
|
||||||
|
self._available = True
|
||||||
hsv = color_util.color_RGB_to_hsv(r, g, b)
|
hsv = color_util.color_RGB_to_hsv(r, g, b)
|
||||||
self._hs_color = hsv[:2]
|
self._hs_color = hsv[:2]
|
||||||
self._brightness = int(round((hsv[2] / 100) * 255))
|
self._brightness = int(round((hsv[2] / 100) * 255))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/kulersky",
|
"documentation": "https://www.home-assistant.io/integrations/kulersky",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pykulersky==0.4.0"
|
"pykulersky==0.5.2"
|
||||||
],
|
],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
"@emlove"
|
"@emlove"
|
||||||
|
@ -1477,7 +1477,7 @@ pykmtronic==0.0.3
|
|||||||
pykodi==0.2.1
|
pykodi==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.kulersky
|
# homeassistant.components.kulersky
|
||||||
pykulersky==0.4.0
|
pykulersky==0.5.2
|
||||||
|
|
||||||
# homeassistant.components.kwb
|
# homeassistant.components.kwb
|
||||||
pykwb==0.0.8
|
pykwb==0.0.8
|
||||||
|
@ -779,7 +779,7 @@ pykmtronic==0.0.3
|
|||||||
pykodi==0.2.1
|
pykodi==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.kulersky
|
# homeassistant.components.kulersky
|
||||||
pykulersky==0.4.0
|
pykulersky==0.5.2
|
||||||
|
|
||||||
# homeassistant.components.lastfm
|
# homeassistant.components.lastfm
|
||||||
pylast==4.1.0
|
pylast==4.1.0
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""Test the Kuler Sky config flow."""
|
"""Test the Kuler Sky config flow."""
|
||||||
from unittest.mock import patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pykulersky
|
import pykulersky
|
||||||
|
|
||||||
@ -16,14 +16,12 @@ async def test_flow_success(hass):
|
|||||||
assert result["type"] == "form"
|
assert result["type"] == "form"
|
||||||
assert result["errors"] is None
|
assert result["errors"] is None
|
||||||
|
|
||||||
|
light = MagicMock(spec=pykulersky.Light)
|
||||||
|
light.address = "AA:BB:CC:11:22:33"
|
||||||
|
light.name = "Bedroom"
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.kulersky.config_flow.pykulersky.discover_bluetooth_devices",
|
"homeassistant.components.kulersky.config_flow.pykulersky.discover",
|
||||||
return_value=[
|
return_value=[light],
|
||||||
{
|
|
||||||
"address": "AA:BB:CC:11:22:33",
|
|
||||||
"name": "Bedroom",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.kulersky.async_setup", return_value=True
|
"homeassistant.components.kulersky.async_setup", return_value=True
|
||||||
) as mock_setup, patch(
|
) as mock_setup, patch(
|
||||||
@ -54,7 +52,7 @@ async def test_flow_no_devices_found(hass):
|
|||||||
assert result["errors"] is None
|
assert result["errors"] is None
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.kulersky.config_flow.pykulersky.discover_bluetooth_devices",
|
"homeassistant.components.kulersky.config_flow.pykulersky.discover",
|
||||||
return_value=[],
|
return_value=[],
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.kulersky.async_setup", return_value=True
|
"homeassistant.components.kulersky.async_setup", return_value=True
|
||||||
@ -84,7 +82,7 @@ async def test_flow_exceptions_caught(hass):
|
|||||||
assert result["errors"] is None
|
assert result["errors"] is None
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.kulersky.config_flow.pykulersky.discover_bluetooth_devices",
|
"homeassistant.components.kulersky.config_flow.pykulersky.discover",
|
||||||
side_effect=pykulersky.PykulerskyException("TEST"),
|
side_effect=pykulersky.PykulerskyException("TEST"),
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.kulersky.async_setup", return_value=True
|
"homeassistant.components.kulersky.async_setup", return_value=True
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
"""Test the Kuler Sky lights."""
|
"""Test the Kuler Sky lights."""
|
||||||
import asyncio
|
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pykulersky
|
import pykulersky
|
||||||
@ -45,28 +44,17 @@ async def mock_light(hass, mock_entry):
|
|||||||
light = MagicMock(spec=pykulersky.Light)
|
light = MagicMock(spec=pykulersky.Light)
|
||||||
light.address = "AA:BB:CC:11:22:33"
|
light.address = "AA:BB:CC:11:22:33"
|
||||||
light.name = "Bedroom"
|
light.name = "Bedroom"
|
||||||
light.connected = False
|
light.connect.return_value = True
|
||||||
|
light.get_color.return_value = (0, 0, 0, 0)
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.kulersky.light.pykulersky.discover_bluetooth_devices",
|
"homeassistant.components.kulersky.light.pykulersky.discover",
|
||||||
return_value=[
|
return_value=[light],
|
||||||
{
|
|
||||||
"address": "AA:BB:CC:11:22:33",
|
|
||||||
"name": "Bedroom",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
):
|
):
|
||||||
with patch(
|
mock_entry.add_to_hass(hass)
|
||||||
"homeassistant.components.kulersky.light.pykulersky.Light",
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
return_value=light,
|
await hass.async_block_till_done()
|
||||||
), patch.object(light, "connect") as mock_connect, patch.object(
|
|
||||||
light, "get_color", return_value=(0, 0, 0, 0)
|
|
||||||
):
|
|
||||||
mock_entry.add_to_hass(hass)
|
|
||||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert mock_connect.called
|
assert light.connect.called
|
||||||
light.connected = True
|
|
||||||
|
|
||||||
yield light
|
yield light
|
||||||
|
|
||||||
@ -82,113 +70,34 @@ async def test_init(hass, mock_light):
|
|||||||
| SUPPORT_WHITE_VALUE,
|
| SUPPORT_WHITE_VALUE,
|
||||||
}
|
}
|
||||||
|
|
||||||
with patch.object(hass.loop, "stop"), patch.object(
|
with patch.object(hass.loop, "stop"):
|
||||||
mock_light, "disconnect"
|
|
||||||
) as mock_disconnect:
|
|
||||||
await hass.async_stop()
|
await hass.async_stop()
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert mock_disconnect.called
|
assert mock_light.disconnect.called
|
||||||
|
|
||||||
|
|
||||||
async def test_discovery_lock(hass, mock_entry):
|
|
||||||
"""Test discovery lock."""
|
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
discovery_finished = None
|
|
||||||
first_discovery_started = asyncio.Event()
|
|
||||||
|
|
||||||
async def mock_discovery(*args):
|
|
||||||
"""Block to simulate multiple discovery calls while one still running."""
|
|
||||||
nonlocal discovery_finished
|
|
||||||
if discovery_finished:
|
|
||||||
first_discovery_started.set()
|
|
||||||
await discovery_finished.wait()
|
|
||||||
return []
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.kulersky.light.pykulersky.discover_bluetooth_devices",
|
|
||||||
return_value=[],
|
|
||||||
), patch(
|
|
||||||
"homeassistant.components.kulersky.light.async_track_time_interval",
|
|
||||||
) as mock_track_time_interval:
|
|
||||||
mock_entry.add_to_hass(hass)
|
|
||||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with patch.object(
|
|
||||||
hass, "async_add_executor_job", side_effect=mock_discovery
|
|
||||||
) as mock_run_discovery:
|
|
||||||
discovery_coroutine = mock_track_time_interval.call_args[0][1]
|
|
||||||
|
|
||||||
discovery_finished = asyncio.Event()
|
|
||||||
|
|
||||||
# Schedule multiple discoveries
|
|
||||||
hass.async_create_task(discovery_coroutine())
|
|
||||||
hass.async_create_task(discovery_coroutine())
|
|
||||||
hass.async_create_task(discovery_coroutine())
|
|
||||||
|
|
||||||
# Wait until the first discovery call is blocked
|
|
||||||
await first_discovery_started.wait()
|
|
||||||
|
|
||||||
# Unblock the first discovery
|
|
||||||
discovery_finished.set()
|
|
||||||
|
|
||||||
# Flush the remaining jobs
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
# The discovery method should only have been called once
|
|
||||||
mock_run_discovery.assert_called_once()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_discovery_connection_error(hass, mock_entry):
|
|
||||||
"""Test that invalid devices are skipped."""
|
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
light = MagicMock(spec=pykulersky.Light)
|
|
||||||
light.address = "AA:BB:CC:11:22:33"
|
|
||||||
light.name = "Bedroom"
|
|
||||||
light.connected = False
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.kulersky.light.pykulersky.discover_bluetooth_devices",
|
|
||||||
return_value=[
|
|
||||||
{
|
|
||||||
"address": "AA:BB:CC:11:22:33",
|
|
||||||
"name": "Bedroom",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
):
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.kulersky.light.pykulersky.Light"
|
|
||||||
) as mockdevice, patch.object(
|
|
||||||
light, "connect", side_effect=pykulersky.PykulerskyException
|
|
||||||
):
|
|
||||||
mockdevice.return_value = light
|
|
||||||
mock_entry.add_to_hass(hass)
|
|
||||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
# Assert entity was not added
|
|
||||||
state = hass.states.get("light.bedroom")
|
|
||||||
assert state is None
|
|
||||||
|
|
||||||
|
|
||||||
async def test_remove_entry(hass, mock_light, mock_entry):
|
async def test_remove_entry(hass, mock_light, mock_entry):
|
||||||
"""Test platform setup."""
|
"""Test platform setup."""
|
||||||
with patch.object(mock_light, "disconnect") as mock_disconnect:
|
await hass.config_entries.async_remove(mock_entry.entry_id)
|
||||||
await hass.config_entries.async_remove(mock_entry.entry_id)
|
|
||||||
|
|
||||||
assert mock_disconnect.called
|
assert mock_light.disconnect.called
|
||||||
|
|
||||||
|
|
||||||
|
async def test_remove_entry_exceptions_caught(hass, mock_light, mock_entry):
|
||||||
|
"""Assert that disconnect exceptions are caught."""
|
||||||
|
mock_light.disconnect.side_effect = pykulersky.PykulerskyException("Mock error")
|
||||||
|
await hass.config_entries.async_remove(mock_entry.entry_id)
|
||||||
|
|
||||||
|
assert mock_light.disconnect.called
|
||||||
|
|
||||||
|
|
||||||
async def test_update_exception(hass, mock_light):
|
async def test_update_exception(hass, mock_light):
|
||||||
"""Test platform setup."""
|
"""Test platform setup."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||||
|
|
||||||
with patch.object(
|
mock_light.get_color.side_effect = pykulersky.PykulerskyException
|
||||||
mock_light, "get_color", side_effect=pykulersky.PykulerskyException
|
await hass.helpers.entity_component.async_update_entity("light.bedroom")
|
||||||
):
|
|
||||||
await hass.helpers.entity_component.async_update_entity("light.bedroom")
|
|
||||||
state = hass.states.get("light.bedroom")
|
state = hass.states.get("light.bedroom")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_UNAVAILABLE
|
assert state.state == STATE_UNAVAILABLE
|
||||||
@ -196,69 +105,59 @@ async def test_update_exception(hass, mock_light):
|
|||||||
|
|
||||||
async def test_light_turn_on(hass, mock_light):
|
async def test_light_turn_on(hass, mock_light):
|
||||||
"""Test KulerSkyLight turn_on."""
|
"""Test KulerSkyLight turn_on."""
|
||||||
with patch.object(mock_light, "set_color") as mock_set_color, patch.object(
|
mock_light.get_color.return_value = (255, 255, 255, 255)
|
||||||
mock_light, "get_color", return_value=(255, 255, 255, 255)
|
await hass.services.async_call(
|
||||||
):
|
"light",
|
||||||
await hass.services.async_call(
|
"turn_on",
|
||||||
"light",
|
{ATTR_ENTITY_ID: "light.bedroom"},
|
||||||
"turn_on",
|
blocking=True,
|
||||||
{ATTR_ENTITY_ID: "light.bedroom"},
|
)
|
||||||
blocking=True,
|
await hass.async_block_till_done()
|
||||||
)
|
mock_light.set_color.assert_called_with(255, 255, 255, 255)
|
||||||
await hass.async_block_till_done()
|
|
||||||
mock_set_color.assert_called_with(255, 255, 255, 255)
|
|
||||||
|
|
||||||
with patch.object(mock_light, "set_color") as mock_set_color, patch.object(
|
mock_light.get_color.return_value = (50, 50, 50, 255)
|
||||||
mock_light, "get_color", return_value=(50, 50, 50, 255)
|
await hass.services.async_call(
|
||||||
):
|
"light",
|
||||||
await hass.services.async_call(
|
"turn_on",
|
||||||
"light",
|
{ATTR_ENTITY_ID: "light.bedroom", ATTR_BRIGHTNESS: 50},
|
||||||
"turn_on",
|
blocking=True,
|
||||||
{ATTR_ENTITY_ID: "light.bedroom", ATTR_BRIGHTNESS: 50},
|
)
|
||||||
blocking=True,
|
await hass.async_block_till_done()
|
||||||
)
|
mock_light.set_color.assert_called_with(50, 50, 50, 255)
|
||||||
await hass.async_block_till_done()
|
|
||||||
mock_set_color.assert_called_with(50, 50, 50, 255)
|
|
||||||
|
|
||||||
with patch.object(mock_light, "set_color") as mock_set_color, patch.object(
|
mock_light.get_color.return_value = (50, 45, 25, 255)
|
||||||
mock_light, "get_color", return_value=(50, 45, 25, 255)
|
await hass.services.async_call(
|
||||||
):
|
"light",
|
||||||
await hass.services.async_call(
|
"turn_on",
|
||||||
"light",
|
{ATTR_ENTITY_ID: "light.bedroom", ATTR_HS_COLOR: (50, 50)},
|
||||||
"turn_on",
|
blocking=True,
|
||||||
{ATTR_ENTITY_ID: "light.bedroom", ATTR_HS_COLOR: (50, 50)},
|
)
|
||||||
blocking=True,
|
await hass.async_block_till_done()
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
mock_set_color.assert_called_with(50, 45, 25, 255)
|
mock_light.set_color.assert_called_with(50, 45, 25, 255)
|
||||||
|
|
||||||
with patch.object(mock_light, "set_color") as mock_set_color, patch.object(
|
mock_light.get_color.return_value = (220, 201, 110, 180)
|
||||||
mock_light, "get_color", return_value=(220, 201, 110, 180)
|
await hass.services.async_call(
|
||||||
):
|
"light",
|
||||||
await hass.services.async_call(
|
"turn_on",
|
||||||
"light",
|
{ATTR_ENTITY_ID: "light.bedroom", ATTR_WHITE_VALUE: 180},
|
||||||
"turn_on",
|
blocking=True,
|
||||||
{ATTR_ENTITY_ID: "light.bedroom", ATTR_WHITE_VALUE: 180},
|
)
|
||||||
blocking=True,
|
await hass.async_block_till_done()
|
||||||
)
|
mock_light.set_color.assert_called_with(50, 45, 25, 180)
|
||||||
await hass.async_block_till_done()
|
|
||||||
mock_set_color.assert_called_with(50, 45, 25, 180)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_light_turn_off(hass, mock_light):
|
async def test_light_turn_off(hass, mock_light):
|
||||||
"""Test KulerSkyLight turn_on."""
|
"""Test KulerSkyLight turn_on."""
|
||||||
with patch.object(mock_light, "set_color") as mock_set_color, patch.object(
|
mock_light.get_color.return_value = (0, 0, 0, 0)
|
||||||
mock_light, "get_color", return_value=(0, 0, 0, 0)
|
await hass.services.async_call(
|
||||||
):
|
"light",
|
||||||
await hass.services.async_call(
|
"turn_off",
|
||||||
"light",
|
{ATTR_ENTITY_ID: "light.bedroom"},
|
||||||
"turn_off",
|
blocking=True,
|
||||||
{ATTR_ENTITY_ID: "light.bedroom"},
|
)
|
||||||
blocking=True,
|
await hass.async_block_till_done()
|
||||||
)
|
mock_light.set_color.assert_called_with(0, 0, 0, 0)
|
||||||
await hass.async_block_till_done()
|
|
||||||
mock_set_color.assert_called_with(0, 0, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_light_update(hass, mock_light):
|
async def test_light_update(hass, mock_light):
|
||||||
@ -275,12 +174,10 @@ async def test_light_update(hass, mock_light):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Test an exception during discovery
|
# Test an exception during discovery
|
||||||
with patch.object(
|
mock_light.get_color.side_effect = pykulersky.PykulerskyException("TEST")
|
||||||
mock_light, "get_color", side_effect=pykulersky.PykulerskyException("TEST")
|
utcnow = utcnow + SCAN_INTERVAL
|
||||||
):
|
async_fire_time_changed(hass, utcnow)
|
||||||
utcnow = utcnow + SCAN_INTERVAL
|
await hass.async_block_till_done()
|
||||||
async_fire_time_changed(hass, utcnow)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
state = hass.states.get("light.bedroom")
|
state = hass.states.get("light.bedroom")
|
||||||
assert state.state == STATE_UNAVAILABLE
|
assert state.state == STATE_UNAVAILABLE
|
||||||
@ -291,14 +188,11 @@ async def test_light_update(hass, mock_light):
|
|||||||
| SUPPORT_WHITE_VALUE,
|
| SUPPORT_WHITE_VALUE,
|
||||||
}
|
}
|
||||||
|
|
||||||
with patch.object(
|
mock_light.get_color.side_effect = None
|
||||||
mock_light,
|
mock_light.get_color.return_value = (80, 160, 200, 240)
|
||||||
"get_color",
|
utcnow = utcnow + SCAN_INTERVAL
|
||||||
return_value=(80, 160, 200, 240),
|
async_fire_time_changed(hass, utcnow)
|
||||||
):
|
await hass.async_block_till_done()
|
||||||
utcnow = utcnow + SCAN_INTERVAL
|
|
||||||
async_fire_time_changed(hass, utcnow)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
state = hass.states.get("light.bedroom")
|
state = hass.states.get("light.bedroom")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
Loading…
x
Reference in New Issue
Block a user