More async tests (#4223)
* Annotate test callbacks to be async * Convert device_sun_light_trigger to be asyncpull/4236/head
parent
22c3d014aa
commit
62785c2431
|
@ -9,6 +9,7 @@ from datetime import timedelta
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.const import STATE_HOME, STATE_NOT_HOME
|
||||
from homeassistant.helpers.event import track_point_in_time
|
||||
|
@ -79,21 +80,22 @@ def setup(hass, config):
|
|||
return None
|
||||
return next_setting - LIGHT_TRANSITION_TIME * len(light_ids)
|
||||
|
||||
def turn_light_on_before_sunset(light_id):
|
||||
def async_turn_on_before_sunset(light_id):
|
||||
"""Helper function to turn on lights.
|
||||
|
||||
Speed is slow if there are devices home and the light is not on yet.
|
||||
"""
|
||||
if not device_tracker.is_on(hass) or light.is_on(hass, light_id):
|
||||
return
|
||||
light.turn_on(hass, light_id,
|
||||
transition=LIGHT_TRANSITION_TIME.seconds,
|
||||
profile=light_profile)
|
||||
light.async_turn_on(hass, light_id,
|
||||
transition=LIGHT_TRANSITION_TIME.seconds,
|
||||
profile=light_profile)
|
||||
|
||||
# Track every time sun rises so we can schedule a time-based
|
||||
# pre-sun set event
|
||||
@track_state_change(sun.ENTITY_ID, sun.STATE_BELOW_HORIZON,
|
||||
sun.STATE_ABOVE_HORIZON)
|
||||
@callback
|
||||
def schedule_lights_at_sun_set(hass, entity, old_state, new_state):
|
||||
"""The moment sun sets we want to have all the lights on.
|
||||
|
||||
|
@ -104,16 +106,21 @@ def setup(hass, config):
|
|||
if not start_point:
|
||||
return
|
||||
|
||||
def turn_on(light_id):
|
||||
def async_turn_on_factory(light_id):
|
||||
"""Lambda can keep track of function parameters.
|
||||
|
||||
No local parameters. If we put the lambda directly in the below
|
||||
statement only the last light will be turned on.
|
||||
"""
|
||||
return lambda now: turn_light_on_before_sunset(light_id)
|
||||
@callback
|
||||
def async_turn_on_light(now):
|
||||
"""Turn on specific light."""
|
||||
async_turn_on_before_sunset(light_id)
|
||||
|
||||
return async_turn_on_light
|
||||
|
||||
for index, light_id in enumerate(light_ids):
|
||||
track_point_in_time(hass, turn_on(light_id),
|
||||
track_point_in_time(hass, async_turn_on_factory(light_id),
|
||||
start_point + index * LIGHT_TRANSITION_TIME)
|
||||
|
||||
# If the sun is already above horizon schedule the time-based pre-sun set
|
||||
|
@ -122,6 +129,7 @@ def setup(hass, config):
|
|||
schedule_lights_at_sun_set(hass, None, None, None)
|
||||
|
||||
@track_state_change(device_entity_ids, STATE_NOT_HOME, STATE_HOME)
|
||||
@callback
|
||||
def check_light_on_dev_state_change(hass, entity, old_state, new_state):
|
||||
"""Handle tracked device state changes."""
|
||||
# pylint: disable=unused-variable
|
||||
|
@ -136,7 +144,7 @@ def setup(hass, config):
|
|||
# Do we need lights?
|
||||
if light_needed:
|
||||
logger.info("Home coming event for %s. Turning lights on", entity)
|
||||
light.turn_on(hass, light_ids, profile=light_profile)
|
||||
light.async_turn_on(hass, light_ids, profile=light_profile)
|
||||
|
||||
# Are we in the time span were we would turn on the lights
|
||||
# if someone would be home?
|
||||
|
@ -149,7 +157,7 @@ def setup(hass, config):
|
|||
# when the fading in started and turn it on if so
|
||||
for index, light_id in enumerate(light_ids):
|
||||
if now > start_point + index * LIGHT_TRANSITION_TIME:
|
||||
light.turn_on(hass, light_id)
|
||||
light.async_turn_on(hass, light_id)
|
||||
|
||||
else:
|
||||
# If this light didn't happen to be turned on yet so
|
||||
|
@ -158,6 +166,7 @@ def setup(hass, config):
|
|||
|
||||
if not disable_turn_off:
|
||||
@track_state_change(device_group, STATE_HOME, STATE_NOT_HOME)
|
||||
@callback
|
||||
def turn_off_lights_when_all_leave(hass, entity, old_state, new_state):
|
||||
"""Handle device group state change."""
|
||||
# pylint: disable=unused-variable
|
||||
|
@ -166,6 +175,6 @@ def setup(hass, config):
|
|||
|
||||
logger.info(
|
||||
"Everyone has left but there are lights on. Turning them off")
|
||||
light.turn_off(hass, light_ids)
|
||||
light.async_turn_off(hass, light_ids)
|
||||
|
||||
return True
|
||||
|
|
|
@ -10,6 +10,7 @@ import csv
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components import group
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
from homeassistant.const import (
|
||||
|
@ -20,6 +21,7 @@ from homeassistant.helpers.entity_component import EntityComponent
|
|||
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import homeassistant.util.color as color_util
|
||||
from homeassistant.util.async import run_callback_threadsafe
|
||||
|
||||
|
||||
DOMAIN = "light"
|
||||
|
@ -128,6 +130,18 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None,
|
|||
rgb_color=None, xy_color=None, color_temp=None, white_value=None,
|
||||
profile=None, flash=None, effect=None, color_name=None):
|
||||
"""Turn all or specified light on."""
|
||||
run_callback_threadsafe(
|
||||
hass.loop, async_turn_on, hass, entity_id, transition, brightness,
|
||||
rgb_color, xy_color, color_temp, white_value,
|
||||
profile, flash, effect, color_name).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_turn_on(hass, entity_id=None, transition=None, brightness=None,
|
||||
rgb_color=None, xy_color=None, color_temp=None,
|
||||
white_value=None, profile=None, flash=None, effect=None,
|
||||
color_name=None):
|
||||
"""Turn all or specified light on."""
|
||||
data = {
|
||||
key: value for key, value in [
|
||||
(ATTR_ENTITY_ID, entity_id),
|
||||
|
@ -144,10 +158,17 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None,
|
|||
] if value is not None
|
||||
}
|
||||
|
||||
hass.services.call(DOMAIN, SERVICE_TURN_ON, data)
|
||||
hass.async_add_job(hass.services.async_call, DOMAIN, SERVICE_TURN_ON, data)
|
||||
|
||||
|
||||
def turn_off(hass, entity_id=None, transition=None):
|
||||
"""Turn all or specified light off."""
|
||||
run_callback_threadsafe(
|
||||
hass.loop, async_turn_off, hass, entity_id, transition).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_turn_off(hass, entity_id=None, transition=None):
|
||||
"""Turn all or specified light off."""
|
||||
data = {
|
||||
key: value for key, value in [
|
||||
|
@ -156,7 +177,8 @@ def turn_off(hass, entity_id=None, transition=None):
|
|||
] if value is not None
|
||||
}
|
||||
|
||||
hass.services.call(DOMAIN, SERVICE_TURN_OFF, data)
|
||||
hass.async_add_job(hass.services.async_call, DOMAIN, SERVICE_TURN_OFF,
|
||||
data)
|
||||
|
||||
|
||||
def toggle(hass, entity_id=None, transition=None):
|
||||
|
|
|
@ -49,14 +49,20 @@ def is_on(hass, entity_id=None):
|
|||
|
||||
|
||||
def next_setting(hass, entity_id=None):
|
||||
"""Local datetime object of the next sun setting."""
|
||||
"""Local datetime object of the next sun setting.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
utc_next = next_setting_utc(hass, entity_id)
|
||||
|
||||
return dt_util.as_local(utc_next) if utc_next else None
|
||||
|
||||
|
||||
def next_setting_utc(hass, entity_id=None):
|
||||
"""UTC datetime object of the next sun setting."""
|
||||
"""UTC datetime object of the next sun setting.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
entity_id = entity_id or ENTITY_ID
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
|
@ -71,14 +77,20 @@ def next_setting_utc(hass, entity_id=None):
|
|||
|
||||
|
||||
def next_rising(hass, entity_id=None):
|
||||
"""Local datetime object of the next sun rising."""
|
||||
"""Local datetime object of the next sun rising.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
utc_next = next_rising_utc(hass, entity_id)
|
||||
|
||||
return dt_util.as_local(utc_next) if utc_next else None
|
||||
|
||||
|
||||
def next_rising_utc(hass, entity_id=None):
|
||||
"""UTC datetime object of the next sun rising."""
|
||||
"""UTC datetime object of the next sun rising.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
entity_id = entity_id or ENTITY_ID
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
|
|
|
@ -129,8 +129,12 @@ def mock_service(hass, domain, service):
|
|||
"""
|
||||
calls = []
|
||||
|
||||
@ha.callback
|
||||
def mock_service(call):
|
||||
calls.append(call)
|
||||
|
||||
# pylint: disable=unnecessary-lambda
|
||||
hass.services.register(domain, service, lambda call: calls.append(call))
|
||||
hass.services.register(domain, service, mock_service)
|
||||
|
||||
return calls
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the Event automation."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
|
||||
|
@ -16,6 +17,7 @@ class TestAutomationEvent(unittest.TestCase):
|
|||
self.hass.config.components.append('group')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""Helper for recording the call."""
|
||||
self.calls.append(service)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
|
@ -22,6 +23,7 @@ class TestAutomation(unittest.TestCase):
|
|||
self.hass.config.components.append('group')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""Record call."""
|
||||
self.calls.append(service)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT automation."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
from tests.common import (
|
||||
|
@ -17,6 +18,7 @@ class TestAutomationMQTT(unittest.TestCase):
|
|||
mock_mqtt_component(self.hass)
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
self.calls.append(service)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for numeric state automation."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
|
||||
|
@ -16,6 +17,7 @@ class TestAutomationNumericState(unittest.TestCase):
|
|||
self.hass.config.components.append('group')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""Helper to record calls."""
|
||||
self.calls.append(service)
|
||||
|
|
|
@ -3,6 +3,7 @@ import unittest
|
|||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.components.automation as automation
|
||||
|
@ -21,6 +22,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
self.hass.states.set('test.entity', 'hello')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
self.calls.append(service)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from datetime import datetime
|
|||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components import sun
|
||||
import homeassistant.components.automation as automation
|
||||
|
@ -22,6 +23,7 @@ class TestAutomationSun(unittest.TestCase):
|
|||
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
self.calls.append(service)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the Template automation."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
|
||||
|
@ -17,6 +18,7 @@ class TestAutomationTemplate(unittest.TestCase):
|
|||
self.hass.states.set('test.entity', 'hello')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""helper for recording calls."""
|
||||
self.calls.append(service)
|
||||
|
|
|
@ -3,6 +3,7 @@ from datetime import timedelta
|
|||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.components.automation as automation
|
||||
|
@ -20,6 +21,7 @@ class TestAutomationTime(unittest.TestCase):
|
|||
self.hass.config.components.append('group')
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
self.calls.append(service)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the location automation."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components import automation, zone
|
||||
|
||||
|
@ -25,6 +26,7 @@ class TestAutomationZone(unittest.TestCase):
|
|||
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
self.calls.append(service)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import datetime
|
|||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.const import (
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
|
@ -216,6 +216,7 @@ class TestClimateGenericThermostat(unittest.TestCase):
|
|||
self.hass.states.set(ENT_SWITCH, STATE_ON if is_on else STATE_OFF)
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def log_call(call):
|
||||
"""Log service calls."""
|
||||
self.calls.append(call)
|
||||
|
@ -306,6 +307,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase):
|
|||
self.hass.states.set(ENT_SWITCH, STATE_ON if is_on else STATE_OFF)
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def log_call(call):
|
||||
"""Log service calls."""
|
||||
self.calls.append(call)
|
||||
|
@ -397,6 +399,7 @@ class TestClimateGenericThermostatACModeMinCycle(unittest.TestCase):
|
|||
self.hass.states.set(ENT_SWITCH, STATE_ON if is_on else STATE_OFF)
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def log_call(call):
|
||||
"""Log service calls."""
|
||||
self.calls.append(call)
|
||||
|
@ -487,6 +490,7 @@ class TestClimateGenericThermostatMinCycle(unittest.TestCase):
|
|||
self.hass.states.set(ENT_SWITCH, STATE_ON if is_on else STATE_OFF)
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def log_call(call):
|
||||
"""Log service calls."""
|
||||
self.calls.append(call)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""The tests for the Template switch platform."""
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.bootstrap as bootstrap
|
||||
import homeassistant.components as core
|
||||
|
||||
from homeassistant.const import (
|
||||
STATE_ON,
|
||||
STATE_OFF)
|
||||
|
@ -21,6 +21,7 @@ class TestTemplateSwitch:
|
|||
self.hass = get_test_home_assistant()
|
||||
self.calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""Track function calls.."""
|
||||
self.calls.append(service)
|
||||
|
|
|
@ -6,6 +6,7 @@ import unittest
|
|||
|
||||
import requests
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant import bootstrap, const
|
||||
from homeassistant.components import alexa, http
|
||||
|
||||
|
@ -47,7 +48,11 @@ def setUpModule():
|
|||
{http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD,
|
||||
http.CONF_SERVER_PORT: SERVER_PORT}})
|
||||
|
||||
hass.services.register("test", "alexa", lambda call: calls.append(call))
|
||||
@callback
|
||||
def mock_service(call):
|
||||
calls.append(call)
|
||||
|
||||
hass.services.register("test", "alexa", mock_service)
|
||||
|
||||
bootstrap.setup_component(hass, alexa.DOMAIN, {
|
||||
# Key is here to verify we allow other keys in config too
|
||||
|
|
|
@ -288,6 +288,7 @@ class TestAPI(unittest.TestCase):
|
|||
"""Test if the API allows us to call a service."""
|
||||
test_value = []
|
||||
|
||||
@ha.callback
|
||||
def listener(service_call):
|
||||
"""Helper method that will verify that our service got called."""
|
||||
test_value.append(1)
|
||||
|
@ -307,6 +308,7 @@ class TestAPI(unittest.TestCase):
|
|||
"""Test if the API allows us to call a service."""
|
||||
test_value = []
|
||||
|
||||
@ha.callback
|
||||
def listener(service_call):
|
||||
"""Helper method that will verify that our service got called.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.bootstrap import setup_component
|
||||
import homeassistant.components as core_components
|
||||
from homeassistant.components import conversation
|
||||
|
@ -38,6 +39,7 @@ class TestConversation(unittest.TestCase):
|
|||
"""Setup and perform good turn on requests."""
|
||||
calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
calls.append(service)
|
||||
|
||||
|
@ -56,6 +58,7 @@ class TestConversation(unittest.TestCase):
|
|||
"""Setup and perform good turn off requests."""
|
||||
calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
calls.append(service)
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ class TestScriptComponent(unittest.TestCase):
|
|||
"""Test different ways of passing in variables."""
|
||||
calls = []
|
||||
|
||||
@callback
|
||||
def record_call(service):
|
||||
"""Add recorded event to set."""
|
||||
calls.append(service)
|
||||
|
|
|
@ -508,7 +508,12 @@ class TestServiceRegistry(unittest.TestCase):
|
|||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.services = self.hass.services
|
||||
self.services.register("Test_Domain", "TEST_SERVICE", lambda x: None)
|
||||
|
||||
@ha.callback
|
||||
def mock_service(call):
|
||||
pass
|
||||
|
||||
self.services.register("Test_Domain", "TEST_SERVICE", mock_service)
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def tearDown(self):
|
||||
|
@ -535,6 +540,7 @@ class TestServiceRegistry(unittest.TestCase):
|
|||
"""Test call with blocking."""
|
||||
calls = []
|
||||
|
||||
@ha.callback
|
||||
def service_handler(call):
|
||||
"""Service handler."""
|
||||
calls.append(call)
|
||||
|
|
|
@ -116,6 +116,7 @@ class TestRemoteMethods(unittest.TestCase):
|
|||
"""Test Python API fire_event."""
|
||||
test_value = []
|
||||
|
||||
@ha.callback
|
||||
def listener(event):
|
||||
"""Helper method that will verify our event got called."""
|
||||
test_value.append(1)
|
||||
|
@ -200,6 +201,7 @@ class TestRemoteMethods(unittest.TestCase):
|
|||
"""Test Python API services.call."""
|
||||
test_value = []
|
||||
|
||||
@ha.callback
|
||||
def listener(service_call):
|
||||
"""Helper method that will verify that our service got called."""
|
||||
test_value.append(1)
|
||||
|
|
Loading…
Reference in New Issue