Rewritten HomeKit tests (#14377)

* Use pytest fixtures and parametrize
* Use async
This commit is contained in:
cdce8p 2018-05-11 01:21:59 +02:00 committed by GitHub
parent 6843893d9f
commit 8fcf085829
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1255 additions and 1591 deletions

View File

@ -3,8 +3,7 @@
This includes tests for all mock object types. This includes tests for all mock object types.
""" """
from datetime import datetime, timedelta from datetime import datetime, timedelta
import unittest from unittest.mock import patch, Mock
from unittest.mock import call, patch, Mock
from homeassistant.components.homekit.accessories import ( from homeassistant.components.homekit.accessories import (
debounce, HomeAccessory, HomeBridge, HomeDriver) debounce, HomeAccessory, HomeBridge, HomeDriver)
@ -15,8 +14,6 @@ from homeassistant.components.homekit.const import (
from homeassistant.const import __version__, ATTR_NOW, EVENT_TIME_CHANGED from homeassistant.const import __version__, ATTR_NOW, EVENT_TIME_CHANGED
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import get_test_home_assistant
def patch_debounce(): def patch_debounce():
"""Return patch for debounce method.""" """Return patch for debounce method."""
@ -24,10 +21,7 @@ def patch_debounce():
lambda f: lambda *args, **kwargs: f(*args, **kwargs)) lambda f: lambda *args, **kwargs: f(*args, **kwargs))
class TestAccessories(unittest.TestCase): async def test_debounce(hass):
"""Test pyhap adapter methods."""
def test_debounce(self):
"""Test add_timeout decorator function.""" """Test add_timeout decorator function."""
def demo_func(*args): def demo_func(*args):
nonlocal arguments, counter nonlocal arguments, counter
@ -36,92 +30,78 @@ class TestAccessories(unittest.TestCase):
arguments = None arguments = None
counter = 0 counter = 0
hass = get_test_home_assistant()
mock = Mock(hass=hass) mock = Mock(hass=hass)
debounce_demo = debounce(demo_func) debounce_demo = debounce(demo_func)
self.assertEqual(debounce_demo.__name__, 'demo_func') assert debounce_demo.__name__ == 'demo_func'
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC) now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', return_value=now): with patch('homeassistant.util.dt.utcnow', return_value=now):
debounce_demo(mock, 'value') await hass.async_add_job(debounce_demo, mock, 'value')
hass.bus.fire( hass.bus.async_fire(
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)}) EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
hass.block_till_done() await hass.async_block_till_done()
assert counter == 1 assert counter == 1
assert len(arguments) == 2 assert len(arguments) == 2
with patch('homeassistant.util.dt.utcnow', return_value=now): with patch('homeassistant.util.dt.utcnow', return_value=now):
debounce_demo(mock, 'value') await hass.async_add_job(debounce_demo, mock, 'value')
debounce_demo(mock, 'value') await hass.async_add_job(debounce_demo, mock, 'value')
hass.bus.fire( hass.bus.async_fire(
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)}) EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
hass.block_till_done() await hass.async_block_till_done()
assert counter == 2 assert counter == 2
hass.stop()
def test_home_accessory(self): async def test_home_accessory(hass):
"""Test HomeAccessory class.""" """Test HomeAccessory class."""
hass = get_test_home_assistant()
acc = HomeAccessory(hass, 'Home Accessory', 'homekit.accessory', 2) acc = HomeAccessory(hass, 'Home Accessory', 'homekit.accessory', 2)
self.assertEqual(acc.hass, hass) assert acc.hass == hass
self.assertEqual(acc.display_name, 'Home Accessory') assert acc.display_name == 'Home Accessory'
self.assertEqual(acc.category, 1) # Category.OTHER assert acc.category == 1 # Category.OTHER
self.assertEqual(len(acc.services), 1) assert len(acc.services) == 1
serv = acc.services[0] # SERV_ACCESSORY_INFO serv = acc.services[0] # SERV_ACCESSORY_INFO
self.assertEqual(serv.display_name, SERV_ACCESSORY_INFO) assert serv.display_name == SERV_ACCESSORY_INFO
self.assertEqual( assert serv.get_characteristic(CHAR_NAME).value == 'Home Accessory'
serv.get_characteristic(CHAR_NAME).value, 'Home Accessory') assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
self.assertEqual( assert serv.get_characteristic(CHAR_MODEL).value == 'Homekit'
serv.get_characteristic(CHAR_MANUFACTURER).value, MANUFACTURER) assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
self.assertEqual( 'homekit.accessory'
serv.get_characteristic(CHAR_MODEL).value, 'Homekit')
self.assertEqual(serv.get_characteristic(CHAR_SERIAL_NUMBER).value,
'homekit.accessory')
hass.states.set('homekit.accessory', 'on') hass.states.async_set('homekit.accessory', 'on')
hass.block_till_done() await hass.async_block_till_done()
acc.run() await hass.async_add_job(acc.run)
hass.states.set('homekit.accessory', 'off') hass.states.async_set('homekit.accessory', 'off')
hass.block_till_done() await hass.async_block_till_done()
acc = HomeAccessory('hass', 'test_name', 'test_model.demo', 2) acc = HomeAccessory('hass', 'test_name', 'test_model.demo', 2)
self.assertEqual(acc.display_name, 'test_name') assert acc.display_name == 'test_name'
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(len(acc.services), 1) assert len(acc.services) == 1
serv = acc.services[0] # SERV_ACCESSORY_INFO serv = acc.services[0] # SERV_ACCESSORY_INFO
self.assertEqual( assert serv.get_characteristic(CHAR_MODEL).value == 'Test Model'
serv.get_characteristic(CHAR_MODEL).value, 'Test Model')
hass.stop()
def test_home_bridge(self): def test_home_bridge():
"""Test HomeBridge class.""" """Test HomeBridge class."""
bridge = HomeBridge('hass') bridge = HomeBridge('hass')
self.assertEqual(bridge.hass, 'hass') assert bridge.hass == 'hass'
self.assertEqual(bridge.display_name, BRIDGE_NAME) assert bridge.display_name == BRIDGE_NAME
self.assertEqual(bridge.category, 2) # Category.BRIDGE assert bridge.category == 2 # Category.BRIDGE
self.assertEqual(len(bridge.services), 1) assert len(bridge.services) == 1
serv = bridge.services[0] # SERV_ACCESSORY_INFO serv = bridge.services[0] # SERV_ACCESSORY_INFO
self.assertEqual(serv.display_name, SERV_ACCESSORY_INFO) assert serv.display_name == SERV_ACCESSORY_INFO
self.assertEqual( assert serv.get_characteristic(CHAR_NAME).value == BRIDGE_NAME
serv.get_characteristic(CHAR_NAME).value, BRIDGE_NAME) assert serv.get_characteristic(CHAR_FIRMWARE_REVISION).value == __version__
self.assertEqual( assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
serv.get_characteristic(CHAR_FIRMWARE_REVISION).value, __version__) assert serv.get_characteristic(CHAR_MODEL).value == BRIDGE_MODEL
self.assertEqual( assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
serv.get_characteristic(CHAR_MANUFACTURER).value, MANUFACTURER) BRIDGE_SERIAL_NUMBER
self.assertEqual(
serv.get_characteristic(CHAR_MODEL).value, BRIDGE_MODEL)
self.assertEqual(
serv.get_characteristic(CHAR_SERIAL_NUMBER).value,
BRIDGE_SERIAL_NUMBER)
bridge = HomeBridge('hass', 'test_name') bridge = HomeBridge('hass', 'test_name')
self.assertEqual(bridge.display_name, 'test_name') assert bridge.display_name == 'test_name'
self.assertEqual(len(bridge.services), 1) assert len(bridge.services) == 1
serv = bridge.services[0] # SERV_ACCESSORY_INFO serv = bridge.services[0] # SERV_ACCESSORY_INFO
# setup_message # setup_message
@ -134,9 +114,8 @@ class TestAccessories(unittest.TestCase):
'dismiss_setup_message') as mock_dissmiss_msg: 'dismiss_setup_message') as mock_dissmiss_msg:
bridge.add_paired_client('client_uuid', 'client_public') bridge.add_paired_client('client_uuid', 'client_public')
self.assertEqual(mock_add_paired_client.call_args, mock_add_paired_client.assert_called_with('client_uuid', 'client_public')
call('client_uuid', 'client_public')) mock_dissmiss_msg.assert_called_with('hass')
self.assertEqual(mock_dissmiss_msg.call_args, call('hass'))
# remove_paired_client # remove_paired_client
with patch('pyhap.accessory.Accessory.remove_paired_client') \ with patch('pyhap.accessory.Accessory.remove_paired_client') \
@ -145,11 +124,11 @@ class TestAccessories(unittest.TestCase):
'show_setup_message') as mock_show_msg: 'show_setup_message') as mock_show_msg:
bridge.remove_paired_client('client_uuid') bridge.remove_paired_client('client_uuid')
self.assertEqual( mock_remove_paired_client.assert_called_with('client_uuid')
mock_remove_paired_client.call_args, call('client_uuid')) mock_show_msg.assert_called_with('hass', bridge)
self.assertEqual(mock_show_msg.call_args, call('hass', bridge))
def test_home_driver(self):
def test_home_driver():
"""Test HomeDriver class.""" """Test HomeDriver class."""
bridge = HomeBridge('hass') bridge = HomeBridge('hass')
ip_address = '127.0.0.1' ip_address = '127.0.0.1'
@ -160,5 +139,4 @@ class TestAccessories(unittest.TestCase):
as mock_driver: as mock_driver:
HomeDriver(bridge, ip_address, port, path) HomeDriver(bridge, ip_address, port, path)
self.assertEqual( mock_driver.assert_called_with(bridge, ip_address, port, path)
mock_driver.call_args, call(bridge, ip_address, port, path))

View File

@ -1,22 +1,20 @@
"""Package to test the get_accessory method.""" """Package to test the get_accessory method."""
import logging import logging
import unittest
from unittest.mock import patch, Mock from unittest.mock import patch, Mock
import pytest
from homeassistant.core import State from homeassistant.core import State
from homeassistant.components.cover import ( from homeassistant.components.cover import SUPPORT_OPEN, SUPPORT_CLOSE
SUPPORT_OPEN, SUPPORT_CLOSE)
from homeassistant.components.climate import ( from homeassistant.components.climate import (
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW) SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW)
from homeassistant.components.homekit import get_accessory, TYPES from homeassistant.components.homekit import get_accessory, TYPES
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_UNIT_OF_MEASUREMENT, ATTR_SUPPORTED_FEATURES, ATTR_CODE, ATTR_DEVICE_CLASS, ATTR_SUPPORTED_FEATURES,
TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_DEVICE_CLASS) ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, TEMP_FAHRENHEIT)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONFIG = {}
def test_get_accessory_invalid_aid(caplog): def test_get_accessory_invalid_aid(caplog):
"""Test with unsupported component.""" """Test with unsupported component."""
@ -32,182 +30,93 @@ def test_not_supported():
is None is None
class TestGetAccessories(unittest.TestCase): @pytest.mark.parametrize('type_name, entity_id, state, attrs, config', [
"""Methods to test the get_accessory method.""" ('Light', 'light.test', 'on', {}, None),
('Lock', 'lock.test', 'locked', {}, None),
def setUp(self): ('Thermostat', 'climate.test', 'auto', {}, None),
"""Setup Mock type.""" ('Thermostat', 'climate.test', 'auto',
self.mock_type = Mock() {ATTR_SUPPORTED_FEATURES: SUPPORT_TARGET_TEMPERATURE_LOW |
SUPPORT_TARGET_TEMPERATURE_HIGH}, None),
def tearDown(self): ('SecuritySystem', 'alarm_control_panel.test', 'armed', {},
"""Test if mock type was called.""" {ATTR_CODE: '1234'}),
self.assertTrue(self.mock_type.called) ])
def test_types(type_name, entity_id, state, attrs, config):
"""Test if types are associated correctly."""
mock_type = Mock()
with patch.dict(TYPES, {type_name: mock_type}):
entity_state = State(entity_id, state, attrs)
get_accessory(None, entity_state, 2, config)
assert mock_type.called
def test_sensor_temperature(self): if config:
"""Test temperature sensor with device class temperature.""" assert mock_type.call_args[1]['config'] == config
with patch.dict(TYPES, {'TemperatureSensor': self.mock_type}):
state = State('sensor.temperature', '23',
{ATTR_DEVICE_CLASS: 'temperature'})
get_accessory(None, state, 2, {})
def test_sensor_temperature_celsius(self):
"""Test temperature sensor with Celsius as unit."""
with patch.dict(TYPES, {'TemperatureSensor': self.mock_type}):
state = State('sensor.temperature', '23',
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
get_accessory(None, state, 2, {})
def test_sensor_temperature_fahrenheit(self): @pytest.mark.parametrize('type_name, entity_id, state, attrs', [
"""Test temperature sensor with Fahrenheit as unit.""" ('GarageDoorOpener', 'cover.garage_door', 'open',
with patch.dict(TYPES, {'TemperatureSensor': self.mock_type}): {ATTR_DEVICE_CLASS: 'garage',
state = State('sensor.temperature', '74', ATTR_SUPPORTED_FEATURES: SUPPORT_OPEN | SUPPORT_CLOSE}),
{ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT}) ('WindowCovering', 'cover.set_position', 'open',
get_accessory(None, state, 2, {}) {ATTR_SUPPORTED_FEATURES: 4}),
('WindowCoveringBasic', 'cover.open_window', 'open',
{ATTR_SUPPORTED_FEATURES: 3}),
])
def test_type_covers(type_name, entity_id, state, attrs):
"""Test if cover types are associated correctly."""
mock_type = Mock()
with patch.dict(TYPES, {type_name: mock_type}):
entity_state = State(entity_id, state, attrs)
get_accessory(None, entity_state, 2, None)
assert mock_type.called
def test_sensor_humidity(self):
"""Test humidity sensor with device class humidity."""
with patch.dict(TYPES, {'HumiditySensor': self.mock_type}):
state = State('sensor.humidity', '20',
{ATTR_DEVICE_CLASS: 'humidity',
ATTR_UNIT_OF_MEASUREMENT: '%'})
get_accessory(None, state, 2, {})
def test_air_quality_sensor(self): @pytest.mark.parametrize('type_name, entity_id, state, attrs', [
"""Test air quality sensor with pm25 class.""" ('BinarySensor', 'binary_sensor.opening', 'on',
with patch.dict(TYPES, {'AirQualitySensor': self.mock_type}): {ATTR_DEVICE_CLASS: 'opening'}),
state = State('sensor.air_quality', '40', ('BinarySensor', 'device_tracker.someone', 'not_home', {}),
{ATTR_DEVICE_CLASS: 'pm25'})
get_accessory(None, state, 2, {})
def test_air_quality_sensor_entity_id(self): ('AirQualitySensor', 'sensor.air_quality_pm25', '40', {}),
"""Test air quality sensor with entity_id contains pm25.""" ('AirQualitySensor', 'sensor.air_quality', '40',
with patch.dict(TYPES, {'AirQualitySensor': self.mock_type}): {ATTR_DEVICE_CLASS: 'pm25'}),
state = State('sensor.air_quality_pm25', '40', {})
get_accessory(None, state, 2, {})
def test_co2_sensor(self): ('CarbonDioxideSensor', 'sensor.airmeter_co2', '500', {}),
"""Test co2 sensor with device class co2.""" ('CarbonDioxideSensor', 'sensor.airmeter', '500',
with patch.dict(TYPES, {'CarbonDioxideSensor': self.mock_type}): {ATTR_DEVICE_CLASS: 'co2'}),
state = State('sensor.airmeter', '500',
{ATTR_DEVICE_CLASS: 'co2'})
get_accessory(None, state, 2, {})
def test_co2_sensor_entity_id(self): ('HumiditySensor', 'sensor.humidity', '20',
"""Test co2 sensor with entity_id contains co2.""" {ATTR_DEVICE_CLASS: 'humidity', ATTR_UNIT_OF_MEASUREMENT: '%'}),
with patch.dict(TYPES, {'CarbonDioxideSensor': self.mock_type}):
state = State('sensor.airmeter_co2', '500', {})
get_accessory(None, state, 2, {})
def test_light_sensor(self): ('LightSensor', 'sensor.light', '900', {ATTR_DEVICE_CLASS: 'illuminance'}),
"""Test light sensor with device class illuminance.""" ('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lm'}),
with patch.dict(TYPES, {'LightSensor': self.mock_type}): ('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lx'}),
state = State('sensor.light', '900',
{ATTR_DEVICE_CLASS: 'illuminance'})
get_accessory(None, state, 2, {})
def test_light_sensor_unit_lm(self): ('TemperatureSensor', 'sensor.temperature', '23',
"""Test light sensor with lm as unit.""" {ATTR_DEVICE_CLASS: 'temperature'}),
with patch.dict(TYPES, {'LightSensor': self.mock_type}): ('TemperatureSensor', 'sensor.temperature', '23',
state = State('sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}),
{ATTR_UNIT_OF_MEASUREMENT: 'lm'}) ('TemperatureSensor', 'sensor.temperature', '74',
get_accessory(None, state, 2, {}) {ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT}),
])
def test_type_sensors(type_name, entity_id, state, attrs):
"""Test if sensor types are associated correctly."""
mock_type = Mock()
with patch.dict(TYPES, {type_name: mock_type}):
entity_state = State(entity_id, state, attrs)
get_accessory(None, entity_state, 2, None)
assert mock_type.called
def test_light_sensor_unit_lx(self):
"""Test light sensor with lx as unit."""
with patch.dict(TYPES, {'LightSensor': self.mock_type}):
state = State('sensor.light', '900',
{ATTR_UNIT_OF_MEASUREMENT: 'lx'})
get_accessory(None, state, 2, {})
def test_binary_sensor(self): @pytest.mark.parametrize('type_name, entity_id, state, attrs', [
"""Test binary sensor with opening class.""" ('Switch', 'switch.test', 'on', {}),
with patch.dict(TYPES, {'BinarySensor': self.mock_type}): ('Switch', 'remote.test', 'on', {}),
state = State('binary_sensor.opening', 'on', ('Switch', 'input_boolean.test', 'on', {}),
{ATTR_DEVICE_CLASS: 'opening'}) ])
get_accessory(None, state, 2, {}) def test_type_switches(type_name, entity_id, state, attrs):
"""Test if switch types are associated correctly."""
def test_device_tracker(self): mock_type = Mock()
"""Test binary sensor with opening class.""" with patch.dict(TYPES, {type_name: mock_type}):
with patch.dict(TYPES, {'BinarySensor': self.mock_type}): entity_state = State(entity_id, state, attrs)
state = State('device_tracker.someone', 'not_home', {}) get_accessory(None, entity_state, 2, None)
get_accessory(None, state, 2, {}) assert mock_type.called
def test_garage_door(self):
"""Test cover with device_class: 'garage' and required features."""
with patch.dict(TYPES, {'GarageDoorOpener': self.mock_type}):
state = State('cover.garage_door', 'open', {
ATTR_DEVICE_CLASS: 'garage',
ATTR_SUPPORTED_FEATURES:
SUPPORT_OPEN | SUPPORT_CLOSE})
get_accessory(None, state, 2, {})
def test_cover_set_position(self):
"""Test cover with support for set_cover_position."""
with patch.dict(TYPES, {'WindowCovering': self.mock_type}):
state = State('cover.set_position', 'open',
{ATTR_SUPPORTED_FEATURES: 4})
get_accessory(None, state, 2, {})
def test_cover_open_close(self):
"""Test cover with support for open and close."""
with patch.dict(TYPES, {'WindowCoveringBasic': self.mock_type}):
state = State('cover.open_window', 'open',
{ATTR_SUPPORTED_FEATURES: 3})
get_accessory(None, state, 2, {})
def test_alarm_control_panel(self):
"""Test alarm control panel."""
config = {ATTR_CODE: '1234'}
with patch.dict(TYPES, {'SecuritySystem': self.mock_type}):
state = State('alarm_control_panel.test', 'armed')
get_accessory(None, state, 2, config)
# pylint: disable=unsubscriptable-object
print(self.mock_type.call_args[1])
self.assertEqual(
self.mock_type.call_args[1]['config'][ATTR_CODE], '1234')
def test_climate(self):
"""Test climate devices."""
with patch.dict(TYPES, {'Thermostat': self.mock_type}):
state = State('climate.test', 'auto')
get_accessory(None, state, 2, {})
def test_light(self):
"""Test light devices."""
with patch.dict(TYPES, {'Light': self.mock_type}):
state = State('light.test', 'on')
get_accessory(None, state, 2, {})
def test_climate_support_auto(self):
"""Test climate devices with support for auto mode."""
with patch.dict(TYPES, {'Thermostat': self.mock_type}):
state = State('climate.test', 'auto', {
ATTR_SUPPORTED_FEATURES:
SUPPORT_TARGET_TEMPERATURE_LOW |
SUPPORT_TARGET_TEMPERATURE_HIGH})
get_accessory(None, state, 2, {})
def test_switch(self):
"""Test switch."""
with patch.dict(TYPES, {'Switch': self.mock_type}):
state = State('switch.test', 'on')
get_accessory(None, state, 2, {})
def test_remote(self):
"""Test remote."""
with patch.dict(TYPES, {'Switch': self.mock_type}):
state = State('remote.test', 'on')
get_accessory(None, state, 2, {})
def test_input_boolean(self):
"""Test input_boolean."""
with patch.dict(TYPES, {'Switch': self.mock_type}):
state = State('input_boolean.test', 'on')
get_accessory(None, state, 2, {})
def test_lock(self):
"""Test lock."""
with patch.dict(TYPES, {'Lock': self.mock_type}):
state = State('lock.test', 'locked')
get_accessory(None, state, 2, {})

View File

@ -1,6 +1,7 @@
"""Tests for the HomeKit component.""" """Tests for the HomeKit component."""
import unittest from unittest.mock import patch, ANY, Mock
from unittest.mock import call, patch, ANY, Mock
import pytest
from homeassistant import setup from homeassistant import setup
from homeassistant.core import State from homeassistant.core import State
@ -16,208 +17,193 @@ from homeassistant.const import (
CONF_IP_ADDRESS, CONF_PORT, CONF_IP_ADDRESS, CONF_PORT,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from tests.common import get_test_home_assistant
from tests.components.homekit.test_accessories import patch_debounce 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'
class TestHomeKit(unittest.TestCase): @pytest.fixture('module')
"""Test setup of HomeKit component and HomeKit class.""" def debounce_patcher(request):
"""Patch debounce method."""
patcher = patch_debounce()
patcher.start()
request.addfinalizer(patcher.stop)
@classmethod
def setUpClass(cls):
"""Setup debounce patcher."""
cls.patcher = patch_debounce()
cls.patcher.start()
@classmethod def test_generate_aid():
def tearDownClass(cls):
"""Stop debounce patcher."""
cls.patcher.stop()
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_generate_aid(self):
"""Test generate aid method.""" """Test generate aid method."""
aid = generate_aid('demo.entity') aid = generate_aid('demo.entity')
self.assertIsInstance(aid, int) assert isinstance(aid, int)
self.assertTrue(aid >= 2 and aid <= 18446744073709551615) assert aid >= 2 and aid <= 18446744073709551615
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32: with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
mock_adler32.side_effect = [0, 1] mock_adler32.side_effect = [0, 1]
self.assertIsNone(generate_aid('demo.entity')) assert generate_aid('demo.entity') is None
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_min(self, mock_homekit): async def test_setup_min(hass):
"""Test async_setup with min config options.""" """Test async_setup with min config options."""
self.assertTrue(setup.setup_component( with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
self.hass, DOMAIN, {DOMAIN: {}})) assert await setup.async_setup_component(
hass, DOMAIN, {DOMAIN: {}})
self.assertEqual(mock_homekit.mock_calls, [ mock_homekit.assert_any_call(hass, DEFAULT_PORT, None, ANY, {})
call(self.hass, DEFAULT_PORT, None, ANY, {}), assert mock_homekit().setup.called is True
call().setup()])
# Test auto start enabled # Test auto start enabled
mock_homekit.reset_mock() mock_homekit.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_START) hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(mock_homekit.mock_calls, [call().start(ANY)]) mock_homekit().start.assert_called_with(ANY)
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_auto_start_disabled(self, mock_homekit): async def test_setup_auto_start_disabled(hass):
"""Test async_setup with auto start disabled and test service calls.""" """Test async_setup with auto start disabled and test service calls."""
mock_homekit.return_value = homekit = Mock()
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111, config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
CONF_IP_ADDRESS: '172.0.0.0'}} CONF_IP_ADDRESS: '172.0.0.0'}}
self.assertTrue(setup.setup_component(
self.hass, DOMAIN, config))
self.hass.block_till_done()
self.assertEqual(mock_homekit.mock_calls, [ with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
call(self.hass, 11111, '172.0.0.0', ANY, {}), mock_homekit.return_value = homekit = Mock()
call().setup()]) assert await setup.async_setup_component(
hass, DOMAIN, config)
mock_homekit.assert_any_call(hass, 11111, '172.0.0.0', ANY, {})
assert mock_homekit().setup.called is True
# Test auto_start disabled # Test auto_start disabled
homekit.reset_mock() homekit.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_START) hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(homekit.mock_calls, []) assert homekit.start.called is False
# Test start call with driver is ready # Test start call with driver is ready
homekit.reset_mock() homekit.reset_mock()
homekit.status = STATUS_READY homekit.status = STATUS_READY
self.hass.services.call('homekit', 'start') await hass.services.async_call(
self.assertEqual(homekit.mock_calls, [call.start()]) DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
assert homekit.start.called is True
# Test start call with driver started # Test start call with driver started
homekit.reset_mock() homekit.reset_mock()
homekit.status = STATUS_STOPPED homekit.status = STATUS_STOPPED
self.hass.services.call(DOMAIN, SERVICE_HOMEKIT_START) await hass.services.async_call(
self.assertEqual(homekit.mock_calls, []) DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
assert homekit.start.called is False
def test_homekit_setup(self):
async def test_homekit_setup(hass):
"""Test setup of bridge and driver.""" """Test setup of bridge and driver."""
homekit = HomeKit(self.hass, DEFAULT_PORT, None, {}, {}) homekit = HomeKit(hass, DEFAULT_PORT, None, {}, {})
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \ with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \
patch('homeassistant.util.get_local_ip') as mock_ip: patch('homeassistant.util.get_local_ip') as mock_ip:
mock_ip.return_value = IP_ADDRESS mock_ip.return_value = IP_ADDRESS
homekit.setup() await hass.async_add_job(homekit.setup)
path = self.hass.config.path(HOMEKIT_FILE) path = hass.config.path(HOMEKIT_FILE)
self.assertTrue(isinstance(homekit.bridge, HomeBridge)) assert isinstance(homekit.bridge, HomeBridge)
self.assertEqual(mock_driver.mock_calls, [ mock_driver.assert_called_with(
call(homekit.bridge, DEFAULT_PORT, IP_ADDRESS, path)]) homekit.bridge, DEFAULT_PORT, IP_ADDRESS, path)
# Test if stop listener is setup # Test if stop listener is setup
self.assertEqual( assert hass.bus.async_listeners().get(EVENT_HOMEASSISTANT_STOP) == 1
self.hass.bus.listeners.get(EVENT_HOMEASSISTANT_STOP), 1)
def test_homekit_setup_ip_address(self):
async def test_homekit_setup_ip_address(hass):
"""Test setup with given IP address.""" """Test setup with given IP address."""
homekit = HomeKit(self.hass, DEFAULT_PORT, '172.0.0.0', {}, {}) homekit = HomeKit(hass, DEFAULT_PORT, '172.0.0.0', {}, {})
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver: with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
homekit.setup() await hass.async_add_job(homekit.setup)
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY) mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
def test_homekit_add_accessory(self):
async def test_homekit_add_accessory(hass):
"""Add accessory if config exists and get_acc returns an accessory.""" """Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit(self.hass, None, None, lambda entity_id: True, {}) homekit = HomeKit(hass, None, None, lambda entity_id: True, {})
homekit.bridge = HomeBridge(self.hass) homekit.bridge = HomeBridge(hass)
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \ with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
as mock_add_acc, \ as mock_add_acc, \
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc: patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.side_effect = [None, 'acc', None] mock_get_acc.side_effect = [None, 'acc', None]
homekit.add_bridge_accessory(State('light.demo', 'on')) homekit.add_bridge_accessory(State('light.demo', 'on'))
self.assertEqual(mock_get_acc.call_args, mock_get_acc.assert_called_with(hass, ANY, 363398124, {})
call(self.hass, ANY, 363398124, {})) assert mock_add_acc.called is False
self.assertFalse(mock_add_acc.called)
homekit.add_bridge_accessory(State('demo.test', 'on'))
self.assertEqual(mock_get_acc.call_args,
call(self.hass, ANY, 294192020, {}))
self.assertTrue(mock_add_acc.called)
homekit.add_bridge_accessory(State('demo.test_2', 'on'))
self.assertEqual(mock_get_acc.call_args,
call(self.hass, ANY, 429982757, {}))
self.assertEqual(mock_add_acc.mock_calls, [call('acc')])
def test_homekit_entity_filter(self): homekit.add_bridge_accessory(State('demo.test', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 294192020, {})
assert mock_add_acc.called is True
homekit.add_bridge_accessory(State('demo.test_2', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 429982757, {})
mock_add_acc.assert_called_with('acc')
async def test_homekit_entity_filter(hass):
"""Test the entity filter.""" """Test the entity filter."""
entity_filter = generate_filter(['cover'], ['demo.test'], [], []) entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
homekit = HomeKit(self.hass, None, None, entity_filter, {}) homekit = HomeKit(hass, None, None, entity_filter, {})
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc: with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.return_value = None mock_get_acc.return_value = None
homekit.add_bridge_accessory(State('cover.test', 'open')) homekit.add_bridge_accessory(State('cover.test', 'open'))
self.assertTrue(mock_get_acc.called) assert mock_get_acc.called is True
mock_get_acc.reset_mock() mock_get_acc.reset_mock()
homekit.add_bridge_accessory(State('demo.test', 'on')) homekit.add_bridge_accessory(State('demo.test', 'on'))
self.assertTrue(mock_get_acc.called) assert mock_get_acc.called is True
mock_get_acc.reset_mock() mock_get_acc.reset_mock()
homekit.add_bridge_accessory(State('light.demo', 'light')) homekit.add_bridge_accessory(State('light.demo', 'light'))
self.assertFalse(mock_get_acc.called) assert mock_get_acc.called is False
@patch(PATH_HOMEKIT + '.show_setup_message')
@patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory') async def test_homekit_start(hass, debounce_patcher):
def test_homekit_start(self, mock_add_bridge_acc, mock_show_setup_msg):
"""Test HomeKit start method.""" """Test HomeKit start method."""
homekit = HomeKit(self.hass, None, None, {}, {'cover.demo': {}}) homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}})
homekit.bridge = HomeBridge(self.hass) homekit.bridge = HomeBridge(hass)
homekit.driver = Mock() homekit.driver = Mock()
self.hass.states.set('light.demo', 'on') hass.states.async_set('light.demo', 'on')
state = self.hass.states.all()[0] state = hass.states.async_all()[0]
homekit.start() with patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory') as \
self.hass.block_till_done() mock_add_acc, \
patch(PATH_HOMEKIT + '.show_setup_message') as mock_setup_msg:
await hass.async_add_job(homekit.start)
self.assertEqual(mock_add_bridge_acc.mock_calls, [call(state)]) mock_add_acc.assert_called_with(state)
self.assertEqual(mock_show_setup_msg.mock_calls, [ mock_setup_msg.assert_called_with(hass, homekit.bridge)
call(self.hass, homekit.bridge)]) assert homekit.driver.start.called is True
self.assertEqual(homekit.driver.mock_calls, [call.start()]) assert homekit.status == STATUS_RUNNING
self.assertEqual(homekit.status, STATUS_RUNNING)
# Test start() if already started # Test start() if already started
homekit.driver.reset_mock() homekit.driver.reset_mock()
homekit.start() await hass.async_add_job(homekit.start)
self.hass.block_till_done() assert homekit.driver.start.called is False
self.assertEqual(homekit.driver.mock_calls, [])
def test_homekit_stop(self):
async def test_homekit_stop(hass):
"""Test HomeKit stop method.""" """Test HomeKit stop method."""
homekit = HomeKit(self.hass, None, None, None, None) homekit = HomeKit(hass, None, None, None, None)
homekit.driver = Mock() homekit.driver = Mock()
self.assertEqual(homekit.status, STATUS_READY) assert homekit.status == STATUS_READY
homekit.stop() await hass.async_add_job(homekit.stop)
self.hass.block_till_done()
homekit.status = STATUS_WAIT homekit.status = STATUS_WAIT
homekit.stop() await hass.async_add_job(homekit.stop)
self.hass.block_till_done()
homekit.status = STATUS_STOPPED homekit.status = STATUS_STOPPED
homekit.stop() await hass.async_add_job(homekit.stop)
self.hass.block_till_done() assert homekit.driver.stop.called is False
self.assertFalse(homekit.driver.stop.called)
# Test if driver is started # Test if driver is started
homekit.status = STATUS_RUNNING homekit.status = STATUS_RUNNING
homekit.stop() await hass.async_add_job(homekit.stop)
self.hass.block_till_done() assert homekit.driver.stop.called is True
self.assertTrue(homekit.driver.stop.called)

View File

@ -1,265 +1,231 @@
"""Test different accessory types: Covers.""" """Test different accessory types: Covers."""
import unittest from collections import namedtuple
import pytest
from homeassistant.core import callback
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, ATTR_CURRENT_POSITION, SUPPORT_STOP) DOMAIN, ATTR_CURRENT_POSITION, ATTR_POSITION, SUPPORT_STOP)
from homeassistant.const import ( from homeassistant.const import (
STATE_CLOSED, STATE_UNAVAILABLE, STATE_UNKNOWN, STATE_OPEN, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES,
ATTR_SERVICE, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, STATE_CLOSED, STATE_OPEN, STATE_UNAVAILABLE, STATE_UNKNOWN)
ATTR_SUPPORTED_FEATURES)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.test_accessories import patch_debounce
class TestHomekitCovers(unittest.TestCase): @pytest.fixture(scope='module')
"""Test class for all accessory types regarding covers.""" def cls(request):
"""Patch debounce decorator during import of type_covers."""
@classmethod patcher = patch_debounce()
def setUpClass(cls): patcher.start()
"""Setup Light class import and debounce patcher."""
cls.patcher = patch_debounce()
cls.patcher.start()
_import = __import__('homeassistant.components.homekit.type_covers', _import = __import__('homeassistant.components.homekit.type_covers',
fromlist=['GarageDoorOpener', 'WindowCovering,', fromlist=['GarageDoorOpener', 'WindowCovering,',
'WindowCoveringBasic']) 'WindowCoveringBasic'])
cls.garage_cls = _import.GarageDoorOpener request.addfinalizer(patcher.stop)
cls.window_cls = _import.WindowCovering patcher_tuple = namedtuple('Cls', ['window', 'window_basic', 'garage'])
cls.window_basic_cls = _import.WindowCoveringBasic return patcher_tuple(window=_import.WindowCovering,
window_basic=_import.WindowCoveringBasic,
garage=_import.GarageDoorOpener)
@classmethod
def tearDownClass(cls):
"""Stop debounce patcher."""
cls.patcher.stop()
def setUp(self): async def test_garage_door_open_close(hass, cls):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_garage_door_open_close(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
garage_door = 'cover.garage_door' entity_id = 'cover.garage_door'
acc = self.garage_cls(self.hass, 'Cover', garage_door, 2, config=None) acc = cls.garage(hass, 'Garage Door', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 4) # GarageDoorOpener assert acc.category == 4 # GarageDoorOpener
self.assertEqual(acc.char_current_state.value, 0) assert acc.char_current_state.value == 0
self.assertEqual(acc.char_target_state.value, 0) assert acc.char_target_state.value == 0
self.hass.states.set(garage_door, STATE_CLOSED) hass.states.async_set(entity_id, STATE_CLOSED)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_state.value == 1
assert acc.char_target_state.value == 1
self.assertEqual(acc.char_current_state.value, 1) hass.states.async_set(entity_id, STATE_OPEN)
self.assertEqual(acc.char_target_state.value, 1) await hass.async_block_till_done()
assert acc.char_current_state.value == 0
assert acc.char_target_state.value == 0
self.hass.states.set(garage_door, STATE_OPEN) hass.states.async_set(entity_id, STATE_UNAVAILABLE)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_state.value == 0
assert acc.char_target_state.value == 0
self.assertEqual(acc.char_current_state.value, 0) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.assertEqual(acc.char_target_state.value, 0) await hass.async_block_till_done()
assert acc.char_current_state.value == 0
assert acc.char_target_state.value == 0
self.hass.states.set(garage_door, STATE_UNAVAILABLE) # Set from HomeKit
self.hass.block_till_done() call_close_cover = async_mock_service(hass, DOMAIN, 'close_cover')
call_open_cover = async_mock_service(hass, DOMAIN, 'open_cover')
self.assertEqual(acc.char_current_state.value, 0) await hass.async_add_job(acc.char_target_state.client_update_value, 1)
self.assertEqual(acc.char_target_state.value, 0) await hass.async_block_till_done()
assert call_close_cover
assert call_close_cover[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_current_state.value == 2
assert acc.char_target_state.value == 1
self.hass.states.set(garage_door, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_CLOSED)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_current_state.value, 0) await hass.async_add_job(acc.char_target_state.client_update_value, 0)
self.assertEqual(acc.char_target_state.value, 0) await hass.async_block_till_done()
assert call_open_cover
assert call_open_cover[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_current_state.value == 3
assert acc.char_target_state.value == 0
# Set closed from HomeKit
acc.char_target_state.client_update_value(1)
self.hass.block_till_done()
self.assertEqual(acc.char_current_state.value, 2) async def test_window_set_cover_position(hass, cls):
self.assertEqual(acc.char_target_state.value, 1)
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'close_cover')
self.hass.states.set(garage_door, STATE_CLOSED)
self.hass.block_till_done()
# Set open from HomeKit
acc.char_target_state.client_update_value(0)
self.hass.block_till_done()
self.assertEqual(acc.char_current_state.value, 3)
self.assertEqual(acc.char_target_state.value, 0)
self.assertEqual(
self.events[1].data[ATTR_SERVICE], 'open_cover')
def test_window_set_cover_position(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
window_cover = 'cover.window' entity_id = 'cover.window'
acc = self.window_cls(self.hass, 'Cover', window_cover, 2, config=None) acc = cls.window(hass, 'Cover', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 14) # WindowCovering assert acc.category == 14 # WindowCovering
self.assertEqual(acc.char_current_position.value, 0) assert acc.char_current_position.value == 0
self.assertEqual(acc.char_target_position.value, 0) assert acc.char_target_position.value == 0
self.hass.states.set(window_cover, STATE_UNKNOWN, hass.states.async_set(entity_id, STATE_UNKNOWN,
{ATTR_CURRENT_POSITION: None}) {ATTR_CURRENT_POSITION: None})
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_position.value == 0
assert acc.char_target_position.value == 0
self.assertEqual(acc.char_current_position.value, 0) hass.states.async_set(entity_id, STATE_OPEN,
self.assertEqual(acc.char_target_position.value, 0)
self.hass.states.set(window_cover, STATE_OPEN,
{ATTR_CURRENT_POSITION: 50}) {ATTR_CURRENT_POSITION: 50})
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_position.value == 50
self.assertEqual(acc.char_current_position.value, 50) assert acc.char_target_position.value == 50
self.assertEqual(acc.char_target_position.value, 50)
# Set from HomeKit # Set from HomeKit
acc.char_target_position.client_update_value(25) call_set_cover_position = async_mock_service(hass, DOMAIN,
self.hass.block_till_done() 'set_cover_position')
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'set_cover_position')
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA][ATTR_POSITION], 25)
self.assertEqual(acc.char_current_position.value, 50) await hass.async_add_job(acc.char_target_position.client_update_value, 25)
self.assertEqual(acc.char_target_position.value, 25) await hass.async_block_till_done()
assert call_set_cover_position[0]
assert call_set_cover_position[0].data[ATTR_ENTITY_ID] == entity_id
assert call_set_cover_position[0].data[ATTR_POSITION] == 25
assert acc.char_current_position.value == 50
assert acc.char_target_position.value == 25
# Set from HomeKit await hass.async_add_job(acc.char_target_position.client_update_value, 75)
acc.char_target_position.client_update_value(75) await hass.async_block_till_done()
self.hass.block_till_done() assert call_set_cover_position[1]
self.assertEqual( assert call_set_cover_position[1].data[ATTR_ENTITY_ID] == entity_id
self.events[1].data[ATTR_SERVICE], 'set_cover_position') assert call_set_cover_position[1].data[ATTR_POSITION] == 75
self.assertEqual( assert acc.char_current_position.value == 50
self.events[1].data[ATTR_SERVICE_DATA][ATTR_POSITION], 75) assert acc.char_target_position.value == 75
self.assertEqual(acc.char_current_position.value, 50)
self.assertEqual(acc.char_target_position.value, 75)
def test_window_open_close(self): async def test_window_open_close(hass, cls):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
window_cover = 'cover.window' entity_id = 'cover.window'
self.hass.states.set(window_cover, STATE_UNKNOWN, hass.states.async_set(entity_id, STATE_UNKNOWN,
{ATTR_SUPPORTED_FEATURES: 0}) {ATTR_SUPPORTED_FEATURES: 0})
acc = self.window_basic_cls(self.hass, 'Cover', window_cover, 2, acc = cls.window_basic(hass, 'Cover', entity_id, 2, config=None)
config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 14) # WindowCovering assert acc.category == 14 # WindowCovering
self.assertEqual(acc.char_current_position.value, 0) assert acc.char_current_position.value == 0
self.assertEqual(acc.char_target_position.value, 0) assert acc.char_target_position.value == 0
self.assertEqual(acc.char_position_state.value, 2) assert acc.char_position_state.value == 2
self.hass.states.set(window_cover, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_position.value == 0
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 2
self.assertEqual(acc.char_current_position.value, 0) hass.states.async_set(entity_id, STATE_OPEN)
self.assertEqual(acc.char_target_position.value, 0) await hass.async_block_till_done()
self.assertEqual(acc.char_position_state.value, 2) assert acc.char_current_position.value == 100
assert acc.char_target_position.value == 100
assert acc.char_position_state.value == 2
self.hass.states.set(window_cover, STATE_OPEN) hass.states.async_set(entity_id, STATE_CLOSED)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_position.value == 0
self.assertEqual(acc.char_current_position.value, 100) assert acc.char_target_position.value == 0
self.assertEqual(acc.char_target_position.value, 100) assert acc.char_position_state.value == 2
self.assertEqual(acc.char_position_state.value, 2)
self.hass.states.set(window_cover, STATE_CLOSED)
self.hass.block_till_done()
self.assertEqual(acc.char_current_position.value, 0)
self.assertEqual(acc.char_target_position.value, 0)
self.assertEqual(acc.char_position_state.value, 2)
# Set from HomeKit # Set from HomeKit
acc.char_target_position.client_update_value(25) call_close_cover = async_mock_service(hass, DOMAIN, 'close_cover')
self.hass.block_till_done() call_open_cover = async_mock_service(hass, DOMAIN, 'open_cover')
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'close_cover')
self.assertEqual(acc.char_current_position.value, 0) await hass.async_add_job(acc.char_target_position.client_update_value, 25)
self.assertEqual(acc.char_target_position.value, 0) await hass.async_block_till_done()
self.assertEqual(acc.char_position_state.value, 2) assert call_close_cover
assert call_close_cover[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_current_position.value == 0
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 2
# Set from HomeKit await hass.async_add_job(acc.char_target_position.client_update_value, 90)
acc.char_target_position.client_update_value(90) await hass.async_block_till_done()
self.hass.block_till_done() assert call_open_cover[0]
self.assertEqual( assert call_open_cover[0].data[ATTR_ENTITY_ID] == entity_id
self.events[1].data[ATTR_SERVICE], 'open_cover') assert acc.char_current_position.value == 100
assert acc.char_target_position.value == 100
assert acc.char_position_state.value == 2
self.assertEqual(acc.char_current_position.value, 100) await hass.async_add_job(acc.char_target_position.client_update_value, 55)
self.assertEqual(acc.char_target_position.value, 100) await hass.async_block_till_done()
self.assertEqual(acc.char_position_state.value, 2) assert call_open_cover[1]
assert call_open_cover[1].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_current_position.value == 100
assert acc.char_target_position.value == 100
assert acc.char_position_state.value == 2
# Set from HomeKit
acc.char_target_position.client_update_value(55)
self.hass.block_till_done()
self.assertEqual(
self.events[2].data[ATTR_SERVICE], 'open_cover')
self.assertEqual(acc.char_current_position.value, 100) async def test_window_open_close_stop(hass, cls):
self.assertEqual(acc.char_target_position.value, 100)
self.assertEqual(acc.char_position_state.value, 2)
def test_window_open_close_stop(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
window_cover = 'cover.window' entity_id = 'cover.window'
self.hass.states.set(window_cover, STATE_UNKNOWN, hass.states.async_set(entity_id, STATE_UNKNOWN,
{ATTR_SUPPORTED_FEATURES: SUPPORT_STOP}) {ATTR_SUPPORTED_FEATURES: SUPPORT_STOP})
acc = self.window_basic_cls(self.hass, 'Cover', window_cover, 2, acc = cls.window_basic(hass, 'Cover', entity_id, 2, config=None)
config=None) await hass.async_add_job(acc.run)
acc.run()
# Set from HomeKit # Set from HomeKit
acc.char_target_position.client_update_value(25) call_close_cover = async_mock_service(hass, DOMAIN, 'close_cover')
self.hass.block_till_done() call_open_cover = async_mock_service(hass, DOMAIN, 'open_cover')
self.assertEqual( call_stop_cover = async_mock_service(hass, DOMAIN, 'stop_cover')
self.events[0].data[ATTR_SERVICE], 'close_cover')
self.assertEqual(acc.char_current_position.value, 0) await hass.async_add_job(acc.char_target_position.client_update_value, 25)
self.assertEqual(acc.char_target_position.value, 0) await hass.async_block_till_done()
self.assertEqual(acc.char_position_state.value, 2) assert call_close_cover
assert call_close_cover[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_current_position.value == 0
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 2
# Set from HomeKit await hass.async_add_job(acc.char_target_position.client_update_value, 90)
acc.char_target_position.client_update_value(90) await hass.async_block_till_done()
self.hass.block_till_done() assert call_open_cover
self.assertEqual( assert call_open_cover[0].data[ATTR_ENTITY_ID] == entity_id
self.events[1].data[ATTR_SERVICE], 'open_cover') assert acc.char_current_position.value == 100
assert acc.char_target_position.value == 100
assert acc.char_position_state.value == 2
self.assertEqual(acc.char_current_position.value, 100) await hass.async_add_job(acc.char_target_position.client_update_value, 55)
self.assertEqual(acc.char_target_position.value, 100) await hass.async_block_till_done()
self.assertEqual(acc.char_position_state.value, 2) assert call_stop_cover
assert call_stop_cover[0].data[ATTR_ENTITY_ID] == entity_id
# Set from HomeKit assert acc.char_current_position.value == 50
acc.char_target_position.client_update_value(55) assert acc.char_target_position.value == 50
self.hass.block_till_done() assert acc.char_position_state.value == 2
self.assertEqual(
self.events[2].data[ATTR_SERVICE], 'stop_cover')
self.assertEqual(acc.char_current_position.value, 50)
self.assertEqual(acc.char_target_position.value, 50)
self.assertEqual(acc.char_position_state.value, 2)

View File

@ -1,188 +1,174 @@
"""Test different accessory types: Lights.""" """Test different accessory types: Lights."""
import unittest from collections import namedtuple
import pytest
from homeassistant.core import callback
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)
from homeassistant.const import ( from homeassistant.const import (
ATTR_DOMAIN, ATTR_ENTITY_ID, ATTR_SERVICE, ATTR_SERVICE_DATA, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES,
ATTR_SUPPORTED_FEATURES, EVENT_CALL_SERVICE, SERVICE_TURN_ON, 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 async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.test_accessories import patch_debounce
class TestHomekitLights(unittest.TestCase): @pytest.fixture(scope='module')
"""Test class for all accessory types regarding lights.""" def cls(request):
"""Patch debounce decorator during import of type_lights."""
@classmethod patcher = patch_debounce()
def setUpClass(cls): patcher.start()
"""Setup Light class import and debounce patcher."""
cls.patcher = patch_debounce()
cls.patcher.start()
_import = __import__('homeassistant.components.homekit.type_lights', _import = __import__('homeassistant.components.homekit.type_lights',
fromlist=['Light']) fromlist=['Light'])
cls.light_cls = _import.Light request.addfinalizer(patcher.stop)
patcher_tuple = namedtuple('Cls', ['light'])
return patcher_tuple(light=_import.Light)
@classmethod
def tearDownClass(cls):
"""Stop debounce patcher."""
cls.patcher.stop()
def setUp(self): async def test_light_basic(hass, cls):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_light_basic(self):
"""Test light with char state.""" """Test light with char state."""
entity_id = 'light.demo' entity_id = 'light.demo'
self.hass.states.set(entity_id, STATE_ON, hass.states.async_set(entity_id, STATE_ON,
{ATTR_SUPPORTED_FEATURES: 0}) {ATTR_SUPPORTED_FEATURES: 0})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None) acc = cls.light(hass, 'Light', entity_id, 2, config=None)
self.assertEqual(acc.aid, 2)
self.assertEqual(acc.category, 5) # Lightbulb
self.assertEqual(acc.char_on.value, 0)
acc.run() assert acc.aid == 2
self.hass.block_till_done() assert acc.category == 5 # Lightbulb
self.assertEqual(acc.char_on.value, 1) assert acc.char_on.value == 0
self.hass.states.set(entity_id, STATE_OFF, await hass.async_add_job(acc.run)
await hass.async_block_till_done()
assert acc.char_on.value == 1
hass.states.async_set(entity_id, STATE_OFF,
{ATTR_SUPPORTED_FEATURES: 0}) {ATTR_SUPPORTED_FEATURES: 0})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_on.value, 0) assert acc.char_on.value == 0
self.hass.states.set(entity_id, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_on.value, 0) assert acc.char_on.value == 0
hass.states.async_remove(entity_id)
await hass.async_block_till_done()
assert acc.char_on.value == 0
# Set from HomeKit # Set from HomeKit
acc.char_on.client_update_value(1) call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
self.hass.block_till_done() call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
self.hass.states.set(entity_id, STATE_ON) await hass.async_add_job(acc.char_on.client_update_value, 1)
self.hass.block_till_done() await hass.async_block_till_done()
assert call_turn_on
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
acc.char_on.client_update_value(0) hass.states.async_set(entity_id, STATE_ON)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
self.hass.states.set(entity_id, STATE_OFF) await hass.async_add_job(acc.char_on.client_update_value, 0)
self.hass.block_till_done() await hass.async_block_till_done()
assert call_turn_off
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
# Remove entity
self.hass.states.remove(entity_id)
self.hass.block_till_done()
def test_light_brightness(self): async def test_light_brightness(hass, cls):
"""Test light with brightness.""" """Test light with brightness."""
entity_id = 'light.demo' entity_id = 'light.demo'
self.hass.states.set(entity_id, STATE_ON, { hass.states.async_set(entity_id, STATE_ON, {
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255}) ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None) acc = cls.light(hass, 'Light', entity_id, 2, config=None)
self.assertEqual(acc.char_brightness.value, 0)
acc.run() assert acc.char_brightness.value == 0
self.hass.block_till_done()
self.assertEqual(acc.char_brightness.value, 100)
self.hass.states.set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102}) await hass.async_add_job(acc.run)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_brightness.value, 40) assert acc.char_brightness.value == 100
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
await hass.async_block_till_done()
assert acc.char_brightness.value == 40
# Set from HomeKit # Set from HomeKit
acc.char_brightness.client_update_value(20) call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
acc.char_on.client_update_value(1) call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
self.hass.block_till_done()
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA], {
ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 20})
acc.char_on.client_update_value(1) await hass.async_add_job(acc.char_brightness.client_update_value, 20)
acc.char_brightness.client_update_value(40) await hass.async_add_job(acc.char_on.client_update_value, 1)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN) assert call_turn_on[0]
self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_ON) assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20
self.events[1].data[ATTR_SERVICE_DATA], {
ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 40})
acc.char_on.client_update_value(1) await hass.async_add_job(acc.char_on.client_update_value, 1)
acc.char_brightness.client_update_value(0) await hass.async_add_job(acc.char_brightness.client_update_value, 40)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(self.events[2].data[ATTR_DOMAIN], DOMAIN) assert call_turn_on[1]
self.assertEqual(self.events[2].data[ATTR_SERVICE], SERVICE_TURN_OFF) assert call_turn_on[1].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[1].data[ATTR_BRIGHTNESS_PCT] == 40
def test_light_color_temperature(self): await hass.async_add_job(acc.char_on.client_update_value, 1)
await hass.async_add_job(acc.char_brightness.client_update_value, 0)
await hass.async_block_till_done()
assert call_turn_off
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
async def test_light_color_temperature(hass, cls):
"""Test light with color temperature.""" """Test light with color temperature."""
entity_id = 'light.demo' entity_id = 'light.demo'
self.hass.states.set(entity_id, STATE_ON, { hass.states.async_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})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None) acc = cls.light(hass, 'Light', entity_id, 2, config=None)
self.assertEqual(acc.char_color_temperature.value, 153)
acc.run() assert acc.char_color_temperature.value == 153
self.hass.block_till_done()
self.assertEqual(acc.char_color_temperature.value, 190) await hass.async_add_job(acc.run)
await hass.async_block_till_done()
assert acc.char_color_temperature.value == 190
# Set from HomeKit # Set from HomeKit
acc.char_color_temperature.client_update_value(250) call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
self.hass.block_till_done()
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA], {
ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP: 250})
def test_light_rgb_color(self): await hass.async_add_job(
acc.char_color_temperature.client_update_value, 250)
await hass.async_block_till_done()
assert call_turn_on
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250
async def test_light_rgb_color(hass, cls):
"""Test light with rgb_color.""" """Test light with rgb_color."""
entity_id = 'light.demo' entity_id = 'light.demo'
self.hass.states.set(entity_id, STATE_ON, { hass.states.async_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)})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None) acc = cls.light(hass, 'Light', entity_id, 2, config=None)
self.assertEqual(acc.char_hue.value, 0)
self.assertEqual(acc.char_saturation.value, 75)
acc.run() assert acc.char_hue.value == 0
self.hass.block_till_done() assert acc.char_saturation.value == 75
self.assertEqual(acc.char_hue.value, 260)
self.assertEqual(acc.char_saturation.value, 90) await hass.async_add_job(acc.run)
await hass.async_block_till_done()
assert acc.char_hue.value == 260
assert acc.char_saturation.value == 90
# Set from HomeKit # Set from HomeKit
acc.char_hue.client_update_value(145) call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
acc.char_saturation.client_update_value(75)
self.hass.block_till_done() await hass.async_add_job(acc.char_hue.client_update_value, 145)
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN) await hass.async_add_job(acc.char_saturation.client_update_value, 75)
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) await hass.async_block_till_done()
self.assertEqual( assert call_turn_on
self.events[0].data[ATTR_SERVICE_DATA], { assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (145, 75)}) assert call_turn_on[0].data[ATTR_HS_COLOR] == (145, 75)

View File

@ -1,77 +1,57 @@
"""Test different accessory types: Locks.""" """Test different accessory types: Locks."""
import unittest
from homeassistant.core import callback
from homeassistant.components.homekit.type_locks import Lock from homeassistant.components.homekit.type_locks import Lock
from homeassistant.components.lock import DOMAIN
from homeassistant.const import ( from homeassistant.const import (
STATE_UNKNOWN, STATE_UNLOCKED, STATE_LOCKED, ATTR_ENTITY_ID, STATE_UNKNOWN, STATE_UNLOCKED, STATE_LOCKED)
ATTR_SERVICE, EVENT_CALL_SERVICE)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
class TestHomekitSensors(unittest.TestCase): async def test_lock_unlock(hass):
"""Test class for all accessory types regarding covers."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_lock_unlock(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
kitchen_lock = 'lock.kitchen_door' entity_id = 'lock.kitchen_door'
acc = Lock(self.hass, 'Lock', kitchen_lock, 2, config=None) acc = Lock(hass, 'Lock', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 6) # DoorLock assert acc.category == 6 # DoorLock
self.assertEqual(acc.char_current_state.value, 3) assert acc.char_current_state.value == 3
self.assertEqual(acc.char_target_state.value, 1) assert acc.char_target_state.value == 1
self.hass.states.set(kitchen_lock, STATE_LOCKED) hass.states.async_set(entity_id, STATE_LOCKED)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_state.value == 1
assert acc.char_target_state.value == 1
self.assertEqual(acc.char_current_state.value, 1) hass.states.async_set(entity_id, STATE_UNLOCKED)
self.assertEqual(acc.char_target_state.value, 1) await hass.async_block_till_done()
assert acc.char_current_state.value == 0
assert acc.char_target_state.value == 0
self.hass.states.set(kitchen_lock, STATE_UNLOCKED) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_current_state.value == 3
assert acc.char_target_state.value == 0
self.assertEqual(acc.char_current_state.value, 0) hass.states.async_remove(entity_id)
self.assertEqual(acc.char_target_state.value, 0) await hass.async_block_till_done()
assert acc.char_current_state.value == 3
self.hass.states.set(kitchen_lock, STATE_UNKNOWN) assert acc.char_target_state.value == 0
self.hass.block_till_done()
self.assertEqual(acc.char_current_state.value, 3)
self.assertEqual(acc.char_target_state.value, 0)
# Set from HomeKit # Set from HomeKit
acc.char_target_state.client_update_value(1) call_lock = async_mock_service(hass, DOMAIN, 'lock')
self.hass.block_till_done() call_unlock = async_mock_service(hass, DOMAIN, 'unlock')
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'lock')
self.assertEqual(acc.char_target_state.value, 1)
acc.char_target_state.client_update_value(0) await hass.async_add_job(acc.char_target_state.client_update_value, 1)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_lock
self.events[1].data[ATTR_SERVICE], 'unlock') assert call_lock[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual(acc.char_target_state.value, 0) assert acc.char_target_state.value == 1
self.hass.states.remove(kitchen_lock) await hass.async_add_job(acc.char_target_state.client_update_value, 0)
self.hass.block_till_done() await hass.async_block_till_done()
assert call_unlock
assert call_unlock[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_target_state.value == 0

View File

@ -1,134 +1,110 @@
"""Test different accessory types: Security Systems.""" """Test different accessory types: Security Systems."""
import unittest import pytest
from homeassistant.core import callback from homeassistant.components.alarm_control_panel import DOMAIN
from homeassistant.components.homekit.type_security_systems import ( from homeassistant.components.homekit.type_security_systems import (
SecuritySystem) SecuritySystem)
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_SERVICE, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
STATE_UNKNOWN)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
class TestHomekitSecuritySystems(unittest.TestCase): async def test_switch_set_state(hass):
"""Test class for all accessory types regarding security systems."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_switch_set_state(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
acp = 'alarm_control_panel.test' code = '1234'
config = {ATTR_CODE: code}
entity_id = 'alarm_control_panel.test'
acc = SecuritySystem(self.hass, 'SecuritySystem', acp, acc = SecuritySystem(hass, 'SecuritySystem', entity_id, 2, config=config)
2, config={ATTR_CODE: '1234'}) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 11) # AlarmSystem assert acc.category == 11 # AlarmSystem
self.assertEqual(acc.char_current_state.value, 3) assert acc.char_current_state.value == 3
self.assertEqual(acc.char_target_state.value, 3) assert acc.char_target_state.value == 3
self.hass.states.set(acp, STATE_ALARM_ARMED_AWAY) hass.states.async_set(entity_id, STATE_ALARM_ARMED_AWAY)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 1) assert acc.char_target_state.value == 1
self.assertEqual(acc.char_current_state.value, 1) assert acc.char_current_state.value == 1
self.hass.states.set(acp, STATE_ALARM_ARMED_HOME) hass.states.async_set(entity_id, STATE_ALARM_ARMED_HOME)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 0) assert acc.char_target_state.value == 0
self.assertEqual(acc.char_current_state.value, 0) assert acc.char_current_state.value == 0
self.hass.states.set(acp, STATE_ALARM_ARMED_NIGHT) hass.states.async_set(entity_id, STATE_ALARM_ARMED_NIGHT)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 2) assert acc.char_target_state.value == 2
self.assertEqual(acc.char_current_state.value, 2) assert acc.char_current_state.value == 2
self.hass.states.set(acp, STATE_ALARM_DISARMED) hass.states.async_set(entity_id, STATE_ALARM_DISARMED)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 3) assert acc.char_target_state.value == 3
self.assertEqual(acc.char_current_state.value, 3) assert acc.char_current_state.value == 3
self.hass.states.set(acp, STATE_ALARM_TRIGGERED) hass.states.async_set(entity_id, STATE_ALARM_TRIGGERED)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 3) assert acc.char_target_state.value == 3
self.assertEqual(acc.char_current_state.value, 4) assert acc.char_current_state.value == 4
self.hass.states.set(acp, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_state.value, 3) assert acc.char_target_state.value == 3
self.assertEqual(acc.char_current_state.value, 4) assert acc.char_current_state.value == 4
# Set from HomeKit # Set from HomeKit
acc.char_target_state.client_update_value(0) call_arm_home = async_mock_service(hass, DOMAIN, 'alarm_arm_home')
self.hass.block_till_done() call_arm_away = async_mock_service(hass, DOMAIN, 'alarm_arm_away')
self.assertEqual( call_arm_night = async_mock_service(hass, DOMAIN, 'alarm_arm_night')
self.events[0].data[ATTR_SERVICE], 'alarm_arm_home') call_disarm = async_mock_service(hass, DOMAIN, 'alarm_disarm')
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234')
self.assertEqual(acc.char_target_state.value, 0)
acc.char_target_state.client_update_value(1) await hass.async_add_job(acc.char_target_state.client_update_value, 0)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_arm_home
self.events[1].data[ATTR_SERVICE], 'alarm_arm_away') assert call_arm_home[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_arm_home[0].data[ATTR_CODE] == code
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234') assert acc.char_target_state.value == 0
self.assertEqual(acc.char_target_state.value, 1)
acc.char_target_state.client_update_value(2) await hass.async_add_job(acc.char_target_state.client_update_value, 1)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_arm_away
self.events[2].data[ATTR_SERVICE], 'alarm_arm_night') assert call_arm_away[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_arm_away[0].data[ATTR_CODE] == code
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234') assert acc.char_target_state.value == 1
self.assertEqual(acc.char_target_state.value, 2)
acc.char_target_state.client_update_value(3) await hass.async_add_job(acc.char_target_state.client_update_value, 2)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_arm_night
self.events[3].data[ATTR_SERVICE], 'alarm_disarm') assert call_arm_night[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_arm_night[0].data[ATTR_CODE] == code
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234') assert acc.char_target_state.value == 2
self.assertEqual(acc.char_target_state.value, 3)
def test_no_alarm_code(self): await hass.async_add_job(acc.char_target_state.client_update_value, 3)
await hass.async_block_till_done()
assert call_disarm
assert call_disarm[0].data[ATTR_ENTITY_ID] == entity_id
assert call_disarm[0].data[ATTR_CODE] == code
assert acc.char_target_state.value == 3
@pytest.mark.parametrize('config', [{}, {ATTR_CODE: None}])
async def test_no_alarm_code(hass, config):
"""Test accessory if security_system doesn't require a alarm_code.""" """Test accessory if security_system doesn't require a alarm_code."""
acp = 'alarm_control_panel.test' entity_id = 'alarm_control_panel.test'
acc = SecuritySystem(self.hass, 'SecuritySystem', acp, acc = SecuritySystem(hass, 'SecuritySystem', entity_id, 2, config=config)
2, config={ATTR_CODE: None})
# Set from HomeKit
acc.char_target_state.client_update_value(0)
self.hass.block_till_done()
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'alarm_arm_home')
self.assertNotIn(ATTR_CODE, self.events[0].data[ATTR_SERVICE_DATA])
self.assertEqual(acc.char_target_state.value, 0)
acc = SecuritySystem(self.hass, 'SecuritySystem', acp,
2, config={})
# Set from HomeKit # Set from HomeKit
acc.char_target_state.client_update_value(0) call_arm_home = async_mock_service(hass, DOMAIN, 'alarm_arm_home')
self.hass.block_till_done()
self.assertEqual( await hass.async_add_job(acc.char_target_state.client_update_value, 0)
self.events[0].data[ATTR_SERVICE], 'alarm_arm_home') await hass.async_block_till_done()
self.assertNotIn(ATTR_CODE, self.events[0].data[ATTR_SERVICE_DATA]) assert call_arm_home
self.assertEqual(acc.char_target_state.value, 0) assert call_arm_home[0].data[ATTR_ENTITY_ID] == entity_id
assert ATTR_CODE not in call_arm_home[0].data
assert acc.char_target_state.value == 0

View File

@ -1,6 +1,4 @@
"""Test different accessory types: Sensors.""" """Test different accessory types: Sensors."""
import unittest
from homeassistant.components.homekit.const import PROP_CELSIUS from homeassistant.components.homekit.const import PROP_CELSIUS
from homeassistant.components.homekit.type_sensors import ( from homeassistant.components.homekit.type_sensors import (
TemperatureSensor, HumiditySensor, AirQualitySensor, CarbonDioxideSensor, TemperatureSensor, HumiditySensor, AirQualitySensor, CarbonDioxideSensor,
@ -9,201 +7,191 @@ from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_DEVICE_CLASS, STATE_UNKNOWN, STATE_ON, ATTR_UNIT_OF_MEASUREMENT, ATTR_DEVICE_CLASS, STATE_UNKNOWN, STATE_ON,
STATE_OFF, STATE_HOME, STATE_NOT_HOME, TEMP_CELSIUS, TEMP_FAHRENHEIT) STATE_OFF, STATE_HOME, STATE_NOT_HOME, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from tests.common import get_test_home_assistant
async def test_temperature(hass):
class TestHomekitSensors(unittest.TestCase):
"""Test class for all accessory types regarding sensors."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_temperature(self):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'sensor.temperature' entity_id = 'sensor.temperature'
acc = TemperatureSensor(self.hass, 'Temperature', entity_id, acc = TemperatureSensor(hass, 'Temperature', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_temp.value, 0.0) assert acc.char_temp.value == 0.0
for key, value in PROP_CELSIUS.items(): for key, value in PROP_CELSIUS.items():
self.assertEqual(acc.char_temp.properties[key], value) assert acc.char_temp.properties[key] == value
self.hass.states.set(entity_id, STATE_UNKNOWN, hass.states.async_set(entity_id, STATE_UNKNOWN,
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_temp.value, 0.0) assert acc.char_temp.value == 0.0
self.hass.states.set(entity_id, '20', hass.states.async_set(entity_id, '20',
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_temp.value, 20) assert acc.char_temp.value == 20
self.hass.states.set(entity_id, '75.2', hass.states.async_set(entity_id, '75.2',
{ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT}) {ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_temp.value, 24) assert acc.char_temp.value == 24
def test_humidity(self):
async def test_humidity(hass):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'sensor.humidity' entity_id = 'sensor.humidity'
acc = HumiditySensor(self.hass, 'Humidity', entity_id, 2, config=None) acc = HumiditySensor(hass, 'Humidity', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_humidity.value, 0) assert acc.char_humidity.value == 0
self.hass.states.set(entity_id, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_humidity.value, 0) assert acc.char_humidity.value == 0
self.hass.states.set(entity_id, '20') hass.states.async_set(entity_id, '20')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_humidity.value, 20) assert acc.char_humidity.value == 20
def test_air_quality(self):
async def test_air_quality(hass):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'sensor.air_quality' entity_id = 'sensor.air_quality'
acc = AirQualitySensor(self.hass, 'Air Quality', entity_id, acc = AirQualitySensor(hass, 'Air Quality', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_density.value, 0) assert acc.char_density.value == 0
self.assertEqual(acc.char_quality.value, 0) assert acc.char_quality.value == 0
self.hass.states.set(entity_id, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_density.value, 0) assert acc.char_density.value == 0
self.assertEqual(acc.char_quality.value, 0) assert acc.char_quality.value == 0
self.hass.states.set(entity_id, '34') hass.states.async_set(entity_id, '34')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_density.value, 34) assert acc.char_density.value == 34
self.assertEqual(acc.char_quality.value, 1) assert acc.char_quality.value == 1
self.hass.states.set(entity_id, '200') hass.states.async_set(entity_id, '200')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_density.value, 200) assert acc.char_density.value == 200
self.assertEqual(acc.char_quality.value, 5) assert acc.char_quality.value == 5
def test_co2(self):
async def test_co2(hass):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'sensor.co2' entity_id = 'sensor.co2'
acc = CarbonDioxideSensor(self.hass, 'CO2', entity_id, 2, config=None) acc = CarbonDioxideSensor(hass, 'CO2', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_co2.value, 0) assert acc.char_co2.value == 0
self.assertEqual(acc.char_peak.value, 0) assert acc.char_peak.value == 0
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
self.hass.states.set(entity_id, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_co2.value, 0) assert acc.char_co2.value == 0
self.assertEqual(acc.char_peak.value, 0) assert acc.char_peak.value == 0
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
self.hass.states.set(entity_id, '1100') hass.states.async_set(entity_id, '1100')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_co2.value, 1100) assert acc.char_co2.value == 1100
self.assertEqual(acc.char_peak.value, 1100) assert acc.char_peak.value == 1100
self.assertEqual(acc.char_detected.value, 1) assert acc.char_detected.value == 1
self.hass.states.set(entity_id, '800') hass.states.async_set(entity_id, '800')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_co2.value, 800) assert acc.char_co2.value == 800
self.assertEqual(acc.char_peak.value, 1100) assert acc.char_peak.value == 1100
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
def test_light(self):
async def test_light(hass):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'sensor.light' entity_id = 'sensor.light'
acc = LightSensor(self.hass, 'Light', entity_id, 2, config=None) acc = LightSensor(hass, 'Light', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_light.value, 0.0001) assert acc.char_light.value == 0.0001
self.hass.states.set(entity_id, STATE_UNKNOWN) hass.states.async_set(entity_id, STATE_UNKNOWN)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_light.value, 0.0001) assert acc.char_light.value == 0.0001
self.hass.states.set(entity_id, '300') hass.states.async_set(entity_id, '300')
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_light.value, 300) assert acc.char_light.value == 300
def test_binary(self):
async def test_binary(hass):
"""Test if accessory is updated after state change.""" """Test if accessory is updated after state change."""
entity_id = 'binary_sensor.opening' entity_id = 'binary_sensor.opening'
self.hass.states.set(entity_id, STATE_UNKNOWN, hass.states.async_set(entity_id, STATE_UNKNOWN,
{ATTR_DEVICE_CLASS: "opening"}) {ATTR_DEVICE_CLASS: 'opening'})
self.hass.block_till_done() await hass.async_block_till_done()
acc = BinarySensor(self.hass, 'Window Opening', entity_id, acc = BinarySensor(hass, 'Window Opening', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 10) # Sensor assert acc.category == 10 # Sensor
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
self.hass.states.set(entity_id, STATE_ON, hass.states.async_set(entity_id, STATE_ON,
{ATTR_DEVICE_CLASS: "opening"}) {ATTR_DEVICE_CLASS: 'opening'})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_detected.value, 1) assert acc.char_detected.value == 1
self.hass.states.set(entity_id, STATE_OFF, hass.states.async_set(entity_id, STATE_OFF,
{ATTR_DEVICE_CLASS: "opening"}) {ATTR_DEVICE_CLASS: 'opening'})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
self.hass.states.set(entity_id, STATE_HOME, hass.states.async_set(entity_id, STATE_HOME,
{ATTR_DEVICE_CLASS: "opening"}) {ATTR_DEVICE_CLASS: 'opening'})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_detected.value, 1) assert acc.char_detected.value == 1
self.hass.states.set(entity_id, STATE_NOT_HOME, hass.states.async_set(entity_id, STATE_NOT_HOME,
{ATTR_DEVICE_CLASS: "opening"}) {ATTR_DEVICE_CLASS: 'opening'})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_detected.value, 0) assert acc.char_detected.value == 0
self.hass.states.remove(entity_id) hass.states.async_remove(entity_id)
self.hass.block_till_done() await hass.async_block_till_done()
assert acc.char_detected.value == 0
def test_binary_device_classes(self):
async def test_binary_device_classes(hass):
"""Test if services and characteristics are assigned correctly.""" """Test if services and characteristics are assigned correctly."""
entity_id = 'binary_sensor.demo' entity_id = 'binary_sensor.demo'
for device_class, (service, char) in BINARY_SENSOR_SERVICE_MAP.items(): for device_class, (service, char) in BINARY_SENSOR_SERVICE_MAP.items():
self.hass.states.set(entity_id, STATE_OFF, hass.states.async_set(entity_id, STATE_OFF,
{ATTR_DEVICE_CLASS: device_class}) {ATTR_DEVICE_CLASS: device_class})
self.hass.block_till_done() await hass.async_block_till_done()
acc = BinarySensor(self.hass, 'Binary Sensor', entity_id, acc = BinarySensor(hass, 'Binary Sensor', entity_id, 2, config=None)
2, config=None) assert acc.get_service(service).display_name == service
self.assertEqual(acc.get_service(service).display_name, service) assert acc.char_detected.display_name == char
self.assertEqual(acc.char_detected.display_name, char)

View File

@ -1,104 +1,45 @@
"""Test different accessory types: Switches.""" """Test different accessory types: Switches."""
import unittest import pytest
from homeassistant.core import callback, split_entity_id from homeassistant.core import split_entity_id
from homeassistant.components.homekit.type_switches import Switch from homeassistant.components.homekit.type_switches import Switch
from homeassistant.const import ( from homeassistant.const import ATTR_ENTITY_ID, STATE_ON, STATE_OFF
ATTR_DOMAIN, ATTR_SERVICE, EVENT_CALL_SERVICE,
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_ON, STATE_OFF)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
class TestHomekitSwitches(unittest.TestCase): @pytest.mark.parametrize('entity_id', [
"""Test class for all accessory types regarding switches.""" 'switch.test', 'remote.test', 'input_boolean.test'])
async def test_switch_set_state(hass, entity_id):
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_switch_set_state(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
entity_id = 'switch.test'
domain = split_entity_id(entity_id)[0] domain = split_entity_id(entity_id)[0]
acc = Switch(self.hass, 'Switch', entity_id, 2, config=None) acc = Switch(hass, 'Switch', entity_id, 2, config=None)
acc.run() await hass.async_add_job(acc.run)
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 8) # Switch assert acc.category == 8 # Switch
self.assertEqual(acc.char_on.value, False) assert acc.char_on.value is False
self.hass.states.set(entity_id, STATE_ON) hass.states.async_set(entity_id, STATE_ON)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_on.value, True) assert acc.char_on.value is True
self.hass.states.set(entity_id, STATE_OFF) hass.states.async_set(entity_id, STATE_OFF)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_on.value, False) assert acc.char_on.value is False
# Set from HomeKit # Set from HomeKit
acc.char_on.client_update_value(True) call_turn_on = async_mock_service(hass, domain, 'turn_on')
self.hass.block_till_done() call_turn_off = async_mock_service(hass, domain, 'turn_off')
self.assertEqual(
self.events[0].data[ATTR_DOMAIN], domain)
self.assertEqual(
self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
acc.char_on.client_update_value(False) await hass.async_add_job(acc.char_on.client_update_value, True)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_turn_on
self.events[1].data[ATTR_DOMAIN], domain) assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual(
self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
def test_remote_set_state(self): await hass.async_add_job(acc.char_on.client_update_value, False)
"""Test service call for remote as domain.""" await hass.async_block_till_done()
entity_id = 'remote.test' assert call_turn_off
domain = split_entity_id(entity_id)[0] assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
acc = Switch(self.hass, 'Switch', entity_id, 2, config=None)
acc.run()
self.assertEqual(acc.char_on.value, False)
# Set from HomeKit
acc.char_on.client_update_value(True)
self.hass.block_till_done()
self.assertEqual(
self.events[0].data[ATTR_DOMAIN], domain)
self.assertEqual(
self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
self.assertEqual(acc.char_on.value, True)
def test_input_boolean_set_state(self):
"""Test service call for remote as domain."""
entity_id = 'input_boolean.test'
domain = split_entity_id(entity_id)[0]
acc = Switch(self.hass, 'Switch', entity_id, 2, config=None)
acc.run()
self.assertEqual(acc.char_on.value, False)
# Set from HomeKit
acc.char_on.client_update_value(True)
self.hass.block_till_done()
self.assertEqual(
self.events[0].data[ATTR_DOMAIN], domain)
self.assertEqual(
self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
self.assertEqual(acc.char_on.value, True)

View File

@ -1,364 +1,347 @@
"""Test different accessory types: Thermostats.""" """Test different accessory types: Thermostats."""
import unittest from collections import namedtuple
import pytest
from homeassistant.core import callback
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE, DOMAIN, 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.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SERVICE, ATTR_SERVICE_DATA, ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
ATTR_UNIT_OF_MEASUREMENT, EVENT_CALL_SERVICE,
STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT) STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.test_accessories import patch_debounce
class TestHomekitThermostats(unittest.TestCase): @pytest.fixture(scope='module')
"""Test class for all accessory types regarding thermostats.""" def cls(request):
"""Patch debounce decorator during import of type_thermostats."""
@classmethod patcher = patch_debounce()
def setUpClass(cls): patcher.start()
"""Setup Thermostat class import and debounce patcher.""" _import = __import__('homeassistant.components.homekit.type_thermostats',
cls.patcher = patch_debounce()
cls.patcher.start()
_import = __import__(
'homeassistant.components.homekit.type_thermostats',
fromlist=['Thermostat']) fromlist=['Thermostat'])
cls.thermostat_cls = _import.Thermostat request.addfinalizer(patcher.stop)
patcher_tuple = namedtuple('Cls', ['thermostat'])
return patcher_tuple(thermostat=_import.Thermostat)
@classmethod
def tearDownClass(cls):
"""Stop debounce patcher."""
cls.patcher.stop()
def setUp(self): async def test_default_thermostat(hass, cls):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_default_thermostat(self):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
climate = 'climate.test' entity_id = 'climate.test'
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0}) hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.thermostat_cls(self.hass, 'Climate', climate, acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.aid, 2) assert acc.aid == 2
self.assertEqual(acc.category, 9) # Thermostat assert acc.category == 9 # Thermostat
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 0) assert acc.char_target_heat_cool.value == 0
self.assertEqual(acc.char_current_temp.value, 21.0) assert acc.char_current_temp.value == 21.0
self.assertEqual(acc.char_target_temp.value, 21.0) assert acc.char_target_temp.value == 21.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.assertEqual(acc.char_cooling_thresh_temp, None) assert acc.char_cooling_thresh_temp is None
self.assertEqual(acc.char_heating_thresh_temp, None) assert acc.char_heating_thresh_temp is None
self.hass.states.set(climate, STATE_HEAT, hass.states.async_set(entity_id, STATE_HEAT,
{ATTR_OPERATION_MODE: STATE_HEAT, {ATTR_OPERATION_MODE: STATE_HEAT,
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 18.0, ATTR_CURRENT_TEMPERATURE: 18.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 1) assert acc.char_current_heat_cool.value == 1
self.assertEqual(acc.char_target_heat_cool.value, 1) assert acc.char_target_heat_cool.value == 1
self.assertEqual(acc.char_current_temp.value, 18.0) assert acc.char_current_temp.value == 18.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_HEAT, hass.states.async_set(entity_id, STATE_HEAT,
{ATTR_OPERATION_MODE: STATE_HEAT, {ATTR_OPERATION_MODE: STATE_HEAT,
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 23.0, ATTR_CURRENT_TEMPERATURE: 23.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 1) assert acc.char_target_heat_cool.value == 1
self.assertEqual(acc.char_current_temp.value, 23.0) assert acc.char_current_temp.value == 23.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_COOL, hass.states.async_set(entity_id, STATE_COOL,
{ATTR_OPERATION_MODE: STATE_COOL, {ATTR_OPERATION_MODE: STATE_COOL,
ATTR_TEMPERATURE: 20.0, ATTR_TEMPERATURE: 20.0,
ATTR_CURRENT_TEMPERATURE: 25.0, ATTR_CURRENT_TEMPERATURE: 25.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 20.0) assert acc.char_target_temp.value == 20.0
self.assertEqual(acc.char_current_heat_cool.value, 2) assert acc.char_current_heat_cool.value == 2
self.assertEqual(acc.char_target_heat_cool.value, 2) assert acc.char_target_heat_cool.value == 2
self.assertEqual(acc.char_current_temp.value, 25.0) assert acc.char_current_temp.value == 25.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_COOL, hass.states.async_set(entity_id, STATE_COOL,
{ATTR_OPERATION_MODE: STATE_COOL, {ATTR_OPERATION_MODE: STATE_COOL,
ATTR_TEMPERATURE: 20.0, ATTR_TEMPERATURE: 20.0,
ATTR_CURRENT_TEMPERATURE: 19.0, ATTR_CURRENT_TEMPERATURE: 19.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 20.0) assert acc.char_target_temp.value == 20.0
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 2) assert acc.char_target_heat_cool.value == 2
self.assertEqual(acc.char_current_temp.value, 19.0) assert acc.char_current_temp.value == 19.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_OFF, hass.states.async_set(entity_id, STATE_OFF,
{ATTR_OPERATION_MODE: STATE_OFF, {ATTR_OPERATION_MODE: STATE_OFF,
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 18.0, ATTR_CURRENT_TEMPERATURE: 18.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 0) assert acc.char_target_heat_cool.value == 0
self.assertEqual(acc.char_current_temp.value, 18.0) assert acc.char_current_temp.value == 18.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL], ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 18.0, ATTR_CURRENT_TEMPERATURE: 18.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 1) assert acc.char_current_heat_cool.value == 1
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 18.0) assert acc.char_current_temp.value == 18.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL], ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 25.0, ATTR_CURRENT_TEMPERATURE: 25.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 2) assert acc.char_current_heat_cool.value == 2
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 25.0) assert acc.char_current_temp.value == 25.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL], ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
ATTR_TEMPERATURE: 22.0, ATTR_TEMPERATURE: 22.0,
ATTR_CURRENT_TEMPERATURE: 22.0, ATTR_CURRENT_TEMPERATURE: 22.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 22.0) assert acc.char_current_temp.value == 22.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
# Set from HomeKit # Set from HomeKit
acc.char_target_temp.client_update_value(19.0) call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
self.hass.block_till_done() call_set_operation_mode = async_mock_service(hass, DOMAIN,
self.assertEqual( 'set_operation_mode')
self.events[0].data[ATTR_SERVICE], 'set_temperature')
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA][ATTR_TEMPERATURE], 19.0)
self.assertEqual(acc.char_target_temp.value, 19.0)
acc.char_target_heat_cool.client_update_value(1) await hass.async_add_job(acc.char_target_temp.client_update_value, 19.0)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_set_temperature
self.events[1].data[ATTR_SERVICE], 'set_operation_mode') assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_set_temperature[0].data[ATTR_TEMPERATURE] == 19.0
self.events[1].data[ATTR_SERVICE_DATA][ATTR_OPERATION_MODE], assert acc.char_target_temp.value == 19.0
STATE_HEAT)
self.assertEqual(acc.char_target_heat_cool.value, 1)
def test_auto_thermostat(self): await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
await hass.async_block_till_done()
assert call_set_operation_mode
assert call_set_operation_mode[0].data[ATTR_ENTITY_ID] == entity_id
assert call_set_operation_mode[0].data[ATTR_OPERATION_MODE] == STATE_HEAT
assert acc.char_target_heat_cool.value == 1
async def test_auto_thermostat(hass, cls):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
climate = 'climate.test' entity_id = 'climate.test'
# support_auto = True # support_auto = True
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6}) hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.thermostat_cls(self.hass, 'Climate', climate, acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0) assert acc.char_cooling_thresh_temp.value == 23.0
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0) assert acc.char_heating_thresh_temp.value == 19.0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_TARGET_TEMP_HIGH: 22.0, ATTR_TARGET_TEMP_HIGH: 22.0,
ATTR_TARGET_TEMP_LOW: 20.0, ATTR_TARGET_TEMP_LOW: 20.0,
ATTR_CURRENT_TEMPERATURE: 18.0, ATTR_CURRENT_TEMPERATURE: 18.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_heating_thresh_temp.value, 20.0) assert acc.char_heating_thresh_temp.value == 20.0
self.assertEqual(acc.char_cooling_thresh_temp.value, 22.0) assert acc.char_cooling_thresh_temp.value == 22.0
self.assertEqual(acc.char_current_heat_cool.value, 1) assert acc.char_current_heat_cool.value == 1
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 18.0) assert acc.char_current_temp.value == 18.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_TARGET_TEMP_HIGH: 23.0, ATTR_TARGET_TEMP_HIGH: 23.0,
ATTR_TARGET_TEMP_LOW: 19.0, ATTR_TARGET_TEMP_LOW: 19.0,
ATTR_CURRENT_TEMPERATURE: 24.0, ATTR_CURRENT_TEMPERATURE: 24.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0) assert acc.char_heating_thresh_temp.value == 19.0
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0) assert acc.char_cooling_thresh_temp.value == 23.0
self.assertEqual(acc.char_current_heat_cool.value, 2) assert acc.char_current_heat_cool.value == 2
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 24.0) assert acc.char_current_temp.value == 24.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_TARGET_TEMP_HIGH: 23.0, ATTR_TARGET_TEMP_HIGH: 23.0,
ATTR_TARGET_TEMP_LOW: 19.0, ATTR_TARGET_TEMP_LOW: 19.0,
ATTR_CURRENT_TEMPERATURE: 21.0, ATTR_CURRENT_TEMPERATURE: 21.0,
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}) ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0) assert acc.char_heating_thresh_temp.value == 19.0
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0) assert acc.char_cooling_thresh_temp.value == 23.0
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 3) assert acc.char_target_heat_cool.value == 3
self.assertEqual(acc.char_current_temp.value, 21.0) assert acc.char_current_temp.value == 21.0
self.assertEqual(acc.char_display_units.value, 0) assert acc.char_display_units.value == 0
# Set from HomeKit # Set from HomeKit
acc.char_heating_thresh_temp.client_update_value(20.0) call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
self.hass.block_till_done()
self.assertEqual(
self.events[0].data[ATTR_SERVICE], 'set_temperature')
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA][ATTR_TARGET_TEMP_LOW], 20.0)
self.assertEqual(acc.char_heating_thresh_temp.value, 20.0)
acc.char_cooling_thresh_temp.client_update_value(25.0) await hass.async_add_job(
self.hass.block_till_done() acc.char_heating_thresh_temp.client_update_value, 20.0)
self.assertEqual( await hass.async_block_till_done()
self.events[1].data[ATTR_SERVICE], 'set_temperature') assert call_set_temperature[0]
self.assertEqual( assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
self.events[1].data[ATTR_SERVICE_DATA][ATTR_TARGET_TEMP_HIGH], assert call_set_temperature[0].data[ATTR_TARGET_TEMP_LOW] == 20.0
25.0) assert acc.char_heating_thresh_temp.value == 20.0
self.assertEqual(acc.char_cooling_thresh_temp.value, 25.0)
def test_power_state(self): await hass.async_add_job(
acc.char_cooling_thresh_temp.client_update_value, 25.0)
await hass.async_block_till_done()
assert call_set_temperature[1]
assert call_set_temperature[1].data[ATTR_ENTITY_ID] == entity_id
assert call_set_temperature[1].data[ATTR_TARGET_TEMP_HIGH] == 25.0
assert acc.char_cooling_thresh_temp.value == 25.0
async def test_power_state(hass, cls):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
climate = 'climate.test' entity_id = 'climate.test'
# SUPPORT_ON_OFF = True # SUPPORT_ON_OFF = True
self.hass.states.set(climate, STATE_HEAT, hass.states.async_set(entity_id, STATE_HEAT,
{ATTR_SUPPORTED_FEATURES: 4096, {ATTR_SUPPORTED_FEATURES: 4096,
ATTR_OPERATION_MODE: STATE_HEAT, ATTR_OPERATION_MODE: STATE_HEAT,
ATTR_TEMPERATURE: 23.0, ATTR_TEMPERATURE: 23.0,
ATTR_CURRENT_TEMPERATURE: 18.0}) ATTR_CURRENT_TEMPERATURE: 18.0})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.thermostat_cls(self.hass, 'Climate', climate, acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run() assert acc.support_power_state is True
self.assertTrue(acc.support_power_state)
self.assertEqual(acc.char_current_heat_cool.value, 1) assert acc.char_current_heat_cool.value == 1
self.assertEqual(acc.char_target_heat_cool.value, 1) assert acc.char_target_heat_cool.value == 1
self.hass.states.set(climate, STATE_OFF, hass.states.async_set(entity_id, STATE_OFF,
{ATTR_OPERATION_MODE: STATE_HEAT, {ATTR_OPERATION_MODE: STATE_HEAT,
ATTR_TEMPERATURE: 23.0, ATTR_TEMPERATURE: 23.0,
ATTR_CURRENT_TEMPERATURE: 18.0}) ATTR_CURRENT_TEMPERATURE: 18.0})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 0) assert acc.char_target_heat_cool.value == 0
self.hass.states.set(climate, STATE_OFF, hass.states.async_set(entity_id, STATE_OFF,
{ATTR_OPERATION_MODE: STATE_OFF, {ATTR_OPERATION_MODE: STATE_OFF,
ATTR_TEMPERATURE: 23.0, ATTR_TEMPERATURE: 23.0,
ATTR_CURRENT_TEMPERATURE: 18.0}) ATTR_CURRENT_TEMPERATURE: 18.0})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_current_heat_cool.value, 0) assert acc.char_current_heat_cool.value == 0
self.assertEqual(acc.char_target_heat_cool.value, 0) assert acc.char_target_heat_cool.value == 0
# Set from HomeKit # Set from HomeKit
acc.char_target_heat_cool.client_update_value(1) call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
self.hass.block_till_done() call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
self.assertEqual( call_set_operation_mode = async_mock_service(hass, DOMAIN,
self.events[0].data[ATTR_SERVICE], 'turn_on') 'set_operation_mode')
self.assertEqual(
self.events[0].data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID],
climate)
self.assertEqual(
self.events[1].data[ATTR_SERVICE], 'set_operation_mode')
self.assertEqual(
self.events[1].data[ATTR_SERVICE_DATA][ATTR_OPERATION_MODE],
STATE_HEAT)
self.assertEqual(acc.char_target_heat_cool.value, 1)
acc.char_target_heat_cool.client_update_value(0) await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual( assert call_turn_on
self.events[2].data[ATTR_SERVICE], 'turn_off') assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
self.assertEqual( assert call_set_operation_mode
self.events[2].data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID], assert call_set_operation_mode[0].data[ATTR_ENTITY_ID] == entity_id
climate) assert call_set_operation_mode[0].data[ATTR_OPERATION_MODE] == STATE_HEAT
self.assertEqual(acc.char_target_heat_cool.value, 0) assert acc.char_target_heat_cool.value == 1
def test_thermostat_fahrenheit(self): await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 0)
await hass.async_block_till_done()
assert call_turn_off
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
assert acc.char_target_heat_cool.value == 0
async def test_thermostat_fahrenheit(hass, cls):
"""Test if accessory and HA are updated accordingly.""" """Test if accessory and HA are updated accordingly."""
climate = 'climate.test' entity_id = 'climate.test'
# support_auto = True # support_auto = True
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6}) hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
self.hass.block_till_done() await hass.async_block_till_done()
acc = self.thermostat_cls(self.hass, 'Climate', climate, acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
2, config=None) await hass.async_add_job(acc.run)
acc.run()
self.hass.states.set(climate, STATE_AUTO, hass.states.async_set(entity_id, STATE_AUTO,
{ATTR_OPERATION_MODE: STATE_AUTO, {ATTR_OPERATION_MODE: STATE_AUTO,
ATTR_TARGET_TEMP_HIGH: 75.2, ATTR_TARGET_TEMP_HIGH: 75.2,
ATTR_TARGET_TEMP_LOW: 68, ATTR_TARGET_TEMP_LOW: 68,
ATTR_TEMPERATURE: 71.6, ATTR_TEMPERATURE: 71.6,
ATTR_CURRENT_TEMPERATURE: 73.4, ATTR_CURRENT_TEMPERATURE: 73.4,
ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT}) ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
self.hass.block_till_done() await hass.async_block_till_done()
self.assertEqual(acc.char_heating_thresh_temp.value, 20.0) assert acc.char_heating_thresh_temp.value == 20.0
self.assertEqual(acc.char_cooling_thresh_temp.value, 24.0) assert acc.char_cooling_thresh_temp.value == 24.0
self.assertEqual(acc.char_current_temp.value, 23.0) assert acc.char_current_temp.value == 23.0
self.assertEqual(acc.char_target_temp.value, 22.0) assert acc.char_target_temp.value == 22.0
self.assertEqual(acc.char_display_units.value, 1) assert acc.char_display_units.value == 1
# Set from HomeKit # Set from HomeKit
acc.char_cooling_thresh_temp.client_update_value(23) call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
self.hass.block_till_done()
service_data = self.events[-1].data[ATTR_SERVICE_DATA]
self.assertEqual(service_data[ATTR_TARGET_TEMP_HIGH], 73.4)
self.assertEqual(service_data[ATTR_TARGET_TEMP_LOW], 68)
acc.char_heating_thresh_temp.client_update_value(22) await hass.async_add_job(
self.hass.block_till_done() acc.char_cooling_thresh_temp.client_update_value, 23)
service_data = self.events[-1].data[ATTR_SERVICE_DATA] await hass.async_block_till_done()
self.assertEqual(service_data[ATTR_TARGET_TEMP_HIGH], 73.4) assert call_set_temperature[0]
self.assertEqual(service_data[ATTR_TARGET_TEMP_LOW], 71.6) assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
assert call_set_temperature[0].data[ATTR_TARGET_TEMP_HIGH] == 73.4
assert call_set_temperature[0].data[ATTR_TARGET_TEMP_LOW] == 68
acc.char_target_temp.client_update_value(24.0) await hass.async_add_job(
self.hass.block_till_done() acc.char_heating_thresh_temp.client_update_value, 22)
service_data = self.events[-1].data[ATTR_SERVICE_DATA] await hass.async_block_till_done()
self.assertEqual(service_data[ATTR_TEMPERATURE], 75.2) assert call_set_temperature[1]
assert call_set_temperature[1].data[ATTR_ENTITY_ID] == entity_id
assert call_set_temperature[1].data[ATTR_TARGET_TEMP_HIGH] == 73.4
assert call_set_temperature[1].data[ATTR_TARGET_TEMP_LOW] == 71.6
await hass.async_add_job(acc.char_target_temp.client_update_value, 24.0)
await hass.async_block_till_done()
assert call_set_temperature[2]
assert call_set_temperature[2].data[ATTR_ENTITY_ID] == entity_id
assert call_set_temperature[2].data[ATTR_TEMPERATURE] == 75.2

View File

@ -1,25 +1,20 @@
"""Test HomeKit util module.""" """Test HomeKit util module."""
import unittest
import voluptuous as vol
import pytest import pytest
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.components.homekit.accessories import HomeBridge from homeassistant.components.homekit.accessories import HomeBridge
from homeassistant.components.homekit.const import HOMEKIT_NOTIFY_ID from homeassistant.components.homekit.const import HOMEKIT_NOTIFY_ID
from homeassistant.components.homekit.util import ( from homeassistant.components.homekit.util import (
show_setup_message, dismiss_setup_message, convert_to_float, show_setup_message, dismiss_setup_message, convert_to_float,
temperature_to_homekit, temperature_to_states, ATTR_CODE, temperature_to_homekit, temperature_to_states, density_to_air_quality)
density_to_air_quality)
from homeassistant.components.homekit.util import validate_entity_config \ from homeassistant.components.homekit.util import validate_entity_config \
as vec as vec
from homeassistant.components.persistent_notification import ( from homeassistant.components.persistent_notification import (
SERVICE_CREATE, SERVICE_DISMISS, ATTR_NOTIFICATION_ID) DOMAIN, ATTR_NOTIFICATION_ID)
from homeassistant.const import ( from homeassistant.const import (
EVENT_CALL_SERVICE, ATTR_DOMAIN, ATTR_SERVICE, ATTR_SERVICE_DATA, ATTR_CODE, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT)
TEMP_CELSIUS, TEMP_FAHRENHEIT, STATE_UNKNOWN)
from tests.common import get_test_home_assistant from tests.common import async_mock_service
def test_validate_entity_config(): def test_validate_entity_config():
@ -68,51 +63,27 @@ def test_density_to_air_quality():
assert density_to_air_quality(300) == 5 assert density_to_air_quality(300) == 5
class TestUtil(unittest.TestCase): async def test_show_setup_msg(hass):
"""Test all HomeKit util methods."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.events = []
@callback
def record_event(event):
"""Track called event."""
self.events.append(event)
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_show_setup_msg(self):
"""Test show setup message as persistence notification.""" """Test show setup message as persistence notification."""
bridge = HomeBridge(self.hass) bridge = HomeBridge(hass)
show_setup_message(self.hass, bridge) call_create_notification = async_mock_service(hass, DOMAIN, 'create')
self.hass.block_till_done()
data = self.events[0].data await hass.async_add_job(show_setup_message, hass, bridge)
self.assertEqual( await hass.async_block_till_done()
data.get(ATTR_DOMAIN, None), 'persistent_notification')
self.assertEqual(data.get(ATTR_SERVICE, None), SERVICE_CREATE)
self.assertNotEqual(data.get(ATTR_SERVICE_DATA, None), None)
self.assertEqual(
data[ATTR_SERVICE_DATA].get(ATTR_NOTIFICATION_ID, None),
HOMEKIT_NOTIFY_ID)
def test_dismiss_setup_msg(self): assert call_create_notification
assert call_create_notification[0].data[ATTR_NOTIFICATION_ID] == \
HOMEKIT_NOTIFY_ID
async def test_dismiss_setup_msg(hass):
"""Test dismiss setup message.""" """Test dismiss setup message."""
dismiss_setup_message(self.hass) call_dismiss_notification = async_mock_service(hass, DOMAIN, 'dismiss')
self.hass.block_till_done()
data = self.events[0].data await hass.async_add_job(dismiss_setup_message, hass)
self.assertEqual( await hass.async_block_till_done()
data.get(ATTR_DOMAIN, None), 'persistent_notification')
self.assertEqual(data.get(ATTR_SERVICE, None), SERVICE_DISMISS) assert call_dismiss_notification
self.assertNotEqual(data.get(ATTR_SERVICE_DATA, None), None) assert call_dismiss_notification[0].data[ATTR_NOTIFICATION_ID] == \
self.assertEqual( HOMEKIT_NOTIFY_ID
data[ATTR_SERVICE_DATA].get(ATTR_NOTIFICATION_ID, None),
HOMEKIT_NOTIFY_ID)