mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Rewritten HomeKit tests (#14377)
* Use pytest fixtures and parametrize * Use async
This commit is contained in:
parent
6843893d9f
commit
8fcf085829
@ -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,141 +21,122 @@ 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."""
|
"""Test add_timeout decorator function."""
|
||||||
|
def demo_func(*args):
|
||||||
|
nonlocal arguments, counter
|
||||||
|
counter += 1
|
||||||
|
arguments = args
|
||||||
|
|
||||||
def test_debounce(self):
|
arguments = None
|
||||||
"""Test add_timeout decorator function."""
|
counter = 0
|
||||||
def demo_func(*args):
|
mock = Mock(hass=hass)
|
||||||
nonlocal arguments, counter
|
|
||||||
counter += 1
|
|
||||||
arguments = args
|
|
||||||
|
|
||||||
arguments = None
|
debounce_demo = debounce(demo_func)
|
||||||
counter = 0
|
assert debounce_demo.__name__ == 'demo_func'
|
||||||
hass = get_test_home_assistant()
|
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC)
|
||||||
mock = Mock(hass=hass)
|
|
||||||
|
|
||||||
debounce_demo = debounce(demo_func)
|
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||||
self.assertEqual(debounce_demo.__name__, 'demo_func')
|
await hass.async_add_job(debounce_demo, mock, 'value')
|
||||||
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC)
|
hass.bus.async_fire(
|
||||||
|
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert counter == 1
|
||||||
|
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')
|
||||||
hass.bus.fire(
|
await hass.async_add_job(debounce_demo, mock, 'value')
|
||||||
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
|
||||||
hass.block_till_done()
|
|
||||||
assert counter == 1
|
|
||||||
assert len(arguments) == 2
|
|
||||||
|
|
||||||
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
hass.bus.async_fire(
|
||||||
debounce_demo(mock, 'value')
|
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
||||||
debounce_demo(mock, 'value')
|
await hass.async_block_till_done()
|
||||||
|
assert counter == 2
|
||||||
|
|
||||||
hass.bus.fire(
|
|
||||||
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
|
|
||||||
hass.block_till_done()
|
|
||||||
assert counter == 2
|
|
||||||
|
|
||||||
hass.stop()
|
async def test_home_accessory(hass):
|
||||||
|
"""Test HomeAccessory class."""
|
||||||
|
acc = HomeAccessory(hass, 'Home Accessory', 'homekit.accessory', 2)
|
||||||
|
assert acc.hass == hass
|
||||||
|
assert acc.display_name == 'Home Accessory'
|
||||||
|
assert acc.category == 1 # Category.OTHER
|
||||||
|
assert len(acc.services) == 1
|
||||||
|
serv = acc.services[0] # SERV_ACCESSORY_INFO
|
||||||
|
assert serv.display_name == SERV_ACCESSORY_INFO
|
||||||
|
assert serv.get_characteristic(CHAR_NAME).value == 'Home Accessory'
|
||||||
|
assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
|
||||||
|
assert serv.get_characteristic(CHAR_MODEL).value == 'Homekit'
|
||||||
|
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
|
||||||
|
'homekit.accessory'
|
||||||
|
|
||||||
def test_home_accessory(self):
|
hass.states.async_set('homekit.accessory', 'on')
|
||||||
"""Test HomeAccessory class."""
|
await hass.async_block_till_done()
|
||||||
hass = get_test_home_assistant()
|
await hass.async_add_job(acc.run)
|
||||||
|
hass.states.async_set('homekit.accessory', 'off')
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
acc = HomeAccessory(hass, 'Home Accessory', 'homekit.accessory', 2)
|
acc = HomeAccessory('hass', 'test_name', 'test_model.demo', 2)
|
||||||
self.assertEqual(acc.hass, hass)
|
assert acc.display_name == 'test_name'
|
||||||
self.assertEqual(acc.display_name, 'Home Accessory')
|
assert acc.aid == 2
|
||||||
self.assertEqual(acc.category, 1) # Category.OTHER
|
assert len(acc.services) == 1
|
||||||
self.assertEqual(len(acc.services), 1)
|
serv = acc.services[0] # SERV_ACCESSORY_INFO
|
||||||
serv = acc.services[0] # SERV_ACCESSORY_INFO
|
assert serv.get_characteristic(CHAR_MODEL).value == 'Test Model'
|
||||||
self.assertEqual(serv.display_name, SERV_ACCESSORY_INFO)
|
|
||||||
self.assertEqual(
|
|
||||||
serv.get_characteristic(CHAR_NAME).value, 'Home Accessory')
|
|
||||||
self.assertEqual(
|
|
||||||
serv.get_characteristic(CHAR_MANUFACTURER).value, MANUFACTURER)
|
|
||||||
self.assertEqual(
|
|
||||||
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.block_till_done()
|
|
||||||
acc.run()
|
|
||||||
hass.states.set('homekit.accessory', 'off')
|
|
||||||
hass.block_till_done()
|
|
||||||
|
|
||||||
acc = HomeAccessory('hass', 'test_name', 'test_model.demo', 2)
|
def test_home_bridge():
|
||||||
self.assertEqual(acc.display_name, 'test_name')
|
"""Test HomeBridge class."""
|
||||||
self.assertEqual(acc.aid, 2)
|
bridge = HomeBridge('hass')
|
||||||
self.assertEqual(len(acc.services), 1)
|
assert bridge.hass == 'hass'
|
||||||
serv = acc.services[0] # SERV_ACCESSORY_INFO
|
assert bridge.display_name == BRIDGE_NAME
|
||||||
self.assertEqual(
|
assert bridge.category == 2 # Category.BRIDGE
|
||||||
serv.get_characteristic(CHAR_MODEL).value, 'Test Model')
|
assert len(bridge.services) == 1
|
||||||
|
serv = bridge.services[0] # SERV_ACCESSORY_INFO
|
||||||
|
assert serv.display_name == SERV_ACCESSORY_INFO
|
||||||
|
assert serv.get_characteristic(CHAR_NAME).value == BRIDGE_NAME
|
||||||
|
assert serv.get_characteristic(CHAR_FIRMWARE_REVISION).value == __version__
|
||||||
|
assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
|
||||||
|
assert serv.get_characteristic(CHAR_MODEL).value == BRIDGE_MODEL
|
||||||
|
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
|
||||||
|
BRIDGE_SERIAL_NUMBER
|
||||||
|
|
||||||
hass.stop()
|
bridge = HomeBridge('hass', 'test_name')
|
||||||
|
assert bridge.display_name == 'test_name'
|
||||||
|
assert len(bridge.services) == 1
|
||||||
|
serv = bridge.services[0] # SERV_ACCESSORY_INFO
|
||||||
|
|
||||||
def test_home_bridge(self):
|
# setup_message
|
||||||
"""Test HomeBridge class."""
|
bridge.setup_message()
|
||||||
bridge = HomeBridge('hass')
|
|
||||||
self.assertEqual(bridge.hass, 'hass')
|
|
||||||
self.assertEqual(bridge.display_name, BRIDGE_NAME)
|
|
||||||
self.assertEqual(bridge.category, 2) # Category.BRIDGE
|
|
||||||
self.assertEqual(len(bridge.services), 1)
|
|
||||||
serv = bridge.services[0] # SERV_ACCESSORY_INFO
|
|
||||||
self.assertEqual(serv.display_name, SERV_ACCESSORY_INFO)
|
|
||||||
self.assertEqual(
|
|
||||||
serv.get_characteristic(CHAR_NAME).value, BRIDGE_NAME)
|
|
||||||
self.assertEqual(
|
|
||||||
serv.get_characteristic(CHAR_FIRMWARE_REVISION).value, __version__)
|
|
||||||
self.assertEqual(
|
|
||||||
serv.get_characteristic(CHAR_MANUFACTURER).value, MANUFACTURER)
|
|
||||||
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')
|
# add_paired_client
|
||||||
self.assertEqual(bridge.display_name, 'test_name')
|
with patch('pyhap.accessory.Accessory.add_paired_client') \
|
||||||
self.assertEqual(len(bridge.services), 1)
|
as mock_add_paired_client, \
|
||||||
serv = bridge.services[0] # SERV_ACCESSORY_INFO
|
patch('homeassistant.components.homekit.accessories.'
|
||||||
|
'dismiss_setup_message') as mock_dissmiss_msg:
|
||||||
|
bridge.add_paired_client('client_uuid', 'client_public')
|
||||||
|
|
||||||
# setup_message
|
mock_add_paired_client.assert_called_with('client_uuid', 'client_public')
|
||||||
bridge.setup_message()
|
mock_dissmiss_msg.assert_called_with('hass')
|
||||||
|
|
||||||
# add_paired_client
|
# remove_paired_client
|
||||||
with patch('pyhap.accessory.Accessory.add_paired_client') \
|
with patch('pyhap.accessory.Accessory.remove_paired_client') \
|
||||||
as mock_add_paired_client, \
|
as mock_remove_paired_client, \
|
||||||
patch('homeassistant.components.homekit.accessories.'
|
patch('homeassistant.components.homekit.accessories.'
|
||||||
'dismiss_setup_message') as mock_dissmiss_msg:
|
'show_setup_message') as mock_show_msg:
|
||||||
bridge.add_paired_client('client_uuid', 'client_public')
|
bridge.remove_paired_client('client_uuid')
|
||||||
|
|
||||||
self.assertEqual(mock_add_paired_client.call_args,
|
mock_remove_paired_client.assert_called_with('client_uuid')
|
||||||
call('client_uuid', 'client_public'))
|
mock_show_msg.assert_called_with('hass', bridge)
|
||||||
self.assertEqual(mock_dissmiss_msg.call_args, call('hass'))
|
|
||||||
|
|
||||||
# remove_paired_client
|
|
||||||
with patch('pyhap.accessory.Accessory.remove_paired_client') \
|
|
||||||
as mock_remove_paired_client, \
|
|
||||||
patch('homeassistant.components.homekit.accessories.'
|
|
||||||
'show_setup_message') as mock_show_msg:
|
|
||||||
bridge.remove_paired_client('client_uuid')
|
|
||||||
|
|
||||||
self.assertEqual(
|
def test_home_driver():
|
||||||
mock_remove_paired_client.call_args, call('client_uuid'))
|
"""Test HomeDriver class."""
|
||||||
self.assertEqual(mock_show_msg.call_args, call('hass', bridge))
|
bridge = HomeBridge('hass')
|
||||||
|
ip_address = '127.0.0.1'
|
||||||
|
port = 51826
|
||||||
|
path = '.homekit.state'
|
||||||
|
|
||||||
def test_home_driver(self):
|
with patch('pyhap.accessory_driver.AccessoryDriver.__init__') \
|
||||||
"""Test HomeDriver class."""
|
as mock_driver:
|
||||||
bridge = HomeBridge('hass')
|
HomeDriver(bridge, ip_address, port, path)
|
||||||
ip_address = '127.0.0.1'
|
|
||||||
port = 51826
|
|
||||||
path = '.homekit.state'
|
|
||||||
|
|
||||||
with patch('pyhap.accessory_driver.AccessoryDriver.__init__') \
|
mock_driver.assert_called_with(bridge, ip_address, port, path)
|
||||||
as mock_driver:
|
|
||||||
HomeDriver(bridge, ip_address, port, path)
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
mock_driver.call_args, call(bridge, ip_address, port, path))
|
|
||||||
|
@ -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, {})
|
|
||||||
|
@ -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):
|
"""Test generate aid method."""
|
||||||
"""Stop debounce patcher."""
|
aid = generate_aid('demo.entity')
|
||||||
cls.patcher.stop()
|
assert isinstance(aid, int)
|
||||||
|
assert aid >= 2 and aid <= 18446744073709551615
|
||||||
|
|
||||||
def setUp(self):
|
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
|
||||||
"""Setup things to be run when tests are started."""
|
mock_adler32.side_effect = [0, 1]
|
||||||
self.hass = get_test_home_assistant()
|
assert generate_aid('demo.entity') is None
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""Stop down everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
def test_generate_aid(self):
|
async def test_setup_min(hass):
|
||||||
"""Test generate aid method."""
|
"""Test async_setup with min config options."""
|
||||||
aid = generate_aid('demo.entity')
|
with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
|
||||||
self.assertIsInstance(aid, int)
|
assert await setup.async_setup_component(
|
||||||
self.assertTrue(aid >= 2 and aid <= 18446744073709551615)
|
hass, DOMAIN, {DOMAIN: {}})
|
||||||
|
|
||||||
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
|
mock_homekit.assert_any_call(hass, DEFAULT_PORT, None, ANY, {})
|
||||||
mock_adler32.side_effect = [0, 1]
|
assert mock_homekit().setup.called is True
|
||||||
self.assertIsNone(generate_aid('demo.entity'))
|
|
||||||
|
|
||||||
@patch(PATH_HOMEKIT + '.HomeKit')
|
# Test auto start enabled
|
||||||
def test_setup_min(self, mock_homekit):
|
mock_homekit.reset_mock()
|
||||||
"""Test async_setup with min config options."""
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
self.assertTrue(setup.setup_component(
|
await hass.async_block_till_done()
|
||||||
self.hass, DOMAIN, {DOMAIN: {}}))
|
|
||||||
|
|
||||||
self.assertEqual(mock_homekit.mock_calls, [
|
mock_homekit().start.assert_called_with(ANY)
|
||||||
call(self.hass, DEFAULT_PORT, None, ANY, {}),
|
|
||||||
call().setup()])
|
|
||||||
|
|
||||||
# Test auto start enabled
|
|
||||||
mock_homekit.reset_mock()
|
|
||||||
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
self.assertEqual(mock_homekit.mock_calls, [call().start(ANY)])
|
async def test_setup_auto_start_disabled(hass):
|
||||||
|
"""Test async_setup with auto start disabled and test service calls."""
|
||||||
|
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
|
||||||
|
CONF_IP_ADDRESS: '172.0.0.0'}}
|
||||||
|
|
||||||
@patch(PATH_HOMEKIT + '.HomeKit')
|
with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
|
||||||
def test_setup_auto_start_disabled(self, mock_homekit):
|
|
||||||
"""Test async_setup with auto start disabled and test service calls."""
|
|
||||||
mock_homekit.return_value = homekit = Mock()
|
mock_homekit.return_value = homekit = Mock()
|
||||||
|
assert await setup.async_setup_component(
|
||||||
|
hass, DOMAIN, config)
|
||||||
|
|
||||||
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
|
mock_homekit.assert_any_call(hass, 11111, '172.0.0.0', ANY, {})
|
||||||
CONF_IP_ADDRESS: '172.0.0.0'}}
|
assert mock_homekit().setup.called is True
|
||||||
self.assertTrue(setup.setup_component(
|
|
||||||
self.hass, DOMAIN, config))
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
self.assertEqual(mock_homekit.mock_calls, [
|
# Test auto_start disabled
|
||||||
call(self.hass, 11111, '172.0.0.0', ANY, {}),
|
homekit.reset_mock()
|
||||||
call().setup()])
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert homekit.start.called is False
|
||||||
|
|
||||||
# Test auto_start disabled
|
# Test start call with driver is ready
|
||||||
homekit.reset_mock()
|
homekit.reset_mock()
|
||||||
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
|
homekit.status = STATUS_READY
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(homekit.mock_calls, [])
|
|
||||||
|
|
||||||
# Test start call with driver is ready
|
await hass.services.async_call(
|
||||||
homekit.reset_mock()
|
DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
|
||||||
homekit.status = STATUS_READY
|
assert homekit.start.called is True
|
||||||
|
|
||||||
self.hass.services.call('homekit', 'start')
|
# Test start call with driver started
|
||||||
self.assertEqual(homekit.mock_calls, [call.start()])
|
homekit.reset_mock()
|
||||||
|
homekit.status = STATUS_STOPPED
|
||||||
|
|
||||||
# Test start call with driver started
|
await hass.services.async_call(
|
||||||
homekit.reset_mock()
|
DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
|
||||||
homekit.status = STATUS_STOPPED
|
assert homekit.start.called is False
|
||||||
|
|
||||||
self.hass.services.call(DOMAIN, SERVICE_HOMEKIT_START)
|
|
||||||
self.assertEqual(homekit.mock_calls, [])
|
|
||||||
|
|
||||||
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):
|
|
||||||
"""Test setup with given IP address."""
|
|
||||||
homekit = HomeKit(self.hass, DEFAULT_PORT, '172.0.0.0', {}, {})
|
|
||||||
|
|
||||||
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
|
async def test_homekit_setup_ip_address(hass):
|
||||||
homekit.setup()
|
"""Test setup with given IP address."""
|
||||||
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
|
homekit = HomeKit(hass, DEFAULT_PORT, '172.0.0.0', {}, {})
|
||||||
|
|
||||||
def test_homekit_add_accessory(self):
|
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
|
||||||
"""Add accessory if config exists and get_acc returns an accessory."""
|
await hass.async_add_job(homekit.setup)
|
||||||
homekit = HomeKit(self.hass, None, None, lambda entity_id: True, {})
|
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
|
||||||
homekit.bridge = HomeBridge(self.hass)
|
|
||||||
|
|
||||||
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
|
|
||||||
as mock_add_acc, \
|
|
||||||
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
|
||||||
mock_get_acc.side_effect = [None, 'acc', None]
|
|
||||||
homekit.add_bridge_accessory(State('light.demo', 'on'))
|
|
||||||
self.assertEqual(mock_get_acc.call_args,
|
|
||||||
call(self.hass, ANY, 363398124, {}))
|
|
||||||
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):
|
async def test_homekit_add_accessory(hass):
|
||||||
"""Test the entity filter."""
|
"""Add accessory if config exists and get_acc returns an accessory."""
|
||||||
entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
|
homekit = HomeKit(hass, None, None, lambda entity_id: True, {})
|
||||||
homekit = HomeKit(self.hass, None, None, entity_filter, {})
|
homekit.bridge = HomeBridge(hass)
|
||||||
|
|
||||||
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
|
||||||
mock_get_acc.return_value = None
|
as mock_add_acc, \
|
||||||
|
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
||||||
|
|
||||||
homekit.add_bridge_accessory(State('cover.test', 'open'))
|
mock_get_acc.side_effect = [None, 'acc', None]
|
||||||
self.assertTrue(mock_get_acc.called)
|
homekit.add_bridge_accessory(State('light.demo', 'on'))
|
||||||
mock_get_acc.reset_mock()
|
mock_get_acc.assert_called_with(hass, ANY, 363398124, {})
|
||||||
|
assert mock_add_acc.called is False
|
||||||
|
|
||||||
homekit.add_bridge_accessory(State('demo.test', 'on'))
|
homekit.add_bridge_accessory(State('demo.test', 'on'))
|
||||||
self.assertTrue(mock_get_acc.called)
|
mock_get_acc.assert_called_with(hass, ANY, 294192020, {})
|
||||||
mock_get_acc.reset_mock()
|
assert mock_add_acc.called is True
|
||||||
|
|
||||||
homekit.add_bridge_accessory(State('light.demo', 'light'))
|
homekit.add_bridge_accessory(State('demo.test_2', 'on'))
|
||||||
self.assertFalse(mock_get_acc.called)
|
mock_get_acc.assert_called_with(hass, ANY, 429982757, {})
|
||||||
|
mock_add_acc.assert_called_with('acc')
|
||||||
|
|
||||||
@patch(PATH_HOMEKIT + '.show_setup_message')
|
|
||||||
@patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory')
|
|
||||||
def test_homekit_start(self, mock_add_bridge_acc, mock_show_setup_msg):
|
|
||||||
"""Test HomeKit start method."""
|
|
||||||
homekit = HomeKit(self.hass, None, None, {}, {'cover.demo': {}})
|
|
||||||
homekit.bridge = HomeBridge(self.hass)
|
|
||||||
homekit.driver = Mock()
|
|
||||||
|
|
||||||
self.hass.states.set('light.demo', 'on')
|
async def test_homekit_entity_filter(hass):
|
||||||
state = self.hass.states.all()[0]
|
"""Test the entity filter."""
|
||||||
|
entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
|
||||||
|
homekit = HomeKit(hass, None, None, entity_filter, {})
|
||||||
|
|
||||||
homekit.start()
|
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
||||||
self.hass.block_till_done()
|
mock_get_acc.return_value = None
|
||||||
|
|
||||||
self.assertEqual(mock_add_bridge_acc.mock_calls, [call(state)])
|
homekit.add_bridge_accessory(State('cover.test', 'open'))
|
||||||
self.assertEqual(mock_show_setup_msg.mock_calls, [
|
assert mock_get_acc.called is True
|
||||||
call(self.hass, homekit.bridge)])
|
mock_get_acc.reset_mock()
|
||||||
self.assertEqual(homekit.driver.mock_calls, [call.start()])
|
|
||||||
self.assertEqual(homekit.status, STATUS_RUNNING)
|
|
||||||
|
|
||||||
# Test start() if already started
|
homekit.add_bridge_accessory(State('demo.test', 'on'))
|
||||||
homekit.driver.reset_mock()
|
assert mock_get_acc.called is True
|
||||||
homekit.start()
|
mock_get_acc.reset_mock()
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(homekit.driver.mock_calls, [])
|
|
||||||
|
|
||||||
def test_homekit_stop(self):
|
homekit.add_bridge_accessory(State('light.demo', 'light'))
|
||||||
"""Test HomeKit stop method."""
|
assert mock_get_acc.called is False
|
||||||
homekit = HomeKit(self.hass, None, None, None, None)
|
|
||||||
homekit.driver = Mock()
|
|
||||||
|
|
||||||
self.assertEqual(homekit.status, STATUS_READY)
|
|
||||||
homekit.stop()
|
|
||||||
self.hass.block_till_done()
|
|
||||||
homekit.status = STATUS_WAIT
|
|
||||||
homekit.stop()
|
|
||||||
self.hass.block_till_done()
|
|
||||||
homekit.status = STATUS_STOPPED
|
|
||||||
homekit.stop()
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertFalse(homekit.driver.stop.called)
|
|
||||||
|
|
||||||
# Test if driver is started
|
async def test_homekit_start(hass, debounce_patcher):
|
||||||
homekit.status = STATUS_RUNNING
|
"""Test HomeKit start method."""
|
||||||
homekit.stop()
|
homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}})
|
||||||
self.hass.block_till_done()
|
homekit.bridge = HomeBridge(hass)
|
||||||
self.assertTrue(homekit.driver.stop.called)
|
homekit.driver = Mock()
|
||||||
|
|
||||||
|
hass.states.async_set('light.demo', 'on')
|
||||||
|
state = hass.states.async_all()[0]
|
||||||
|
|
||||||
|
with patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory') as \
|
||||||
|
mock_add_acc, \
|
||||||
|
patch(PATH_HOMEKIT + '.show_setup_message') as mock_setup_msg:
|
||||||
|
await hass.async_add_job(homekit.start)
|
||||||
|
|
||||||
|
mock_add_acc.assert_called_with(state)
|
||||||
|
mock_setup_msg.assert_called_with(hass, homekit.bridge)
|
||||||
|
assert homekit.driver.start.called is True
|
||||||
|
assert homekit.status == STATUS_RUNNING
|
||||||
|
|
||||||
|
# Test start() if already started
|
||||||
|
homekit.driver.reset_mock()
|
||||||
|
await hass.async_add_job(homekit.start)
|
||||||
|
assert homekit.driver.start.called is False
|
||||||
|
|
||||||
|
|
||||||
|
async def test_homekit_stop(hass):
|
||||||
|
"""Test HomeKit stop method."""
|
||||||
|
homekit = HomeKit(hass, None, None, None, None)
|
||||||
|
homekit.driver = Mock()
|
||||||
|
|
||||||
|
assert homekit.status == STATUS_READY
|
||||||
|
await hass.async_add_job(homekit.stop)
|
||||||
|
homekit.status = STATUS_WAIT
|
||||||
|
await hass.async_add_job(homekit.stop)
|
||||||
|
homekit.status = STATUS_STOPPED
|
||||||
|
await hass.async_add_job(homekit.stop)
|
||||||
|
assert homekit.driver.stop.called is False
|
||||||
|
|
||||||
|
# Test if driver is started
|
||||||
|
homekit.status = STATUS_RUNNING
|
||||||
|
await hass.async_add_job(homekit.stop)
|
||||||
|
assert homekit.driver.stop.called is True
|
||||||
|
@ -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."""
|
||||||
|
patcher = patch_debounce()
|
||||||
|
patcher.start()
|
||||||
|
_import = __import__('homeassistant.components.homekit.type_covers',
|
||||||
|
fromlist=['GarageDoorOpener', 'WindowCovering,',
|
||||||
|
'WindowCoveringBasic'])
|
||||||
|
request.addfinalizer(patcher.stop)
|
||||||
|
patcher_tuple = namedtuple('Cls', ['window', 'window_basic', 'garage'])
|
||||||
|
return patcher_tuple(window=_import.WindowCovering,
|
||||||
|
window_basic=_import.WindowCoveringBasic,
|
||||||
|
garage=_import.GarageDoorOpener)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""Setup Light class import and debounce patcher."""
|
|
||||||
cls.patcher = patch_debounce()
|
|
||||||
cls.patcher.start()
|
|
||||||
_import = __import__('homeassistant.components.homekit.type_covers',
|
|
||||||
fromlist=['GarageDoorOpener', 'WindowCovering,',
|
|
||||||
'WindowCoveringBasic'])
|
|
||||||
cls.garage_cls = _import.GarageDoorOpener
|
|
||||||
cls.window_cls = _import.WindowCovering
|
|
||||||
cls.window_basic_cls = _import.WindowCoveringBasic
|
|
||||||
|
|
||||||
@classmethod
|
async def test_garage_door_open_close(hass, cls):
|
||||||
def tearDownClass(cls):
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
"""Stop debounce patcher."""
|
entity_id = 'cover.garage_door'
|
||||||
cls.patcher.stop()
|
|
||||||
|
|
||||||
def setUp(self):
|
acc = cls.garage(hass, 'Garage Door', entity_id, 2, config=None)
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_add_job(acc.run)
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 4 # GarageDoorOpener
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert acc.char_current_state.value == 0
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_CLOSED)
|
||||||
"""Stop down everything that was started."""
|
await hass.async_block_till_done()
|
||||||
self.hass.stop()
|
assert acc.char_current_state.value == 1
|
||||||
|
assert acc.char_target_state.value == 1
|
||||||
|
|
||||||
def test_garage_door_open_close(self):
|
hass.states.async_set(entity_id, STATE_OPEN)
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
await hass.async_block_till_done()
|
||||||
garage_door = 'cover.garage_door'
|
assert acc.char_current_state.value == 0
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
acc = self.garage_cls(self.hass, 'Cover', garage_door, 2, config=None)
|
hass.states.async_set(entity_id, STATE_UNAVAILABLE)
|
||||||
acc.run()
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_current_state.value == 0
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
self.assertEqual(acc.category, 4) # GarageDoorOpener
|
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)
|
# Set from HomeKit
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
call_close_cover = async_mock_service(hass, DOMAIN, 'close_cover')
|
||||||
|
call_open_cover = async_mock_service(hass, DOMAIN, 'open_cover')
|
||||||
|
|
||||||
self.hass.states.set(garage_door, STATE_CLOSED)
|
await hass.async_add_job(acc.char_target_state.client_update_value, 1)
|
||||||
self.hass.block_till_done()
|
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.assertEqual(acc.char_current_state.value, 1)
|
hass.states.async_set(entity_id, STATE_CLOSED)
|
||||||
self.assertEqual(acc.char_target_state.value, 1)
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
self.hass.states.set(garage_door, STATE_OPEN)
|
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_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
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(garage_door, STATE_UNAVAILABLE)
|
async def test_window_set_cover_position(hass, cls):
|
||||||
self.hass.block_till_done()
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
|
entity_id = 'cover.window'
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 0)
|
acc = cls.window(hass, 'Cover', entity_id, 2, config=None)
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
self.hass.states.set(garage_door, STATE_UNKNOWN)
|
assert acc.aid == 2
|
||||||
self.hass.block_till_done()
|
assert acc.category == 14 # WindowCovering
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 0)
|
assert acc.char_current_position.value == 0
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
assert acc.char_target_position.value == 0
|
||||||
|
|
||||||
# Set closed from HomeKit
|
hass.states.async_set(entity_id, STATE_UNKNOWN,
|
||||||
acc.char_target_state.client_update_value(1)
|
{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_state.value, 2)
|
hass.states.async_set(entity_id, STATE_OPEN,
|
||||||
self.assertEqual(acc.char_target_state.value, 1)
|
{ATTR_CURRENT_POSITION: 50})
|
||||||
self.assertEqual(
|
await hass.async_block_till_done()
|
||||||
self.events[0].data[ATTR_SERVICE], 'close_cover')
|
assert acc.char_current_position.value == 50
|
||||||
|
assert acc.char_target_position.value == 50
|
||||||
|
|
||||||
self.hass.states.set(garage_door, STATE_CLOSED)
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_set_cover_position = async_mock_service(hass, DOMAIN,
|
||||||
|
'set_cover_position')
|
||||||
|
|
||||||
# Set open from HomeKit
|
await hass.async_add_job(acc.char_target_position.client_update_value, 25)
|
||||||
acc.char_target_state.client_update_value(0)
|
await hass.async_block_till_done()
|
||||||
self.hass.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
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 3)
|
await hass.async_add_job(acc.char_target_position.client_update_value, 75)
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(
|
assert call_set_cover_position[1]
|
||||||
self.events[1].data[ATTR_SERVICE], 'open_cover')
|
assert call_set_cover_position[1].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_set_cover_position[1].data[ATTR_POSITION] == 75
|
||||||
|
assert acc.char_current_position.value == 50
|
||||||
|
assert acc.char_target_position.value == 75
|
||||||
|
|
||||||
def test_window_set_cover_position(self):
|
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
|
||||||
window_cover = 'cover.window'
|
|
||||||
|
|
||||||
acc = self.window_cls(self.hass, 'Cover', window_cover, 2, config=None)
|
async def test_window_open_close(hass, cls):
|
||||||
acc.run()
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
|
entity_id = 'cover.window'
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, STATE_UNKNOWN,
|
||||||
self.assertEqual(acc.category, 14) # WindowCovering
|
{ATTR_SUPPORTED_FEATURES: 0})
|
||||||
|
acc = cls.window_basic(hass, 'Cover', entity_id, 2, config=None)
|
||||||
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 0)
|
assert acc.aid == 2
|
||||||
self.assertEqual(acc.char_target_position.value, 0)
|
assert acc.category == 14 # WindowCovering
|
||||||
|
|
||||||
self.hass.states.set(window_cover, STATE_UNKNOWN,
|
assert acc.char_current_position.value == 0
|
||||||
{ATTR_CURRENT_POSITION: None})
|
assert acc.char_target_position.value == 0
|
||||||
self.hass.block_till_done()
|
assert acc.char_position_state.value == 2
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 0)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
self.assertEqual(acc.char_target_position.value, 0)
|
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.hass.states.set(window_cover, STATE_OPEN,
|
hass.states.async_set(entity_id, STATE_OPEN)
|
||||||
{ATTR_CURRENT_POSITION: 50})
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
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, 50)
|
hass.states.async_set(entity_id, STATE_CLOSED)
|
||||||
self.assertEqual(acc.char_target_position.value, 50)
|
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
|
||||||
|
|
||||||
# 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], '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_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(75)
|
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], 'set_cover_position')
|
assert acc.char_current_position.value == 100
|
||||||
self.assertEqual(
|
assert acc.char_target_position.value == 100
|
||||||
self.events[1].data[ATTR_SERVICE_DATA][ATTR_POSITION], 75)
|
assert acc.char_position_state.value == 2
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 50)
|
await hass.async_add_job(acc.char_target_position.client_update_value, 55)
|
||||||
self.assertEqual(acc.char_target_position.value, 75)
|
await hass.async_block_till_done()
|
||||||
|
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
|
||||||
|
|
||||||
def test_window_open_close(self):
|
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
|
||||||
window_cover = 'cover.window'
|
|
||||||
|
|
||||||
self.hass.states.set(window_cover, STATE_UNKNOWN,
|
async def test_window_open_close_stop(hass, cls):
|
||||||
{ATTR_SUPPORTED_FEATURES: 0})
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
acc = self.window_basic_cls(self.hass, 'Cover', window_cover, 2,
|
entity_id = 'cover.window'
|
||||||
config=None)
|
|
||||||
acc.run()
|
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, STATE_UNKNOWN,
|
||||||
self.assertEqual(acc.category, 14) # WindowCovering
|
{ATTR_SUPPORTED_FEATURES: SUPPORT_STOP})
|
||||||
|
acc = cls.window_basic(hass, 'Cover', entity_id, 2, config=None)
|
||||||
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 0)
|
# Set from HomeKit
|
||||||
self.assertEqual(acc.char_target_position.value, 0)
|
call_close_cover = async_mock_service(hass, DOMAIN, 'close_cover')
|
||||||
self.assertEqual(acc.char_position_state.value, 2)
|
call_open_cover = async_mock_service(hass, DOMAIN, 'open_cover')
|
||||||
|
call_stop_cover = async_mock_service(hass, DOMAIN, 'stop_cover')
|
||||||
|
|
||||||
self.hass.states.set(window_cover, STATE_UNKNOWN)
|
await hass.async_add_job(acc.char_target_position.client_update_value, 25)
|
||||||
self.hass.block_till_done()
|
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_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)
|
await hass.async_add_job(acc.char_target_position.client_update_value, 90)
|
||||||
self.assertEqual(acc.char_target_position.value, 0)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_position_state.value, 2)
|
assert call_open_cover
|
||||||
|
assert call_open_cover[0].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
|
||||||
|
|
||||||
self.hass.states.set(window_cover, STATE_OPEN)
|
await hass.async_add_job(acc.char_target_position.client_update_value, 55)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
assert call_stop_cover
|
||||||
self.assertEqual(acc.char_current_position.value, 100)
|
assert call_stop_cover[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(acc.char_target_position.value, 100)
|
assert acc.char_current_position.value == 50
|
||||||
self.assertEqual(acc.char_position_state.value, 2)
|
assert acc.char_target_position.value == 50
|
||||||
|
assert 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
|
|
||||||
acc.char_target_position.client_update_value(25)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[0].data[ATTR_SERVICE], 'close_cover')
|
|
||||||
|
|
||||||
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
|
|
||||||
acc.char_target_position.client_update_value(90)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE], 'open_cover')
|
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 100)
|
|
||||||
self.assertEqual(acc.char_target_position.value, 100)
|
|
||||||
self.assertEqual(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)
|
|
||||||
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."""
|
|
||||||
window_cover = 'cover.window'
|
|
||||||
|
|
||||||
self.hass.states.set(window_cover, STATE_UNKNOWN,
|
|
||||||
{ATTR_SUPPORTED_FEATURES: SUPPORT_STOP})
|
|
||||||
acc = self.window_basic_cls(self.hass, 'Cover', window_cover, 2,
|
|
||||||
config=None)
|
|
||||||
acc.run()
|
|
||||||
|
|
||||||
# Set from HomeKit
|
|
||||||
acc.char_target_position.client_update_value(25)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[0].data[ATTR_SERVICE], 'close_cover')
|
|
||||||
|
|
||||||
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
|
|
||||||
acc.char_target_position.client_update_value(90)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE], 'open_cover')
|
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_position.value, 100)
|
|
||||||
self.assertEqual(acc.char_target_position.value, 100)
|
|
||||||
self.assertEqual(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], '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)
|
|
||||||
|
@ -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."""
|
||||||
|
patcher = patch_debounce()
|
||||||
|
patcher.start()
|
||||||
|
_import = __import__('homeassistant.components.homekit.type_lights',
|
||||||
|
fromlist=['Light'])
|
||||||
|
request.addfinalizer(patcher.stop)
|
||||||
|
patcher_tuple = namedtuple('Cls', ['light'])
|
||||||
|
return patcher_tuple(light=_import.Light)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""Setup Light class import and debounce patcher."""
|
|
||||||
cls.patcher = patch_debounce()
|
|
||||||
cls.patcher.start()
|
|
||||||
_import = __import__('homeassistant.components.homekit.type_lights',
|
|
||||||
fromlist=['Light'])
|
|
||||||
cls.light_cls = _import.Light
|
|
||||||
|
|
||||||
@classmethod
|
async def test_light_basic(hass, cls):
|
||||||
def tearDownClass(cls):
|
"""Test light with char state."""
|
||||||
"""Stop debounce patcher."""
|
entity_id = 'light.demo'
|
||||||
cls.patcher.stop()
|
|
||||||
|
|
||||||
def setUp(self):
|
hass.states.async_set(entity_id, STATE_ON,
|
||||||
"""Setup things to be run when tests are started."""
|
{ATTR_SUPPORTED_FEATURES: 0})
|
||||||
self.hass = get_test_home_assistant()
|
await hass.async_block_till_done()
|
||||||
self.events = []
|
acc = cls.light(hass, 'Light', entity_id, 2, config=None)
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 5 # Lightbulb
|
||||||
"""Track called event."""
|
assert acc.char_on.value == 0
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
await hass.async_add_job(acc.run)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_on.value == 1
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_OFF,
|
||||||
"""Stop down everything that was started."""
|
{ATTR_SUPPORTED_FEATURES: 0})
|
||||||
self.hass.stop()
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_on.value == 0
|
||||||
|
|
||||||
def test_light_basic(self):
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
"""Test light with char state."""
|
await hass.async_block_till_done()
|
||||||
entity_id = 'light.demo'
|
assert acc.char_on.value == 0
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON,
|
hass.states.async_remove(entity_id)
|
||||||
{ATTR_SUPPORTED_FEATURES: 0})
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert acc.char_on.value == 0
|
||||||
acc = self.light_cls(self.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()
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
|
||||||
self.assertEqual(acc.char_on.value, 1)
|
call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_OFF,
|
await hass.async_add_job(acc.char_on.client_update_value, 1)
|
||||||
{ATTR_SUPPORTED_FEATURES: 0})
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert call_turn_on
|
||||||
self.assertEqual(acc.char_on.value, 0)
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN)
|
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, 0)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
await hass.async_add_job(acc.char_on.client_update_value, 0)
|
||||||
acc.char_on.client_update_value(1)
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert call_turn_off
|
||||||
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
|
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
acc.char_on.client_update_value(0)
|
async def test_light_brightness(hass, cls):
|
||||||
self.hass.block_till_done()
|
"""Test light with brightness."""
|
||||||
self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN)
|
entity_id = 'light.demo'
|
||||||
self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_OFF)
|
hass.states.async_set(entity_id, STATE_ON, {
|
||||||
self.hass.block_till_done()
|
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
acc = cls.light(hass, 'Light', entity_id, 2, config=None)
|
||||||
|
|
||||||
# Remove entity
|
assert acc.char_brightness.value == 0
|
||||||
self.hass.states.remove(entity_id)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
def test_light_brightness(self):
|
await hass.async_add_job(acc.run)
|
||||||
"""Test light with brightness."""
|
await hass.async_block_till_done()
|
||||||
entity_id = 'light.demo'
|
assert acc.char_brightness.value == 100
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON, {
|
hass.states.async_set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
|
||||||
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert acc.char_brightness.value == 40
|
||||||
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None)
|
|
||||||
self.assertEqual(acc.char_brightness.value, 0)
|
|
||||||
|
|
||||||
acc.run()
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
|
||||||
self.assertEqual(acc.char_brightness.value, 100)
|
call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
|
await hass.async_add_job(acc.char_brightness.client_update_value, 20)
|
||||||
self.hass.block_till_done()
|
await hass.async_add_job(acc.char_on.client_update_value, 1)
|
||||||
self.assertEqual(acc.char_brightness.value, 40)
|
await hass.async_block_till_done()
|
||||||
|
assert call_turn_on[0]
|
||||||
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20
|
||||||
|
|
||||||
# Set from HomeKit
|
await hass.async_add_job(acc.char_on.client_update_value, 1)
|
||||||
acc.char_brightness.client_update_value(20)
|
await hass.async_add_job(acc.char_brightness.client_update_value, 40)
|
||||||
acc.char_on.client_update_value(1)
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert call_turn_on[1]
|
||||||
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
|
assert call_turn_on[1].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
|
assert call_turn_on[1].data[ATTR_BRIGHTNESS_PCT] == 40
|
||||||
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_on.client_update_value, 1)
|
||||||
acc.char_brightness.client_update_value(40)
|
await hass.async_add_job(acc.char_brightness.client_update_value, 0)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN)
|
assert call_turn_off
|
||||||
self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_ON)
|
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE_DATA], {
|
|
||||||
ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 40})
|
|
||||||
|
|
||||||
acc.char_on.client_update_value(1)
|
|
||||||
acc.char_brightness.client_update_value(0)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(self.events[2].data[ATTR_DOMAIN], DOMAIN)
|
|
||||||
self.assertEqual(self.events[2].data[ATTR_SERVICE], SERVICE_TURN_OFF)
|
|
||||||
|
|
||||||
def test_light_color_temperature(self):
|
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)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
await hass.async_add_job(acc.run)
|
||||||
acc.char_color_temperature.client_update_value(250)
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert acc.char_color_temperature.value == 190
|
||||||
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):
|
# Set from HomeKit
|
||||||
"""Test light with rgb_color."""
|
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
|
||||||
entity_id = 'light.demo'
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON, {
|
await hass.async_add_job(
|
||||||
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR,
|
acc.char_color_temperature.client_update_value, 250)
|
||||||
ATTR_HS_COLOR: (260, 90)})
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert call_turn_on
|
||||||
acc = self.light_cls(self.hass, 'Light', entity_id, 2, config=None)
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(acc.char_hue.value, 0)
|
assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250
|
||||||
self.assertEqual(acc.char_saturation.value, 75)
|
|
||||||
|
|
||||||
acc.run()
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_hue.value, 260)
|
|
||||||
self.assertEqual(acc.char_saturation.value, 90)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
async def test_light_rgb_color(hass, cls):
|
||||||
acc.char_hue.client_update_value(145)
|
"""Test light with rgb_color."""
|
||||||
acc.char_saturation.client_update_value(75)
|
entity_id = 'light.demo'
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
|
hass.states.async_set(entity_id, STATE_ON, {
|
||||||
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
|
ATTR_SUPPORTED_FEATURES: SUPPORT_COLOR,
|
||||||
self.assertEqual(
|
ATTR_HS_COLOR: (260, 90)})
|
||||||
self.events[0].data[ATTR_SERVICE_DATA], {
|
await hass.async_block_till_done()
|
||||||
ATTR_ENTITY_ID: entity_id, ATTR_HS_COLOR: (145, 75)})
|
acc = cls.light(hass, 'Light', entity_id, 2, config=None)
|
||||||
|
|
||||||
|
assert acc.char_hue.value == 0
|
||||||
|
assert acc.char_saturation.value == 75
|
||||||
|
|
||||||
|
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
|
||||||
|
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
|
||||||
|
|
||||||
|
await hass.async_add_job(acc.char_hue.client_update_value, 145)
|
||||||
|
await hass.async_add_job(acc.char_saturation.client_update_value, 75)
|
||||||
|
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_HS_COLOR] == (145, 75)
|
||||||
|
@ -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."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
|
entity_id = 'lock.kitchen_door'
|
||||||
|
|
||||||
def setUp(self):
|
acc = Lock(hass, 'Lock', entity_id, 2, config=None)
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_add_job(acc.run)
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 6 # DoorLock
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert acc.char_current_state.value == 3
|
||||||
|
assert acc.char_target_state.value == 1
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_LOCKED)
|
||||||
"""Stop down everything that was started."""
|
await hass.async_block_till_done()
|
||||||
self.hass.stop()
|
assert acc.char_current_state.value == 1
|
||||||
|
assert acc.char_target_state.value == 1
|
||||||
|
|
||||||
def test_lock_unlock(self):
|
hass.states.async_set(entity_id, STATE_UNLOCKED)
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
await hass.async_block_till_done()
|
||||||
kitchen_lock = 'lock.kitchen_door'
|
assert acc.char_current_state.value == 0
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
acc = Lock(self.hass, 'Lock', kitchen_lock, 2, config=None)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
acc.run()
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_current_state.value == 3
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_remove(entity_id)
|
||||||
self.assertEqual(acc.category, 6) # DoorLock
|
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, 3)
|
# Set from HomeKit
|
||||||
self.assertEqual(acc.char_target_state.value, 1)
|
call_lock = async_mock_service(hass, DOMAIN, 'lock')
|
||||||
|
call_unlock = async_mock_service(hass, DOMAIN, 'unlock')
|
||||||
|
|
||||||
self.hass.states.set(kitchen_lock, STATE_LOCKED)
|
await hass.async_add_job(acc.char_target_state.client_update_value, 1)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
assert call_lock
|
||||||
|
assert call_lock[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert acc.char_target_state.value == 1
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 1)
|
await hass.async_add_job(acc.char_target_state.client_update_value, 0)
|
||||||
self.assertEqual(acc.char_target_state.value, 1)
|
await hass.async_block_till_done()
|
||||||
|
assert call_unlock
|
||||||
self.hass.states.set(kitchen_lock, STATE_UNLOCKED)
|
assert call_unlock[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.hass.block_till_done()
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(kitchen_lock, STATE_UNKNOWN)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 3)
|
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
|
||||||
acc.char_target_state.client_update_value(1)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
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)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE], 'unlock')
|
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.remove(kitchen_lock)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
@ -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."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
|
code = '1234'
|
||||||
|
config = {ATTR_CODE: code}
|
||||||
|
entity_id = 'alarm_control_panel.test'
|
||||||
|
|
||||||
def setUp(self):
|
acc = SecuritySystem(hass, 'SecuritySystem', entity_id, 2, config=config)
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_add_job(acc.run)
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 11 # AlarmSystem
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert acc.char_current_state.value == 3
|
||||||
|
assert acc.char_target_state.value == 3
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_ALARM_ARMED_AWAY)
|
||||||
"""Stop down everything that was started."""
|
await hass.async_block_till_done()
|
||||||
self.hass.stop()
|
assert acc.char_target_state.value == 1
|
||||||
|
assert acc.char_current_state.value == 1
|
||||||
|
|
||||||
def test_switch_set_state(self):
|
hass.states.async_set(entity_id, STATE_ALARM_ARMED_HOME)
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
await hass.async_block_till_done()
|
||||||
acp = 'alarm_control_panel.test'
|
assert acc.char_target_state.value == 0
|
||||||
|
assert acc.char_current_state.value == 0
|
||||||
|
|
||||||
acc = SecuritySystem(self.hass, 'SecuritySystem', acp,
|
hass.states.async_set(entity_id, STATE_ALARM_ARMED_NIGHT)
|
||||||
2, config={ATTR_CODE: '1234'})
|
await hass.async_block_till_done()
|
||||||
acc.run()
|
assert acc.char_target_state.value == 2
|
||||||
|
assert acc.char_current_state.value == 2
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, STATE_ALARM_DISARMED)
|
||||||
self.assertEqual(acc.category, 11) # AlarmSystem
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_state.value == 3
|
||||||
|
assert acc.char_current_state.value == 3
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_state.value, 3)
|
hass.states.async_set(entity_id, STATE_ALARM_TRIGGERED)
|
||||||
self.assertEqual(acc.char_target_state.value, 3)
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_state.value == 3
|
||||||
|
assert acc.char_current_state.value == 4
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_ALARM_ARMED_AWAY)
|
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, 1)
|
assert acc.char_target_state.value == 3
|
||||||
self.assertEqual(acc.char_current_state.value, 1)
|
assert acc.char_current_state.value == 4
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_ALARM_ARMED_HOME)
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_arm_home = async_mock_service(hass, DOMAIN, 'alarm_arm_home')
|
||||||
self.assertEqual(acc.char_target_state.value, 0)
|
call_arm_away = async_mock_service(hass, DOMAIN, 'alarm_arm_away')
|
||||||
self.assertEqual(acc.char_current_state.value, 0)
|
call_arm_night = async_mock_service(hass, DOMAIN, 'alarm_arm_night')
|
||||||
|
call_disarm = async_mock_service(hass, DOMAIN, 'alarm_disarm')
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_ALARM_ARMED_NIGHT)
|
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(acc.char_target_state.value, 2)
|
assert call_arm_home
|
||||||
self.assertEqual(acc.char_current_state.value, 2)
|
assert call_arm_home[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_arm_home[0].data[ATTR_CODE] == code
|
||||||
|
assert acc.char_target_state.value == 0
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_ALARM_DISARMED)
|
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(acc.char_target_state.value, 3)
|
assert call_arm_away
|
||||||
self.assertEqual(acc.char_current_state.value, 3)
|
assert call_arm_away[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_arm_away[0].data[ATTR_CODE] == code
|
||||||
|
assert acc.char_target_state.value == 1
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_ALARM_TRIGGERED)
|
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(acc.char_target_state.value, 3)
|
assert call_arm_night
|
||||||
self.assertEqual(acc.char_current_state.value, 4)
|
assert call_arm_night[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_arm_night[0].data[ATTR_CODE] == code
|
||||||
|
assert acc.char_target_state.value == 2
|
||||||
|
|
||||||
self.hass.states.set(acp, STATE_UNKNOWN)
|
await hass.async_add_job(acc.char_target_state.client_update_value, 3)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_target_state.value, 3)
|
assert call_disarm
|
||||||
self.assertEqual(acc.char_current_state.value, 4)
|
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
|
||||||
|
|
||||||
# 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.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)
|
@pytest.mark.parametrize('config', [{}, {ATTR_CODE: None}])
|
||||||
self.hass.block_till_done()
|
async def test_no_alarm_code(hass, config):
|
||||||
self.assertEqual(
|
"""Test accessory if security_system doesn't require a alarm_code."""
|
||||||
self.events[1].data[ATTR_SERVICE], 'alarm_arm_away')
|
entity_id = 'alarm_control_panel.test'
|
||||||
self.assertEqual(
|
|
||||||
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234')
|
|
||||||
self.assertEqual(acc.char_target_state.value, 1)
|
|
||||||
|
|
||||||
acc.char_target_state.client_update_value(2)
|
acc = SecuritySystem(hass, 'SecuritySystem', entity_id, 2, config=config)
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[2].data[ATTR_SERVICE], 'alarm_arm_night')
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234')
|
|
||||||
self.assertEqual(acc.char_target_state.value, 2)
|
|
||||||
|
|
||||||
acc.char_target_state.client_update_value(3)
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_arm_home = async_mock_service(hass, DOMAIN, 'alarm_arm_home')
|
||||||
self.assertEqual(
|
|
||||||
self.events[3].data[ATTR_SERVICE], 'alarm_disarm')
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[0].data[ATTR_SERVICE_DATA][ATTR_CODE], '1234')
|
|
||||||
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, 0)
|
||||||
"""Test accessory if security_system doesn't require a alarm_code."""
|
await hass.async_block_till_done()
|
||||||
acp = 'alarm_control_panel.test'
|
assert call_arm_home
|
||||||
|
assert call_arm_home[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
acc = SecuritySystem(self.hass, 'SecuritySystem', acp,
|
assert ATTR_CODE not in call_arm_home[0].data
|
||||||
2, config={ATTR_CODE: None})
|
assert acc.char_target_state.value == 0
|
||||||
# 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
|
|
||||||
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)
|
|
||||||
|
@ -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):
|
||||||
|
"""Test if accessory is updated after state change."""
|
||||||
|
entity_id = 'sensor.temperature'
|
||||||
|
|
||||||
|
acc = TemperatureSensor(hass, 'Temperature', entity_id, 2, config=None)
|
||||||
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
|
assert acc.aid == 2
|
||||||
|
assert acc.category == 10 # Sensor
|
||||||
|
|
||||||
|
assert acc.char_temp.value == 0.0
|
||||||
|
for key, value in PROP_CELSIUS.items():
|
||||||
|
assert acc.char_temp.properties[key] == value
|
||||||
|
|
||||||
|
hass.states.async_set(entity_id, STATE_UNKNOWN,
|
||||||
|
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_temp.value == 0.0
|
||||||
|
|
||||||
|
hass.states.async_set(entity_id, '20',
|
||||||
|
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_temp.value == 20
|
||||||
|
|
||||||
|
hass.states.async_set(entity_id, '75.2',
|
||||||
|
{ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_temp.value == 24
|
||||||
|
|
||||||
|
|
||||||
class TestHomekitSensors(unittest.TestCase):
|
async def test_humidity(hass):
|
||||||
"""Test class for all accessory types regarding sensors."""
|
"""Test if accessory is updated after state change."""
|
||||||
|
entity_id = 'sensor.humidity'
|
||||||
|
|
||||||
def setUp(self):
|
acc = HumiditySensor(hass, 'Humidity', entity_id, 2, config=None)
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_add_job(acc.run)
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
def tearDown(self):
|
assert acc.aid == 2
|
||||||
"""Stop down everything that was started."""
|
assert acc.category == 10 # Sensor
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
def test_temperature(self):
|
assert acc.char_humidity.value == 0
|
||||||
"""Test if accessory is updated after state change."""
|
|
||||||
entity_id = 'sensor.temperature'
|
|
||||||
|
|
||||||
acc = TemperatureSensor(self.hass, 'Temperature', entity_id,
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
2, config=None)
|
await hass.async_block_till_done()
|
||||||
acc.run()
|
assert acc.char_humidity.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, '20')
|
||||||
self.assertEqual(acc.category, 10) # Sensor
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_humidity.value == 20
|
||||||
|
|
||||||
self.assertEqual(acc.char_temp.value, 0.0)
|
|
||||||
for key, value in PROP_CELSIUS.items():
|
|
||||||
self.assertEqual(acc.char_temp.properties[key], value)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN,
|
async def test_air_quality(hass):
|
||||||
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
"""Test if accessory is updated after state change."""
|
||||||
self.hass.block_till_done()
|
entity_id = 'sensor.air_quality'
|
||||||
self.assertEqual(acc.char_temp.value, 0.0)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '20',
|
acc = AirQualitySensor(hass, 'Air Quality', entity_id, 2, config=None)
|
||||||
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
await hass.async_add_job(acc.run)
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_temp.value, 20)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '75.2',
|
assert acc.aid == 2
|
||||||
{ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
|
assert acc.category == 10 # Sensor
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_temp.value, 24)
|
|
||||||
|
|
||||||
def test_humidity(self):
|
assert acc.char_density.value == 0
|
||||||
"""Test if accessory is updated after state change."""
|
assert acc.char_quality.value == 0
|
||||||
entity_id = 'sensor.humidity'
|
|
||||||
|
|
||||||
acc = HumiditySensor(self.hass, 'Humidity', entity_id, 2, config=None)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
acc.run()
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_density.value == 0
|
||||||
|
assert acc.char_quality.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, '34')
|
||||||
self.assertEqual(acc.category, 10) # Sensor
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_density.value == 34
|
||||||
|
assert acc.char_quality.value == 1
|
||||||
|
|
||||||
self.assertEqual(acc.char_humidity.value, 0)
|
hass.states.async_set(entity_id, '200')
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_density.value == 200
|
||||||
|
assert acc.char_quality.value == 5
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_humidity.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '20')
|
async def test_co2(hass):
|
||||||
self.hass.block_till_done()
|
"""Test if accessory is updated after state change."""
|
||||||
self.assertEqual(acc.char_humidity.value, 20)
|
entity_id = 'sensor.co2'
|
||||||
|
|
||||||
def test_air_quality(self):
|
acc = CarbonDioxideSensor(hass, 'CO2', entity_id, 2, config=None)
|
||||||
"""Test if accessory is updated after state change."""
|
await hass.async_add_job(acc.run)
|
||||||
entity_id = 'sensor.air_quality'
|
|
||||||
|
|
||||||
acc = AirQualitySensor(self.hass, 'Air Quality', entity_id,
|
assert acc.aid == 2
|
||||||
2, config=None)
|
assert acc.category == 10 # Sensor
|
||||||
acc.run()
|
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
assert acc.char_co2.value == 0
|
||||||
self.assertEqual(acc.category, 10) # Sensor
|
assert acc.char_peak.value == 0
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.char_density.value, 0)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
self.assertEqual(acc.char_quality.value, 0)
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_co2.value == 0
|
||||||
|
assert acc.char_peak.value == 0
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN)
|
hass.states.async_set(entity_id, '1100')
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_density.value, 0)
|
assert acc.char_co2.value == 1100
|
||||||
self.assertEqual(acc.char_quality.value, 0)
|
assert acc.char_peak.value == 1100
|
||||||
|
assert acc.char_detected.value == 1
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '34')
|
hass.states.async_set(entity_id, '800')
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_density.value, 34)
|
assert acc.char_co2.value == 800
|
||||||
self.assertEqual(acc.char_quality.value, 1)
|
assert acc.char_peak.value == 1100
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '200')
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_density.value, 200)
|
|
||||||
self.assertEqual(acc.char_quality.value, 5)
|
|
||||||
|
|
||||||
def test_co2(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.co2'
|
entity_id = 'sensor.light'
|
||||||
|
|
||||||
acc = CarbonDioxideSensor(self.hass, 'CO2', 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_co2.value, 0)
|
assert acc.char_light.value == 0.0001
|
||||||
self.assertEqual(acc.char_peak.value, 0)
|
|
||||||
self.assertEqual(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_light.value == 0.0001
|
||||||
self.assertEqual(acc.char_peak.value, 0)
|
|
||||||
self.assertEqual(acc.char_detected.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '1100')
|
hass.states.async_set(entity_id, '300')
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_co2.value, 1100)
|
assert acc.char_light.value == 300
|
||||||
self.assertEqual(acc.char_peak.value, 1100)
|
|
||||||
self.assertEqual(acc.char_detected.value, 1)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '800')
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_co2.value, 800)
|
|
||||||
self.assertEqual(acc.char_peak.value, 1100)
|
|
||||||
self.assertEqual(acc.char_detected.value, 0)
|
|
||||||
|
|
||||||
def test_light(self):
|
async def test_binary(hass):
|
||||||
"""Test if accessory is updated after state change."""
|
"""Test if accessory is updated after state change."""
|
||||||
entity_id = 'sensor.light'
|
entity_id = 'binary_sensor.opening'
|
||||||
|
|
||||||
acc = LightSensor(self.hass, 'Light', entity_id, 2, config=None)
|
hass.states.async_set(entity_id, STATE_UNKNOWN,
|
||||||
acc.run()
|
{ATTR_DEVICE_CLASS: 'opening'})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
acc = BinarySensor(hass, 'Window Opening', entity_id, 2, config=None)
|
||||||
self.assertEqual(acc.category, 10) # Sensor
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
self.assertEqual(acc.char_light.value, 0.0001)
|
assert acc.aid == 2
|
||||||
|
assert acc.category == 10 # Sensor
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN)
|
assert acc.char_detected.value == 0
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_light.value, 0.0001)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, '300')
|
hass.states.async_set(entity_id, STATE_ON,
|
||||||
self.hass.block_till_done()
|
{ATTR_DEVICE_CLASS: 'opening'})
|
||||||
self.assertEqual(acc.char_light.value, 300)
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_detected.value == 1
|
||||||
|
|
||||||
def test_binary(self):
|
hass.states.async_set(entity_id, STATE_OFF,
|
||||||
"""Test if accessory is updated after state change."""
|
{ATTR_DEVICE_CLASS: 'opening'})
|
||||||
entity_id = 'binary_sensor.opening'
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_UNKNOWN,
|
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()
|
||||||
|
assert acc.char_detected.value == 1
|
||||||
|
|
||||||
acc = BinarySensor(self.hass, 'Window Opening', entity_id,
|
hass.states.async_set(entity_id, STATE_NOT_HOME,
|
||||||
2, config=None)
|
{ATTR_DEVICE_CLASS: 'opening'})
|
||||||
acc.run()
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_remove(entity_id)
|
||||||
self.assertEqual(acc.category, 10) # Sensor
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_detected.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.char_detected.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_ON,
|
async def test_binary_device_classes(hass):
|
||||||
{ATTR_DEVICE_CLASS: "opening"})
|
"""Test if services and characteristics are assigned correctly."""
|
||||||
self.hass.block_till_done()
|
entity_id = 'binary_sensor.demo'
|
||||||
self.assertEqual(acc.char_detected.value, 1)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_OFF,
|
for device_class, (service, char) in BINARY_SENSOR_SERVICE_MAP.items():
|
||||||
{ATTR_DEVICE_CLASS: "opening"})
|
hass.states.async_set(entity_id, STATE_OFF,
|
||||||
self.hass.block_till_done()
|
{ATTR_DEVICE_CLASS: device_class})
|
||||||
self.assertEqual(acc.char_detected.value, 0)
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_HOME,
|
acc = BinarySensor(hass, 'Binary Sensor', entity_id, 2, config=None)
|
||||||
{ATTR_DEVICE_CLASS: "opening"})
|
assert acc.get_service(service).display_name == service
|
||||||
self.hass.block_till_done()
|
assert acc.char_detected.display_name == char
|
||||||
self.assertEqual(acc.char_detected.value, 1)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_NOT_HOME,
|
|
||||||
{ATTR_DEVICE_CLASS: "opening"})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_detected.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.remove(entity_id)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
def test_binary_device_classes(self):
|
|
||||||
"""Test if services and characteristics are assigned correctly."""
|
|
||||||
entity_id = 'binary_sensor.demo'
|
|
||||||
|
|
||||||
for device_class, (service, char) in BINARY_SENSOR_SERVICE_MAP.items():
|
|
||||||
self.hass.states.set(entity_id, STATE_OFF,
|
|
||||||
{ATTR_DEVICE_CLASS: device_class})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
acc = BinarySensor(self.hass, 'Binary Sensor', entity_id,
|
|
||||||
2, config=None)
|
|
||||||
self.assertEqual(acc.get_service(service).display_name, service)
|
|
||||||
self.assertEqual(acc.char_detected.display_name, char)
|
|
||||||
|
@ -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):
|
||||||
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
|
domain = split_entity_id(entity_id)[0]
|
||||||
|
|
||||||
def setUp(self):
|
acc = Switch(hass, 'Switch', entity_id, 2, config=None)
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_add_job(acc.run)
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 8 # Switch
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert acc.char_on.value is False
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_ON)
|
||||||
"""Stop down everything that was started."""
|
await hass.async_block_till_done()
|
||||||
self.hass.stop()
|
assert acc.char_on.value is True
|
||||||
|
|
||||||
def test_switch_set_state(self):
|
hass.states.async_set(entity_id, STATE_OFF)
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
await hass.async_block_till_done()
|
||||||
entity_id = 'switch.test'
|
assert acc.char_on.value is False
|
||||||
domain = split_entity_id(entity_id)[0]
|
|
||||||
|
|
||||||
acc = Switch(self.hass, 'Switch', entity_id, 2, config=None)
|
# Set from HomeKit
|
||||||
acc.run()
|
call_turn_on = async_mock_service(hass, domain, 'turn_on')
|
||||||
|
call_turn_off = async_mock_service(hass, domain, 'turn_off')
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
await hass.async_add_job(acc.char_on.client_update_value, True)
|
||||||
self.assertEqual(acc.category, 8) # Switch
|
await hass.async_block_till_done()
|
||||||
|
assert call_turn_on
|
||||||
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
|
||||||
self.assertEqual(acc.char_on.value, False)
|
await hass.async_add_job(acc.char_on.client_update_value, False)
|
||||||
|
await hass.async_block_till_done()
|
||||||
self.hass.states.set(entity_id, STATE_ON)
|
assert call_turn_off
|
||||||
self.hass.block_till_done()
|
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(acc.char_on.value, True)
|
|
||||||
|
|
||||||
self.hass.states.set(entity_id, STATE_OFF)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
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)
|
|
||||||
|
|
||||||
acc.char_on.client_update_value(False)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_DOMAIN], domain)
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
|
|
||||||
|
|
||||||
def test_remote_set_state(self):
|
|
||||||
"""Test service call for remote as domain."""
|
|
||||||
entity_id = 'remote.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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
@ -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."""
|
||||||
|
patcher = patch_debounce()
|
||||||
|
patcher.start()
|
||||||
|
_import = __import__('homeassistant.components.homekit.type_thermostats',
|
||||||
|
fromlist=['Thermostat'])
|
||||||
|
request.addfinalizer(patcher.stop)
|
||||||
|
patcher_tuple = namedtuple('Cls', ['thermostat'])
|
||||||
|
return patcher_tuple(thermostat=_import.Thermostat)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""Setup Thermostat class import and debounce patcher."""
|
|
||||||
cls.patcher = patch_debounce()
|
|
||||||
cls.patcher.start()
|
|
||||||
_import = __import__(
|
|
||||||
'homeassistant.components.homekit.type_thermostats',
|
|
||||||
fromlist=['Thermostat'])
|
|
||||||
cls.thermostat_cls = _import.Thermostat
|
|
||||||
|
|
||||||
@classmethod
|
async def test_default_thermostat(hass, cls):
|
||||||
def tearDownClass(cls):
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
"""Stop debounce patcher."""
|
entity_id = 'climate.test'
|
||||||
cls.patcher.stop()
|
|
||||||
|
|
||||||
def setUp(self):
|
hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0})
|
||||||
"""Setup things to be run when tests are started."""
|
await hass.async_block_till_done()
|
||||||
self.hass = get_test_home_assistant()
|
acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
|
||||||
self.events = []
|
await hass.async_add_job(acc.run)
|
||||||
|
|
||||||
@callback
|
assert acc.aid == 2
|
||||||
def record_event(event):
|
assert acc.category == 9 # Thermostat
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert acc.char_current_heat_cool.value == 0
|
||||||
|
assert acc.char_target_heat_cool.value == 0
|
||||||
|
assert acc.char_current_temp.value == 21.0
|
||||||
|
assert acc.char_target_temp.value == 21.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
assert acc.char_cooling_thresh_temp is None
|
||||||
|
assert acc.char_heating_thresh_temp is None
|
||||||
|
|
||||||
def tearDown(self):
|
hass.states.async_set(entity_id, STATE_HEAT,
|
||||||
"""Stop down everything that was started."""
|
{ATTR_OPERATION_MODE: STATE_HEAT,
|
||||||
self.hass.stop()
|
ATTR_TEMPERATURE: 22.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_temp.value == 22.0
|
||||||
|
assert acc.char_current_heat_cool.value == 1
|
||||||
|
assert acc.char_target_heat_cool.value == 1
|
||||||
|
assert acc.char_current_temp.value == 18.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
def test_default_thermostat(self):
|
hass.states.async_set(entity_id, STATE_HEAT,
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
{ATTR_OPERATION_MODE: STATE_HEAT,
|
||||||
climate = 'climate.test'
|
ATTR_TEMPERATURE: 22.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 23.0,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_temp.value == 22.0
|
||||||
|
assert acc.char_current_heat_cool.value == 0
|
||||||
|
assert acc.char_target_heat_cool.value == 1
|
||||||
|
assert acc.char_current_temp.value == 23.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 0})
|
hass.states.async_set(entity_id, STATE_COOL,
|
||||||
self.hass.block_till_done()
|
{ATTR_OPERATION_MODE: STATE_COOL,
|
||||||
acc = self.thermostat_cls(self.hass, 'Climate', climate,
|
ATTR_TEMPERATURE: 20.0,
|
||||||
2, config=None)
|
ATTR_CURRENT_TEMPERATURE: 25.0,
|
||||||
acc.run()
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_temp.value == 20.0
|
||||||
|
assert acc.char_current_heat_cool.value == 2
|
||||||
|
assert acc.char_target_heat_cool.value == 2
|
||||||
|
assert acc.char_current_temp.value == 25.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.aid, 2)
|
hass.states.async_set(entity_id, STATE_COOL,
|
||||||
self.assertEqual(acc.category, 9) # Thermostat
|
{ATTR_OPERATION_MODE: STATE_COOL,
|
||||||
|
ATTR_TEMPERATURE: 20.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 19.0,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_temp.value == 20.0
|
||||||
|
assert acc.char_current_heat_cool.value == 0
|
||||||
|
assert acc.char_target_heat_cool.value == 2
|
||||||
|
assert acc.char_current_temp.value == 19.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
hass.states.async_set(entity_id, STATE_OFF,
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 0)
|
{ATTR_OPERATION_MODE: STATE_OFF,
|
||||||
self.assertEqual(acc.char_current_temp.value, 21.0)
|
ATTR_TEMPERATURE: 22.0,
|
||||||
self.assertEqual(acc.char_target_temp.value, 21.0)
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp, None)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_heating_thresh_temp, None)
|
assert acc.char_target_temp.value == 22.0
|
||||||
|
assert acc.char_current_heat_cool.value == 0
|
||||||
|
assert acc.char_target_heat_cool.value == 0
|
||||||
|
assert acc.char_current_temp.value == 18.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_HEAT,
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
{ATTR_OPERATION_MODE: STATE_HEAT,
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
ATTR_TEMPERATURE: 22.0,
|
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
self.hass.block_till_done()
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 1)
|
assert acc.char_target_temp.value == 22.0
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 1)
|
assert acc.char_current_heat_cool.value == 1
|
||||||
self.assertEqual(acc.char_current_temp.value, 18.0)
|
assert acc.char_target_heat_cool.value == 3
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
assert acc.char_current_temp.value == 18.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_HEAT,
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
{ATTR_OPERATION_MODE: STATE_HEAT,
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
ATTR_TEMPERATURE: 22.0,
|
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
||||||
ATTR_CURRENT_TEMPERATURE: 23.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
ATTR_CURRENT_TEMPERATURE: 25.0,
|
||||||
self.hass.block_till_done()
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
assert acc.char_target_temp.value == 22.0
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 1)
|
assert acc.char_current_heat_cool.value == 2
|
||||||
self.assertEqual(acc.char_current_temp.value, 23.0)
|
assert acc.char_target_heat_cool.value == 3
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
assert acc.char_current_temp.value == 25.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_COOL,
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
{ATTR_OPERATION_MODE: STATE_COOL,
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
ATTR_TEMPERATURE: 20.0,
|
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
||||||
ATTR_CURRENT_TEMPERATURE: 25.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
ATTR_CURRENT_TEMPERATURE: 22.0,
|
||||||
self.hass.block_till_done()
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
self.assertEqual(acc.char_target_temp.value, 20.0)
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 2)
|
assert acc.char_target_temp.value == 22.0
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 2)
|
assert acc.char_current_heat_cool.value == 0
|
||||||
self.assertEqual(acc.char_current_temp.value, 25.0)
|
assert acc.char_target_heat_cool.value == 3
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
assert acc.char_current_temp.value == 22.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_COOL,
|
# Set from HomeKit
|
||||||
{ATTR_OPERATION_MODE: STATE_COOL,
|
call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
|
||||||
ATTR_TEMPERATURE: 20.0,
|
call_set_operation_mode = async_mock_service(hass, DOMAIN,
|
||||||
ATTR_CURRENT_TEMPERATURE: 19.0,
|
'set_operation_mode')
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_target_temp.value, 20.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 2)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 19.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_OFF,
|
await hass.async_add_job(acc.char_target_temp.client_update_value, 19.0)
|
||||||
{ATTR_OPERATION_MODE: STATE_OFF,
|
await hass.async_block_till_done()
|
||||||
ATTR_TEMPERATURE: 22.0,
|
assert call_set_temperature
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
assert call_set_temperature[0].data[ATTR_TEMPERATURE] == 19.0
|
||||||
self.hass.block_till_done()
|
assert acc.char_target_temp.value == 19.0
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 18.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
await hass.async_block_till_done()
|
||||||
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
assert call_set_operation_mode
|
||||||
ATTR_TEMPERATURE: 22.0,
|
assert call_set_operation_mode[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
assert call_set_operation_mode[0].data[ATTR_OPERATION_MODE] == STATE_HEAT
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
assert acc.char_target_heat_cool.value == 1
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 1)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 18.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
|
||||||
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
|
||||||
ATTR_TEMPERATURE: 22.0,
|
|
||||||
ATTR_CURRENT_TEMPERATURE: 25.0,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 2)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 25.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
async def test_auto_thermostat(hass, cls):
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
ATTR_OPERATION_LIST: [STATE_HEAT, STATE_COOL],
|
entity_id = 'climate.test'
|
||||||
ATTR_TEMPERATURE: 22.0,
|
|
||||||
ATTR_CURRENT_TEMPERATURE: 22.0,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
# support_auto = True
|
||||||
acc.char_target_temp.client_update_value(19.0)
|
hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(
|
acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
|
||||||
self.events[0].data[ATTR_SERVICE], 'set_temperature')
|
await hass.async_add_job(acc.run)
|
||||||
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)
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
self.hass.block_till_done()
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
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)
|
|
||||||
|
|
||||||
def test_auto_thermostat(self):
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
climate = 'climate.test'
|
ATTR_TARGET_TEMP_HIGH: 22.0,
|
||||||
|
ATTR_TARGET_TEMP_LOW: 20.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_heating_thresh_temp.value == 20.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 22.0
|
||||||
|
assert acc.char_current_heat_cool.value == 1
|
||||||
|
assert acc.char_target_heat_cool.value == 3
|
||||||
|
assert acc.char_current_temp.value == 18.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
# support_auto = True
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
self.hass.block_till_done()
|
ATTR_TARGET_TEMP_HIGH: 23.0,
|
||||||
acc = self.thermostat_cls(self.hass, 'Climate', climate,
|
ATTR_TARGET_TEMP_LOW: 19.0,
|
||||||
2, config=None)
|
ATTR_CURRENT_TEMPERATURE: 24.0,
|
||||||
acc.run()
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
|
assert acc.char_current_heat_cool.value == 2
|
||||||
|
assert acc.char_target_heat_cool.value == 3
|
||||||
|
assert acc.char_current_temp.value == 24.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0)
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0)
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
|
ATTR_TARGET_TEMP_HIGH: 23.0,
|
||||||
|
ATTR_TARGET_TEMP_LOW: 19.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 21.0,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
|
assert acc.char_current_heat_cool.value == 0
|
||||||
|
assert acc.char_target_heat_cool.value == 3
|
||||||
|
assert acc.char_current_temp.value == 21.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
# Set from HomeKit
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
|
||||||
ATTR_TARGET_TEMP_HIGH: 22.0,
|
|
||||||
ATTR_TARGET_TEMP_LOW: 20.0,
|
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_heating_thresh_temp.value, 20.0)
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 1)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 18.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
await hass.async_add_job(
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
acc.char_heating_thresh_temp.client_update_value, 20.0)
|
||||||
ATTR_TARGET_TEMP_HIGH: 23.0,
|
await hass.async_block_till_done()
|
||||||
ATTR_TARGET_TEMP_LOW: 19.0,
|
assert call_set_temperature[0]
|
||||||
ATTR_CURRENT_TEMPERATURE: 24.0,
|
assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
assert call_set_temperature[0].data[ATTR_TARGET_TEMP_LOW] == 20.0
|
||||||
self.hass.block_till_done()
|
assert acc.char_heating_thresh_temp.value == 20.0
|
||||||
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0)
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 2)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 24.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
await hass.async_add_job(
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
acc.char_cooling_thresh_temp.client_update_value, 25.0)
|
||||||
ATTR_TARGET_TEMP_HIGH: 23.0,
|
await hass.async_block_till_done()
|
||||||
ATTR_TARGET_TEMP_LOW: 19.0,
|
assert call_set_temperature[1]
|
||||||
ATTR_CURRENT_TEMPERATURE: 21.0,
|
assert call_set_temperature[1].data[ATTR_ENTITY_ID] == entity_id
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
|
assert call_set_temperature[1].data[ATTR_TARGET_TEMP_HIGH] == 25.0
|
||||||
self.hass.block_till_done()
|
assert acc.char_cooling_thresh_temp.value == 25.0
|
||||||
self.assertEqual(acc.char_heating_thresh_temp.value, 19.0)
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 23.0)
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 3)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 21.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 0)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
|
||||||
acc.char_heating_thresh_temp.client_update_value(20.0)
|
|
||||||
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)
|
async def test_power_state(hass, cls):
|
||||||
self.hass.block_till_done()
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
self.assertEqual(
|
entity_id = 'climate.test'
|
||||||
self.events[1].data[ATTR_SERVICE], 'set_temperature')
|
|
||||||
self.assertEqual(
|
|
||||||
self.events[1].data[ATTR_SERVICE_DATA][ATTR_TARGET_TEMP_HIGH],
|
|
||||||
25.0)
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 25.0)
|
|
||||||
|
|
||||||
def test_power_state(self):
|
# SUPPORT_ON_OFF = True
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
hass.states.async_set(entity_id, STATE_HEAT,
|
||||||
climate = 'climate.test'
|
{ATTR_SUPPORTED_FEATURES: 4096,
|
||||||
|
ATTR_OPERATION_MODE: STATE_HEAT,
|
||||||
|
ATTR_TEMPERATURE: 23.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 18.0})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
|
||||||
|
await hass.async_add_job(acc.run)
|
||||||
|
assert acc.support_power_state is True
|
||||||
|
|
||||||
# SUPPORT_ON_OFF = True
|
assert acc.char_current_heat_cool.value == 1
|
||||||
self.hass.states.set(climate, STATE_HEAT,
|
assert acc.char_target_heat_cool.value == 1
|
||||||
{ATTR_SUPPORTED_FEATURES: 4096,
|
|
||||||
ATTR_OPERATION_MODE: STATE_HEAT,
|
|
||||||
ATTR_TEMPERATURE: 23.0,
|
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
acc = self.thermostat_cls(self.hass, 'Climate', climate,
|
|
||||||
2, config=None)
|
|
||||||
acc.run()
|
|
||||||
self.assertTrue(acc.support_power_state)
|
|
||||||
|
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 1)
|
hass.states.async_set(entity_id, STATE_OFF,
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 1)
|
{ATTR_OPERATION_MODE: STATE_HEAT,
|
||||||
|
ATTR_TEMPERATURE: 23.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 18.0})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_current_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_HEAT,
|
{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
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_OFF,
|
# Set from HomeKit
|
||||||
{ATTR_OPERATION_MODE: STATE_OFF,
|
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')
|
||||||
ATTR_TEMPERATURE: 23.0,
|
call_turn_off = async_mock_service(hass, DOMAIN, 'turn_off')
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0})
|
call_set_operation_mode = async_mock_service(hass, DOMAIN,
|
||||||
self.hass.block_till_done()
|
'set_operation_mode')
|
||||||
self.assertEqual(acc.char_current_heat_cool.value, 0)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 0)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
|
||||||
acc.char_target_heat_cool.client_update_value(1)
|
await hass.async_block_till_done()
|
||||||
self.hass.block_till_done()
|
assert call_turn_on
|
||||||
self.assertEqual(
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.events[0].data[ATTR_SERVICE], 'turn_on')
|
assert call_set_operation_mode
|
||||||
self.assertEqual(
|
assert call_set_operation_mode[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.events[0].data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID],
|
assert call_set_operation_mode[0].data[ATTR_OPERATION_MODE] == STATE_HEAT
|
||||||
climate)
|
assert acc.char_target_heat_cool.value == 1
|
||||||
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, 0)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
self.assertEqual(
|
assert call_turn_off
|
||||||
self.events[2].data[ATTR_SERVICE], 'turn_off')
|
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
self.assertEqual(
|
assert acc.char_target_heat_cool.value == 0
|
||||||
self.events[2].data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID],
|
|
||||||
climate)
|
|
||||||
self.assertEqual(acc.char_target_heat_cool.value, 0)
|
|
||||||
|
|
||||||
def test_thermostat_fahrenheit(self):
|
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
|
||||||
climate = 'climate.test'
|
|
||||||
|
|
||||||
# support_auto = True
|
async def test_thermostat_fahrenheit(hass, cls):
|
||||||
self.hass.states.set(climate, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
self.hass.block_till_done()
|
entity_id = 'climate.test'
|
||||||
acc = self.thermostat_cls(self.hass, 'Climate', climate,
|
|
||||||
2, config=None)
|
|
||||||
acc.run()
|
|
||||||
|
|
||||||
self.hass.states.set(climate, STATE_AUTO,
|
# support_auto = True
|
||||||
{ATTR_OPERATION_MODE: STATE_AUTO,
|
hass.states.async_set(entity_id, STATE_OFF, {ATTR_SUPPORTED_FEATURES: 6})
|
||||||
ATTR_TARGET_TEMP_HIGH: 75.2,
|
await hass.async_block_till_done()
|
||||||
ATTR_TARGET_TEMP_LOW: 68,
|
acc = cls.thermostat(hass, 'Climate', entity_id, 2, config=None)
|
||||||
ATTR_TEMPERATURE: 71.6,
|
await hass.async_add_job(acc.run)
|
||||||
ATTR_CURRENT_TEMPERATURE: 73.4,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
|
|
||||||
self.hass.block_till_done()
|
|
||||||
self.assertEqual(acc.char_heating_thresh_temp.value, 20.0)
|
|
||||||
self.assertEqual(acc.char_cooling_thresh_temp.value, 24.0)
|
|
||||||
self.assertEqual(acc.char_current_temp.value, 23.0)
|
|
||||||
self.assertEqual(acc.char_target_temp.value, 22.0)
|
|
||||||
self.assertEqual(acc.char_display_units.value, 1)
|
|
||||||
|
|
||||||
# Set from HomeKit
|
hass.states.async_set(entity_id, STATE_AUTO,
|
||||||
acc.char_cooling_thresh_temp.client_update_value(23)
|
{ATTR_OPERATION_MODE: STATE_AUTO,
|
||||||
self.hass.block_till_done()
|
ATTR_TARGET_TEMP_HIGH: 75.2,
|
||||||
service_data = self.events[-1].data[ATTR_SERVICE_DATA]
|
ATTR_TARGET_TEMP_LOW: 68,
|
||||||
self.assertEqual(service_data[ATTR_TARGET_TEMP_HIGH], 73.4)
|
ATTR_TEMPERATURE: 71.6,
|
||||||
self.assertEqual(service_data[ATTR_TARGET_TEMP_LOW], 68)
|
ATTR_CURRENT_TEMPERATURE: 73.4,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_heating_thresh_temp.value == 20.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 24.0
|
||||||
|
assert acc.char_current_temp.value == 23.0
|
||||||
|
assert acc.char_target_temp.value == 22.0
|
||||||
|
assert acc.char_display_units.value == 1
|
||||||
|
|
||||||
acc.char_heating_thresh_temp.client_update_value(22)
|
# Set from HomeKit
|
||||||
self.hass.block_till_done()
|
call_set_temperature = async_mock_service(hass, DOMAIN, 'set_temperature')
|
||||||
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], 71.6)
|
|
||||||
|
|
||||||
acc.char_target_temp.client_update_value(24.0)
|
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_TEMPERATURE], 75.2)
|
assert call_set_temperature[0]
|
||||||
|
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
|
||||||
|
|
||||||
|
await hass.async_add_job(
|
||||||
|
acc.char_heating_thresh_temp.client_update_value, 22)
|
||||||
|
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] == 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
|
||||||
|
@ -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."""
|
"""Test show setup message as persistence notification."""
|
||||||
|
bridge = HomeBridge(hass)
|
||||||
|
|
||||||
def setUp(self):
|
call_create_notification = async_mock_service(hass, DOMAIN, 'create')
|
||||||
"""Setup things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
@callback
|
await hass.async_add_job(show_setup_message, hass, bridge)
|
||||||
def record_event(event):
|
await hass.async_block_till_done()
|
||||||
"""Track called event."""
|
|
||||||
self.events.append(event)
|
|
||||||
|
|
||||||
self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
|
assert call_create_notification
|
||||||
|
assert call_create_notification[0].data[ATTR_NOTIFICATION_ID] == \
|
||||||
|
HOMEKIT_NOTIFY_ID
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""Stop down everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
def test_show_setup_msg(self):
|
async def test_dismiss_setup_msg(hass):
|
||||||
"""Test show setup message as persistence notification."""
|
"""Test dismiss setup message."""
|
||||||
bridge = HomeBridge(self.hass)
|
call_dismiss_notification = async_mock_service(hass, DOMAIN, 'dismiss')
|
||||||
|
|
||||||
show_setup_message(self.hass, bridge)
|
await hass.async_add_job(dismiss_setup_message, hass)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
data = self.events[0].data
|
assert call_dismiss_notification
|
||||||
self.assertEqual(
|
assert call_dismiss_notification[0].data[ATTR_NOTIFICATION_ID] == \
|
||||||
data.get(ATTR_DOMAIN, None), 'persistent_notification')
|
HOMEKIT_NOTIFY_ID
|
||||||
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):
|
|
||||||
"""Test dismiss setup message."""
|
|
||||||
dismiss_setup_message(self.hass)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
data = self.events[0].data
|
|
||||||
self.assertEqual(
|
|
||||||
data.get(ATTR_DOMAIN, None), 'persistent_notification')
|
|
||||||
self.assertEqual(data.get(ATTR_SERVICE, None), SERVICE_DISMISS)
|
|
||||||
self.assertNotEqual(data.get(ATTR_SERVICE_DATA, None), None)
|
|
||||||
self.assertEqual(
|
|
||||||
data[ATTR_SERVICE_DATA].get(ATTR_NOTIFICATION_ID, None),
|
|
||||||
HOMEKIT_NOTIFY_ID)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user