mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add timeout / debounce (for brightness and others) (#13534)
* Add async timeout feature * Decorator for setter methods to limit service calls to HA * Changed to async * Use async_call_later * Use lastargs, async_add_job * Use dict for lastargs * Updated tests to stop patch
This commit is contained in:
parent
c77d013f43
commit
262ea14e5a
@ -1,21 +1,64 @@
|
|||||||
"""Extend the basic Accessory and Bridge functions."""
|
"""Extend the basic Accessory and Bridge functions."""
|
||||||
|
from datetime import timedelta
|
||||||
|
from functools import wraps
|
||||||
|
from inspect import getmodule
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyhap.accessory import Accessory, Bridge, Category
|
from pyhap.accessory import Accessory, Bridge, Category
|
||||||
from pyhap.accessory_driver import AccessoryDriver
|
from pyhap.accessory_driver import AccessoryDriver
|
||||||
|
|
||||||
from homeassistant.helpers.event import async_track_state_change
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers.event import (
|
||||||
|
async_track_state_change, track_point_in_utc_time)
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ACCESSORY_MODEL, ACCESSORY_NAME, BRIDGE_MODEL, BRIDGE_NAME,
|
DEBOUNCE_TIMEOUT, ACCESSORY_MODEL, ACCESSORY_NAME, BRIDGE_MODEL,
|
||||||
MANUFACTURER, SERV_ACCESSORY_INFO, CHAR_MANUFACTURER, CHAR_MODEL,
|
BRIDGE_NAME, MANUFACTURER, SERV_ACCESSORY_INFO, CHAR_MANUFACTURER,
|
||||||
CHAR_NAME, CHAR_SERIAL_NUMBER)
|
CHAR_MODEL, CHAR_NAME, CHAR_SERIAL_NUMBER)
|
||||||
from .util import (
|
from .util import (
|
||||||
show_setup_message, dismiss_setup_message)
|
show_setup_message, dismiss_setup_message)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def debounce(func):
|
||||||
|
"""Decorator function. Debounce callbacks form HomeKit."""
|
||||||
|
@callback
|
||||||
|
def call_later_listener(*args):
|
||||||
|
"""Callback listener called from call_later."""
|
||||||
|
# pylint: disable=unsubscriptable-object
|
||||||
|
nonlocal lastargs, remove_listener
|
||||||
|
hass = lastargs['hass']
|
||||||
|
hass.async_add_job(func, *lastargs['args'])
|
||||||
|
lastargs = remove_listener = None
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args):
|
||||||
|
"""Wrapper starts async timer.
|
||||||
|
|
||||||
|
The accessory must have 'self.hass' and 'self.entity_id' as attributes.
|
||||||
|
"""
|
||||||
|
# pylint: disable=not-callable
|
||||||
|
hass = args[0].hass
|
||||||
|
nonlocal lastargs, remove_listener
|
||||||
|
if remove_listener:
|
||||||
|
remove_listener()
|
||||||
|
lastargs = remove_listener = None
|
||||||
|
lastargs = {'hass': hass, 'args': [*args]}
|
||||||
|
remove_listener = track_point_in_utc_time(
|
||||||
|
hass, call_later_listener,
|
||||||
|
dt_util.utcnow() + timedelta(seconds=DEBOUNCE_TIMEOUT))
|
||||||
|
logger.debug('%s: Start %s timeout', args[0].entity_id,
|
||||||
|
func.__name__.replace('set_', ''))
|
||||||
|
|
||||||
|
remove_listener = None
|
||||||
|
lastargs = None
|
||||||
|
name = getmodule(func).__name__
|
||||||
|
logger = logging.getLogger(name)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def add_preload_service(acc, service, chars=None):
|
def add_preload_service(acc, service, chars=None):
|
||||||
"""Define and return a service to be available for the accessory."""
|
"""Define and return a service to be available for the accessory."""
|
||||||
from pyhap.loader import get_serv_loader, get_char_loader
|
from pyhap.loader import get_serv_loader, get_char_loader
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Constants used be the HomeKit component."""
|
"""Constants used be the HomeKit component."""
|
||||||
# #### MISC ####
|
# #### MISC ####
|
||||||
|
DEBOUNCE_TIMEOUT = 0.5
|
||||||
DOMAIN = 'homekit'
|
DOMAIN = 'homekit'
|
||||||
HOMEKIT_FILE = '.homekit.state'
|
HOMEKIT_FILE = '.homekit.state'
|
||||||
HOMEKIT_NOTIFY_ID = 4663548
|
HOMEKIT_NOTIFY_ID = 4663548
|
||||||
|
@ -7,7 +7,7 @@ from homeassistant.components.light import (
|
|||||||
from homeassistant.const import ATTR_SUPPORTED_FEATURES, STATE_ON, STATE_OFF
|
from homeassistant.const import ATTR_SUPPORTED_FEATURES, STATE_ON, STATE_OFF
|
||||||
|
|
||||||
from . import TYPES
|
from . import TYPES
|
||||||
from .accessories import HomeAccessory, add_preload_service
|
from .accessories import HomeAccessory, add_preload_service, debounce
|
||||||
from .const import (
|
from .const import (
|
||||||
CATEGORY_LIGHT, SERV_LIGHTBULB, CHAR_COLOR_TEMPERATURE,
|
CATEGORY_LIGHT, SERV_LIGHTBULB, CHAR_COLOR_TEMPERATURE,
|
||||||
CHAR_BRIGHTNESS, CHAR_HUE, CHAR_ON, CHAR_SATURATION)
|
CHAR_BRIGHTNESS, CHAR_HUE, CHAR_ON, CHAR_SATURATION)
|
||||||
@ -93,6 +93,7 @@ class Light(HomeAccessory):
|
|||||||
elif value == 0:
|
elif value == 0:
|
||||||
self.hass.components.light.turn_off(self.entity_id)
|
self.hass.components.light.turn_off(self.entity_id)
|
||||||
|
|
||||||
|
@debounce
|
||||||
def set_brightness(self, value):
|
def set_brightness(self, value):
|
||||||
"""Set brightness if call came from HomeKit."""
|
"""Set brightness if call came from HomeKit."""
|
||||||
_LOGGER.debug('%s: Set brightness to %d', self.entity_id, value)
|
_LOGGER.debug('%s: Set brightness to %d', self.entity_id, value)
|
||||||
|
@ -10,7 +10,7 @@ from homeassistant.const import (
|
|||||||
ATTR_UNIT_OF_MEASUREMENT, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
ATTR_UNIT_OF_MEASUREMENT, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||||
|
|
||||||
from . import TYPES
|
from . import TYPES
|
||||||
from .accessories import HomeAccessory, add_preload_service
|
from .accessories import HomeAccessory, add_preload_service, debounce
|
||||||
from .const import (
|
from .const import (
|
||||||
CATEGORY_THERMOSTAT, SERV_THERMOSTAT, CHAR_CURRENT_HEATING_COOLING,
|
CATEGORY_THERMOSTAT, SERV_THERMOSTAT, CHAR_CURRENT_HEATING_COOLING,
|
||||||
CHAR_TARGET_HEATING_COOLING, CHAR_CURRENT_TEMPERATURE,
|
CHAR_TARGET_HEATING_COOLING, CHAR_CURRENT_TEMPERATURE,
|
||||||
@ -104,6 +104,7 @@ class Thermostat(HomeAccessory):
|
|||||||
self.hass.components.climate.set_operation_mode(
|
self.hass.components.climate.set_operation_mode(
|
||||||
operation_mode=hass_value, entity_id=self.entity_id)
|
operation_mode=hass_value, entity_id=self.entity_id)
|
||||||
|
|
||||||
|
@debounce
|
||||||
def set_cooling_threshold(self, value):
|
def set_cooling_threshold(self, value):
|
||||||
"""Set cooling threshold temp to value if call came from HomeKit."""
|
"""Set cooling threshold temp to value if call came from HomeKit."""
|
||||||
_LOGGER.debug('%s: Set cooling threshold temperature to %.2f°C',
|
_LOGGER.debug('%s: Set cooling threshold temperature to %.2f°C',
|
||||||
@ -116,6 +117,7 @@ class Thermostat(HomeAccessory):
|
|||||||
entity_id=self.entity_id, target_temp_high=value,
|
entity_id=self.entity_id, target_temp_high=value,
|
||||||
target_temp_low=low)
|
target_temp_low=low)
|
||||||
|
|
||||||
|
@debounce
|
||||||
def set_heating_threshold(self, value):
|
def set_heating_threshold(self, value):
|
||||||
"""Set heating threshold temp to value if call came from HomeKit."""
|
"""Set heating threshold temp to value if call came from HomeKit."""
|
||||||
_LOGGER.debug('%s: Set heating threshold temperature to %.2f°C',
|
_LOGGER.debug('%s: Set heating threshold temperature to %.2f°C',
|
||||||
@ -129,6 +131,7 @@ class Thermostat(HomeAccessory):
|
|||||||
entity_id=self.entity_id, target_temp_high=high,
|
entity_id=self.entity_id, target_temp_high=high,
|
||||||
target_temp_low=value)
|
target_temp_low=value)
|
||||||
|
|
||||||
|
@debounce
|
||||||
def set_target_temperature(self, value):
|
def set_target_temperature(self, value):
|
||||||
"""Set target temperature to value if call came from HomeKit."""
|
"""Set target temperature to value if call came from HomeKit."""
|
||||||
_LOGGER.debug('%s: Set target temperature to %.2f°C',
|
_LOGGER.debug('%s: Set target temperature to %.2f°C',
|
||||||
|
@ -2,21 +2,67 @@
|
|||||||
|
|
||||||
This includes tests for all mock object types.
|
This includes tests for all mock object types.
|
||||||
"""
|
"""
|
||||||
|
from datetime import datetime, timedelta
|
||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import call, patch, Mock
|
from unittest.mock import call, patch, Mock
|
||||||
|
|
||||||
from homeassistant.components.homekit.accessories import (
|
from homeassistant.components.homekit.accessories import (
|
||||||
add_preload_service, set_accessory_info,
|
add_preload_service, set_accessory_info,
|
||||||
HomeAccessory, HomeBridge, HomeDriver)
|
debounce, HomeAccessory, HomeBridge, HomeDriver)
|
||||||
from homeassistant.components.homekit.const import (
|
from homeassistant.components.homekit.const import (
|
||||||
ACCESSORY_MODEL, ACCESSORY_NAME, BRIDGE_MODEL, BRIDGE_NAME,
|
ACCESSORY_MODEL, ACCESSORY_NAME, BRIDGE_MODEL, BRIDGE_NAME,
|
||||||
SERV_ACCESSORY_INFO, CHAR_MANUFACTURER, CHAR_MODEL,
|
SERV_ACCESSORY_INFO, CHAR_MANUFACTURER, CHAR_MODEL,
|
||||||
CHAR_NAME, CHAR_SERIAL_NUMBER)
|
CHAR_NAME, CHAR_SERIAL_NUMBER)
|
||||||
|
from homeassistant.const import ATTR_NOW, EVENT_TIME_CHANGED
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from tests.common import get_test_home_assistant
|
||||||
|
|
||||||
|
|
||||||
|
def patch_debounce():
|
||||||
|
"""Return patch for debounce method."""
|
||||||
|
return patch('homeassistant.components.homekit.accessories.debounce',
|
||||||
|
lambda f: lambda *args, **kwargs: f(*args, **kwargs))
|
||||||
|
|
||||||
|
|
||||||
class TestAccessories(unittest.TestCase):
|
class TestAccessories(unittest.TestCase):
|
||||||
"""Test pyhap adapter methods."""
|
"""Test pyhap adapter methods."""
|
||||||
|
|
||||||
|
def test_debounce(self):
|
||||||
|
"""Test add_timeout decorator function."""
|
||||||
|
def demo_func(*args):
|
||||||
|
nonlocal arguments, counter
|
||||||
|
counter += 1
|
||||||
|
arguments = args
|
||||||
|
|
||||||
|
arguments = None
|
||||||
|
counter = 0
|
||||||
|
hass = get_test_home_assistant()
|
||||||
|
mock = Mock(hass=hass)
|
||||||
|
|
||||||
|
debounce_demo = debounce(demo_func)
|
||||||
|
self.assertEqual(debounce_demo.__name__, 'demo_func')
|
||||||
|
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC)
|
||||||
|
|
||||||
|
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||||
|
debounce_demo(mock, 'value')
|
||||||
|
hass.bus.fire(
|
||||||
|
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
||||||
|
hass.block_till_done()
|
||||||
|
assert counter == 1
|
||||||
|
assert len(arguments) == 2
|
||||||
|
|
||||||
|
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||||
|
debounce_demo(mock, 'value')
|
||||||
|
debounce_demo(mock, 'value')
|
||||||
|
|
||||||
|
hass.bus.fire(
|
||||||
|
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
||||||
|
hass.block_till_done()
|
||||||
|
assert counter == 2
|
||||||
|
|
||||||
|
hass.stop()
|
||||||
|
|
||||||
def test_add_preload_service(self):
|
def test_add_preload_service(self):
|
||||||
"""Test add_preload_service without additional characteristics."""
|
"""Test add_preload_service without additional characteristics."""
|
||||||
acc = Mock()
|
acc = Mock()
|
||||||
|
@ -14,6 +14,7 @@ from homeassistant.const import (
|
|||||||
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
|
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant
|
from tests.common import get_test_home_assistant
|
||||||
|
from tests.components.homekit.test_accessories import patch_debounce
|
||||||
|
|
||||||
IP_ADDRESS = '127.0.0.1'
|
IP_ADDRESS = '127.0.0.1'
|
||||||
PATH_HOMEKIT = 'homeassistant.components.homekit'
|
PATH_HOMEKIT = 'homeassistant.components.homekit'
|
||||||
@ -22,6 +23,17 @@ PATH_HOMEKIT = 'homeassistant.components.homekit'
|
|||||||
class TestHomeKit(unittest.TestCase):
|
class TestHomeKit(unittest.TestCase):
|
||||||
"""Test setup of HomeKit component and HomeKit class."""
|
"""Test setup of HomeKit component and HomeKit class."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""Setup debounce patcher."""
|
||||||
|
cls.patcher = patch_debounce()
|
||||||
|
cls.patcher.start()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""Stop debounce patcher."""
|
||||||
|
cls.patcher.stop()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Setup things to be run when tests are started."""
|
"""Setup things to be run when tests are started."""
|
||||||
self.hass = get_test_home_assistant()
|
self.hass = get_test_home_assistant()
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.components.homekit.type_lights import Light
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
DOMAIN, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_TEMP,
|
DOMAIN, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_TEMP,
|
||||||
ATTR_HS_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR)
|
ATTR_HS_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR)
|
||||||
@ -12,11 +11,26 @@ from homeassistant.const import (
|
|||||||
SERVICE_TURN_OFF, STATE_ON, STATE_OFF, STATE_UNKNOWN)
|
SERVICE_TURN_OFF, STATE_ON, STATE_OFF, STATE_UNKNOWN)
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant
|
from tests.common import get_test_home_assistant
|
||||||
|
from tests.components.homekit.test_accessories import patch_debounce
|
||||||
|
|
||||||
|
|
||||||
class TestHomekitLights(unittest.TestCase):
|
class TestHomekitLights(unittest.TestCase):
|
||||||
"""Test class for all accessory types regarding lights."""
|
"""Test class for all accessory types regarding lights."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""Setup Light class import and debounce patcher."""
|
||||||
|
cls.patcher = patch_debounce()
|
||||||
|
cls.patcher.start()
|
||||||
|
_import = __import__('homeassistant.components.homekit.type_lights',
|
||||||
|
fromlist=['Light'])
|
||||||
|
cls.light_cls = _import.Light
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""Stop debounce patcher."""
|
||||||
|
cls.patcher.stop()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Setup things to be run when tests are started."""
|
"""Setup things to be run when tests are started."""
|
||||||
self.hass = get_test_home_assistant()
|
self.hass = get_test_home_assistant()
|
||||||
@ -38,7 +52,7 @@ class TestHomekitLights(unittest.TestCase):
|
|||||||
entity_id = 'light.demo'
|
entity_id = 'light.demo'
|
||||||
self.hass.states.set(entity_id, STATE_ON,
|
self.hass.states.set(entity_id, STATE_ON,
|
||||||
{ATTR_SUPPORTED_FEATURES: 0})
|
{ATTR_SUPPORTED_FEATURES: 0})
|
||||||
acc = Light(self.hass, entity_id, 'Light', aid=2)
|
acc = self.light_cls(self.hass, entity_id, 'Light', aid=2)
|
||||||
self.assertEqual(acc.aid, 2)
|
self.assertEqual(acc.aid, 2)
|
||||||
self.assertEqual(acc.category, 5) # Lightbulb
|
self.assertEqual(acc.category, 5) # Lightbulb
|
||||||
self.assertEqual(acc.char_on.value, 0)
|
self.assertEqual(acc.char_on.value, 0)
|
||||||
@ -82,7 +96,7 @@ class TestHomekitLights(unittest.TestCase):
|
|||||||
entity_id = 'light.demo'
|
entity_id = 'light.demo'
|
||||||
self.hass.states.set(entity_id, STATE_ON, {
|
self.hass.states.set(entity_id, STATE_ON, {
|
||||||
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
|
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
|
||||||
acc = Light(self.hass, entity_id, 'Light', aid=2)
|
acc = self.light_cls(self.hass, entity_id, 'Light', aid=2)
|
||||||
self.assertEqual(acc.char_brightness.value, 0)
|
self.assertEqual(acc.char_brightness.value, 0)
|
||||||
|
|
||||||
acc.run()
|
acc.run()
|
||||||
@ -124,7 +138,7 @@ class TestHomekitLights(unittest.TestCase):
|
|||||||
self.hass.states.set(entity_id, STATE_ON, {
|
self.hass.states.set(entity_id, STATE_ON, {
|
||||||
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR_TEMP,
|
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR_TEMP,
|
||||||
ATTR_COLOR_TEMP: 190})
|
ATTR_COLOR_TEMP: 190})
|
||||||
acc = Light(self.hass, entity_id, 'Light', aid=2)
|
acc = self.light_cls(self.hass, entity_id, 'Light', aid=2)
|
||||||
self.assertEqual(acc.char_color_temperature.value, 153)
|
self.assertEqual(acc.char_color_temperature.value, 153)
|
||||||
|
|
||||||
acc.run()
|
acc.run()
|
||||||
@ -146,7 +160,7 @@ class TestHomekitLights(unittest.TestCase):
|
|||||||
self.hass.states.set(entity_id, STATE_ON, {
|
self.hass.states.set(entity_id, STATE_ON, {
|
||||||
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR,
|
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR,
|
||||||
ATTR_HS_COLOR: (260, 90)})
|
ATTR_HS_COLOR: (260, 90)})
|
||||||
acc = Light(self.hass, entity_id, 'Light', aid=2)
|
acc = self.light_cls(self.hass, entity_id, 'Light', aid=2)
|
||||||
self.assertEqual(acc.char_hue.value, 0)
|
self.assertEqual(acc.char_hue.value, 0)
|
||||||
self.assertEqual(acc.char_saturation.value, 75)
|
self.assertEqual(acc.char_saturation.value, 75)
|
||||||
|
|
||||||
|
@ -6,17 +6,32 @@ from homeassistant.components.climate import (
|
|||||||
ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE,
|
ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE,
|
||||||
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH, ATTR_OPERATION_MODE,
|
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH, ATTR_OPERATION_MODE,
|
||||||
ATTR_OPERATION_LIST, STATE_COOL, STATE_HEAT, STATE_AUTO)
|
ATTR_OPERATION_LIST, STATE_COOL, STATE_HEAT, STATE_AUTO)
|
||||||
from homeassistant.components.homekit.type_thermostats import Thermostat
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_SERVICE, EVENT_CALL_SERVICE, ATTR_SERVICE_DATA,
|
ATTR_SERVICE, EVENT_CALL_SERVICE, ATTR_SERVICE_DATA,
|
||||||
ATTR_UNIT_OF_MEASUREMENT, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
ATTR_UNIT_OF_MEASUREMENT, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant
|
from tests.common import get_test_home_assistant
|
||||||
|
from tests.components.homekit.test_accessories import patch_debounce
|
||||||
|
|
||||||
|
|
||||||
class TestHomekitThermostats(unittest.TestCase):
|
class TestHomekitThermostats(unittest.TestCase):
|
||||||
"""Test class for all accessory types regarding thermostats."""
|
"""Test class for all accessory types regarding thermostats."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""Setup Thermostat class import and debounce patcher."""
|
||||||
|
cls.patcher = patch_debounce()
|
||||||
|
cls.patcher.start()
|
||||||
|
_import = __import__(
|
||||||
|
'homeassistant.components.homekit.type_thermostats',
|
||||||
|
fromlist=['Thermostat'])
|
||||||
|
cls.thermostat_cls = _import.Thermostat
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""Stop debounce patcher."""
|
||||||
|
cls.patcher.stop()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Setup things to be run when tests are started."""
|
"""Setup things to be run when tests are started."""
|
||||||
self.hass = get_test_home_assistant()
|
self.hass = get_test_home_assistant()
|
||||||
@ -37,7 +52,7 @@ class TestHomekitThermostats(unittest.TestCase):
|
|||||||
"""Test if accessory and HA are updated accordingly."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
climate = 'climate.test'
|
climate = 'climate.test'
|
||||||
|
|
||||||
acc = Thermostat(self.hass, climate, 'Climate', False, aid=2)
|
acc = self.thermostat_cls(self.hass, climate, 'Climate', False, aid=2)
|
||||||
acc.run()
|
acc.run()
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
self.assertEqual(acc.aid, 2)
|
||||||
@ -172,7 +187,7 @@ class TestHomekitThermostats(unittest.TestCase):
|
|||||||
"""Test if accessory and HA are updated accordingly."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
climate = 'climate.test'
|
climate = 'climate.test'
|
||||||
|
|
||||||
acc = Thermostat(self.hass, climate, 'Climate', True)
|
acc = self.thermostat_cls(self.hass, climate, 'Climate', True)
|
||||||
acc.run()
|
acc.run()
|
||||||
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0)
|
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0)
|
||||||
@ -242,7 +257,7 @@ class TestHomekitThermostats(unittest.TestCase):
|
|||||||
"""Test if accessory and HA are updated accordingly."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
climate = 'climate.test'
|
climate = 'climate.test'
|
||||||
|
|
||||||
acc = Thermostat(self.hass, climate, 'Climate', True)
|
acc = self.thermostat_cls(self.hass, climate, 'Climate', True)
|
||||||
acc.run()
|
acc.run()
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
self.hass.states.set(climate, STATE_AUTO,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user