mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Convert homekit fans to use service callbacks (#34229)
* Convert homekit fans to use service callbacks * Convert homekit fans to use service callbacks Service callbacks allow us ensure that we call fan services in the correct order. * Avoid calling turn_on if a speed is sent and the device is on * Fix test to not leave files behind * Fix test * Update homeassistant/components/homekit/type_fans.py Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
d6a47cb3e0
commit
e8710002b1
@ -28,7 +28,7 @@ from homeassistant.const import (
|
||||
)
|
||||
|
||||
from . import TYPES
|
||||
from .accessories import HomeAccessory, debounce
|
||||
from .accessories import HomeAccessory
|
||||
from .const import (
|
||||
CHAR_ACTIVE,
|
||||
CHAR_ROTATION_DIRECTION,
|
||||
@ -51,17 +51,11 @@ class Fan(HomeAccessory):
|
||||
def __init__(self, *args):
|
||||
"""Initialize a new Light accessory object."""
|
||||
super().__init__(*args, category=CATEGORY_FAN)
|
||||
self._flag = {
|
||||
CHAR_ACTIVE: False,
|
||||
CHAR_ROTATION_DIRECTION: False,
|
||||
CHAR_SWING_MODE: False,
|
||||
}
|
||||
self._state = 0
|
||||
|
||||
chars = []
|
||||
features = self.hass.states.get(self.entity_id).attributes.get(
|
||||
ATTR_SUPPORTED_FEATURES
|
||||
)
|
||||
state = self.hass.states.get(self.entity_id)
|
||||
|
||||
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
|
||||
if features & SUPPORT_DIRECTION:
|
||||
chars.append(CHAR_ROTATION_DIRECTION)
|
||||
if features & SUPPORT_OSCILLATE:
|
||||
@ -74,9 +68,7 @@ class Fan(HomeAccessory):
|
||||
chars.append(CHAR_ROTATION_SPEED)
|
||||
|
||||
serv_fan = self.add_preload_service(SERV_FANV2, chars)
|
||||
self.char_active = serv_fan.configure_char(
|
||||
CHAR_ACTIVE, value=0, setter_callback=self.set_state
|
||||
)
|
||||
self.char_active = serv_fan.configure_char(CHAR_ACTIVE, value=0)
|
||||
|
||||
self.char_direction = None
|
||||
self.char_speed = None
|
||||
@ -84,26 +76,52 @@ class Fan(HomeAccessory):
|
||||
|
||||
if CHAR_ROTATION_DIRECTION in chars:
|
||||
self.char_direction = serv_fan.configure_char(
|
||||
CHAR_ROTATION_DIRECTION, value=0, setter_callback=self.set_direction
|
||||
CHAR_ROTATION_DIRECTION, value=0
|
||||
)
|
||||
|
||||
if CHAR_ROTATION_SPEED in chars:
|
||||
# Initial value is set to 100 because 0 is a special value (off). 100 is
|
||||
# an arbitrary non-zero value. It is updated immediately by update_state
|
||||
# to set to the correct initial value.
|
||||
self.char_speed = serv_fan.configure_char(
|
||||
CHAR_ROTATION_SPEED, value=100, setter_callback=self.set_speed
|
||||
)
|
||||
self.char_speed = serv_fan.configure_char(CHAR_ROTATION_SPEED, value=100)
|
||||
|
||||
if CHAR_SWING_MODE in chars:
|
||||
self.char_swing = serv_fan.configure_char(
|
||||
CHAR_SWING_MODE, value=0, setter_callback=self.set_oscillating
|
||||
)
|
||||
self.char_swing = serv_fan.configure_char(CHAR_SWING_MODE, value=0)
|
||||
self.update_state(state)
|
||||
serv_fan.setter_callback = self._set_chars
|
||||
|
||||
def _set_chars(self, char_values):
|
||||
_LOGGER.debug("Fan _set_chars: %s", char_values)
|
||||
if CHAR_ACTIVE in char_values:
|
||||
if char_values[CHAR_ACTIVE]:
|
||||
is_on = False
|
||||
state = self.hass.states.get(self.entity_id)
|
||||
if state and state.state == STATE_ON:
|
||||
is_on = True
|
||||
# Only set the state to active if we
|
||||
# did not get a rotation speed or its off
|
||||
if not is_on or CHAR_ROTATION_SPEED not in char_values:
|
||||
self.set_state(1)
|
||||
else:
|
||||
# Its off, nothing more to do as setting the
|
||||
# other chars will likely turn it back on which
|
||||
# is what we want to avoid
|
||||
self.set_state(0)
|
||||
return
|
||||
|
||||
if CHAR_SWING_MODE in char_values:
|
||||
self.set_oscillating(char_values[CHAR_SWING_MODE])
|
||||
if CHAR_ROTATION_DIRECTION in char_values:
|
||||
self.set_direction(char_values[CHAR_ROTATION_DIRECTION])
|
||||
|
||||
# We always do this LAST to ensure they
|
||||
# get the speed they asked for
|
||||
if CHAR_ROTATION_SPEED in char_values:
|
||||
self.set_speed(char_values[CHAR_ROTATION_SPEED])
|
||||
|
||||
def set_state(self, value):
|
||||
"""Set state if call came from HomeKit."""
|
||||
_LOGGER.debug("%s: Set state to %d", self.entity_id, value)
|
||||
self._flag[CHAR_ACTIVE] = True
|
||||
service = SERVICE_TURN_ON if value == 1 else SERVICE_TURN_OFF
|
||||
params = {ATTR_ENTITY_ID: self.entity_id}
|
||||
self.call_service(DOMAIN, service, params)
|
||||
@ -111,7 +129,6 @@ class Fan(HomeAccessory):
|
||||
def set_direction(self, value):
|
||||
"""Set state if call came from HomeKit."""
|
||||
_LOGGER.debug("%s: Set direction to %d", self.entity_id, value)
|
||||
self._flag[CHAR_ROTATION_DIRECTION] = True
|
||||
direction = DIRECTION_REVERSE if value == 1 else DIRECTION_FORWARD
|
||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_DIRECTION: direction}
|
||||
self.call_service(DOMAIN, SERVICE_SET_DIRECTION, params, direction)
|
||||
@ -119,12 +136,10 @@ class Fan(HomeAccessory):
|
||||
def set_oscillating(self, value):
|
||||
"""Set state if call came from HomeKit."""
|
||||
_LOGGER.debug("%s: Set oscillating to %d", self.entity_id, value)
|
||||
self._flag[CHAR_SWING_MODE] = True
|
||||
oscillating = value == 1
|
||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_OSCILLATING: oscillating}
|
||||
self.call_service(DOMAIN, SERVICE_OSCILLATE, params, oscillating)
|
||||
|
||||
@debounce
|
||||
def set_speed(self, value):
|
||||
"""Set state if call came from HomeKit."""
|
||||
_LOGGER.debug("%s: Set speed to %d", self.entity_id, value)
|
||||
@ -138,21 +153,16 @@ class Fan(HomeAccessory):
|
||||
state = new_state.state
|
||||
if state in (STATE_ON, STATE_OFF):
|
||||
self._state = 1 if state == STATE_ON else 0
|
||||
if not self._flag[CHAR_ACTIVE] and self.char_active.value != self._state:
|
||||
if self.char_active.value != self._state:
|
||||
self.char_active.set_value(self._state)
|
||||
self._flag[CHAR_ACTIVE] = False
|
||||
|
||||
# Handle Direction
|
||||
if self.char_direction is not None:
|
||||
direction = new_state.attributes.get(ATTR_DIRECTION)
|
||||
if not self._flag[CHAR_ROTATION_DIRECTION] and direction in (
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
):
|
||||
if direction in (DIRECTION_FORWARD, DIRECTION_REVERSE):
|
||||
hk_direction = 1 if direction == DIRECTION_REVERSE else 0
|
||||
if self.char_direction.value != hk_direction:
|
||||
self.char_direction.set_value(hk_direction)
|
||||
self._flag[CHAR_ROTATION_DIRECTION] = False
|
||||
|
||||
# Handle Speed
|
||||
if self.char_speed is not None:
|
||||
@ -170,17 +180,15 @@ class Fan(HomeAccessory):
|
||||
# Therefore, if the hk_speed_value is 0 and the device is still on,
|
||||
# the rotation speed is mapped to 1 otherwise the update is ignored
|
||||
# in order to avoid this incorrect behavior.
|
||||
if hk_speed_value == 0:
|
||||
if state == STATE_ON:
|
||||
self.char_speed.set_value(1)
|
||||
else:
|
||||
if hk_speed_value == 0 and state == STATE_ON:
|
||||
hk_speed_value = 1
|
||||
if self.char_speed.value != hk_speed_value:
|
||||
self.char_speed.set_value(hk_speed_value)
|
||||
|
||||
# Handle Oscillating
|
||||
if self.char_swing is not None:
|
||||
oscillating = new_state.attributes.get(ATTR_OSCILLATING)
|
||||
if not self._flag[CHAR_SWING_MODE] and oscillating in (True, False):
|
||||
if isinstance(oscillating, bool):
|
||||
hk_oscillating = 1 if oscillating else 0
|
||||
if self.char_swing.value != hk_oscillating:
|
||||
self.char_swing.set_value(hk_oscillating)
|
||||
self._flag[CHAR_SWING_MODE] = False
|
||||
|
@ -15,8 +15,10 @@ def hk_driver():
|
||||
"pyhap.accessory_driver.AccessoryEncoder"
|
||||
), patch("pyhap.accessory_driver.HAPServer"), patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.publish"
|
||||
), patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.persist"
|
||||
):
|
||||
return AccessoryDriver(pincode=b"123-45-678", address="127.0.0.1")
|
||||
yield AccessoryDriver(pincode=b"123-45-678", address="127.0.0.1")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -2,6 +2,7 @@
|
||||
from collections import namedtuple
|
||||
from unittest.mock import Mock
|
||||
|
||||
from pyhap.const import HAP_REPR_AID, HAP_REPR_CHARS, HAP_REPR_IID, HAP_REPR_VALUE
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
@ -53,11 +54,12 @@ async def test_fan_basic(hass, hk_driver, cls, events):
|
||||
|
||||
hass.states.async_set(entity_id, STATE_ON, {ATTR_SUPPORTED_FEATURES: 0})
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 2, None)
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.aid == 2
|
||||
assert acc.aid == 1
|
||||
assert acc.category == 3 # Fan
|
||||
assert acc.char_active.value == 0
|
||||
assert acc.char_active.value == 1
|
||||
|
||||
# If there are no speed_list values, then HomeKit speed is unsupported
|
||||
assert acc.char_speed is None
|
||||
@ -82,7 +84,20 @@ async def test_fan_basic(hass, hk_driver, cls, events):
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
call_turn_off = async_mock_service(hass, DOMAIN, "turn_off")
|
||||
|
||||
await hass.async_add_executor_job(acc.char_active.client_update_value, 1)
|
||||
char_active_iid = acc.char_active.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_active_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert call_turn_on
|
||||
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
@ -92,7 +107,18 @@ async def test_fan_basic(hass, hk_driver, cls, events):
|
||||
hass.states.async_set(entity_id, STATE_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
await hass.async_add_executor_job(acc.char_active.client_update_value, 0)
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_active_iid,
|
||||
HAP_REPR_VALUE: 0,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert call_turn_off
|
||||
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
@ -110,7 +136,8 @@ async def test_fan_direction(hass, hk_driver, cls, events):
|
||||
{ATTR_SUPPORTED_FEATURES: SUPPORT_DIRECTION, ATTR_DIRECTION: DIRECTION_FORWARD},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 2, None)
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.char_direction.value == 0
|
||||
|
||||
@ -125,7 +152,20 @@ async def test_fan_direction(hass, hk_driver, cls, events):
|
||||
# Set from HomeKit
|
||||
call_set_direction = async_mock_service(hass, DOMAIN, "set_direction")
|
||||
|
||||
await hass.async_add_executor_job(acc.char_direction.client_update_value, 0)
|
||||
char_direction_iid = acc.char_direction.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_direction_iid,
|
||||
HAP_REPR_VALUE: 0,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert call_set_direction[0]
|
||||
assert call_set_direction[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
@ -133,6 +173,18 @@ async def test_fan_direction(hass, hk_driver, cls, events):
|
||||
assert len(events) == 1
|
||||
assert events[-1].data[ATTR_VALUE] == DIRECTION_FORWARD
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_direction_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_add_executor_job(acc.char_direction.client_update_value, 1)
|
||||
await hass.async_block_till_done()
|
||||
assert call_set_direction[1]
|
||||
@ -152,7 +204,8 @@ async def test_fan_oscillate(hass, hk_driver, cls, events):
|
||||
{ATTR_SUPPORTED_FEATURES: SUPPORT_OSCILLATE, ATTR_OSCILLATING: False},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 2, None)
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.char_swing.value == 0
|
||||
|
||||
@ -167,6 +220,20 @@ async def test_fan_oscillate(hass, hk_driver, cls, events):
|
||||
# Set from HomeKit
|
||||
call_oscillate = async_mock_service(hass, DOMAIN, "oscillate")
|
||||
|
||||
char_swing_iid = acc.char_swing.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_swing_iid,
|
||||
HAP_REPR_VALUE: 0,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_add_executor_job(acc.char_swing.client_update_value, 0)
|
||||
await hass.async_block_till_done()
|
||||
assert call_oscillate[0]
|
||||
@ -175,6 +242,18 @@ async def test_fan_oscillate(hass, hk_driver, cls, events):
|
||||
assert len(events) == 1
|
||||
assert events[-1].data[ATTR_VALUE] is False
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_swing_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_add_executor_job(acc.char_swing.client_update_value, 1)
|
||||
await hass.async_block_till_done()
|
||||
assert call_oscillate[1]
|
||||
@ -199,7 +278,8 @@ async def test_fan_speed(hass, hk_driver, cls, events):
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 2, None)
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
|
||||
# speed to 100 when turning on a fan on a freshly booted up server.
|
||||
@ -221,6 +301,20 @@ async def test_fan_speed(hass, hk_driver, cls, events):
|
||||
# Set from HomeKit
|
||||
call_set_speed = async_mock_service(hass, DOMAIN, "set_speed")
|
||||
|
||||
char_speed_iid = acc.char_speed.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_speed_iid,
|
||||
HAP_REPR_VALUE: 42,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_add_executor_job(acc.char_speed.client_update_value, 42)
|
||||
await hass.async_block_till_done()
|
||||
acc.speed_mapping.speed_to_states.assert_called_with(42)
|
||||
@ -231,6 +325,211 @@ async def test_fan_speed(hass, hk_driver, cls, events):
|
||||
assert events[-1].data[ATTR_VALUE] == "ludicrous"
|
||||
|
||||
|
||||
async def test_fan_set_all_one_shot(hass, hk_driver, cls, events):
|
||||
"""Test fan with speed."""
|
||||
entity_id = "fan.demo"
|
||||
speed_list = [SPEED_OFF, SPEED_LOW, SPEED_HIGH]
|
||||
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED
|
||||
| SUPPORT_OSCILLATE
|
||||
| SUPPORT_DIRECTION,
|
||||
ATTR_SPEED: SPEED_OFF,
|
||||
ATTR_OSCILLATING: False,
|
||||
ATTR_DIRECTION: DIRECTION_FORWARD,
|
||||
ATTR_SPEED_LIST: speed_list,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
|
||||
# speed to 100 when turning on a fan on a freshly booted up server.
|
||||
assert acc.char_speed.value != 0
|
||||
await acc.run_handler()
|
||||
assert (
|
||||
acc.speed_mapping.speed_ranges == HomeKitSpeedMapping(speed_list).speed_ranges
|
||||
)
|
||||
|
||||
acc.speed_mapping.speed_to_homekit = Mock(return_value=42)
|
||||
acc.speed_mapping.speed_to_states = Mock(return_value="ludicrous")
|
||||
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
STATE_OFF,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED
|
||||
| SUPPORT_OSCILLATE
|
||||
| SUPPORT_DIRECTION,
|
||||
ATTR_SPEED: SPEED_OFF,
|
||||
ATTR_OSCILLATING: False,
|
||||
ATTR_DIRECTION: DIRECTION_FORWARD,
|
||||
ATTR_SPEED_LIST: speed_list,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
# Set from HomeKit
|
||||
call_set_speed = async_mock_service(hass, DOMAIN, "set_speed")
|
||||
call_oscillate = async_mock_service(hass, DOMAIN, "oscillate")
|
||||
call_set_direction = async_mock_service(hass, DOMAIN, "set_direction")
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
call_turn_off = async_mock_service(hass, DOMAIN, "turn_off")
|
||||
|
||||
char_active_iid = acc.char_active.to_HAP()[HAP_REPR_IID]
|
||||
char_direction_iid = acc.char_direction.to_HAP()[HAP_REPR_IID]
|
||||
char_swing_iid = acc.char_swing.to_HAP()[HAP_REPR_IID]
|
||||
char_speed_iid = acc.char_speed.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_active_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_speed_iid,
|
||||
HAP_REPR_VALUE: 42,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_swing_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_direction_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc.speed_mapping.speed_to_states.assert_called_with(42)
|
||||
assert call_turn_on
|
||||
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_set_speed[0]
|
||||
assert call_set_speed[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_set_speed[0].data[ATTR_SPEED] == "ludicrous"
|
||||
assert call_oscillate[0]
|
||||
assert call_oscillate[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_oscillate[0].data[ATTR_OSCILLATING] is True
|
||||
assert call_set_direction[0]
|
||||
assert call_set_direction[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_set_direction[0].data[ATTR_DIRECTION] == DIRECTION_REVERSE
|
||||
assert len(events) == 4
|
||||
|
||||
assert events[1].data[ATTR_VALUE] is True
|
||||
assert events[2].data[ATTR_VALUE] == DIRECTION_REVERSE
|
||||
assert events[3].data[ATTR_VALUE] == "ludicrous"
|
||||
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED
|
||||
| SUPPORT_OSCILLATE
|
||||
| SUPPORT_DIRECTION,
|
||||
ATTR_SPEED: SPEED_OFF,
|
||||
ATTR_OSCILLATING: False,
|
||||
ATTR_DIRECTION: DIRECTION_FORWARD,
|
||||
ATTR_SPEED_LIST: speed_list,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_active_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_speed_iid,
|
||||
HAP_REPR_VALUE: 42,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_swing_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_direction_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
# Turn on should not be called if its already on
|
||||
# and we set a fan speed
|
||||
await hass.async_block_till_done()
|
||||
acc.speed_mapping.speed_to_states.assert_called_with(42)
|
||||
assert len(events) == 7
|
||||
assert call_set_speed[1]
|
||||
assert call_set_speed[1].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_set_speed[1].data[ATTR_SPEED] == "ludicrous"
|
||||
assert call_oscillate[1]
|
||||
assert call_oscillate[1].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_oscillate[1].data[ATTR_OSCILLATING] is True
|
||||
assert call_set_direction[1]
|
||||
assert call_set_direction[1].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_set_direction[1].data[ATTR_DIRECTION] == DIRECTION_REVERSE
|
||||
|
||||
assert events[-3].data[ATTR_VALUE] is True
|
||||
assert events[-2].data[ATTR_VALUE] == DIRECTION_REVERSE
|
||||
assert events[-1].data[ATTR_VALUE] == "ludicrous"
|
||||
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_active_iid,
|
||||
HAP_REPR_VALUE: 0,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_speed_iid,
|
||||
HAP_REPR_VALUE: 42,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_swing_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
{
|
||||
HAP_REPR_AID: acc.aid,
|
||||
HAP_REPR_IID: char_direction_iid,
|
||||
HAP_REPR_VALUE: 1,
|
||||
},
|
||||
]
|
||||
},
|
||||
"mock_addr",
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 8
|
||||
assert call_turn_off
|
||||
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert len(call_set_speed) == 2
|
||||
assert len(call_oscillate) == 2
|
||||
assert len(call_set_direction) == 2
|
||||
|
||||
|
||||
async def test_fan_restore(hass, hk_driver, cls, events):
|
||||
"""Test setting up an entity from state in the event registry."""
|
||||
hass.state = CoreState.not_running
|
||||
|
@ -1,8 +1,6 @@
|
||||
"""Test different accessory types: Lights."""
|
||||
from collections import namedtuple
|
||||
|
||||
from asynctest import patch
|
||||
from pyhap.accessory_driver import AccessoryDriver
|
||||
from pyhap.const import HAP_REPR_AID, HAP_REPR_CHARS, HAP_REPR_IID, HAP_REPR_VALUE
|
||||
import pytest
|
||||
|
||||
@ -33,15 +31,6 @@ from tests.common import async_mock_service
|
||||
from tests.components.homekit.common import patch_debounce
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def driver():
|
||||
"""Patch AccessoryDriver without zeroconf or HAPServer."""
|
||||
with patch("pyhap.accessory_driver.HAPServer"), patch(
|
||||
"pyhap.accessory_driver.Zeroconf"
|
||||
), patch("pyhap.accessory_driver.AccessoryDriver.persist"):
|
||||
yield AccessoryDriver()
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def cls():
|
||||
"""Patch debounce decorator during import of type_lights."""
|
||||
@ -55,14 +44,14 @@ def cls():
|
||||
patcher.stop()
|
||||
|
||||
|
||||
async def test_light_basic(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_basic(hass, hk_driver, cls, events):
|
||||
"""Test light with char state."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
hass.states.async_set(entity_id, STATE_ON, {ATTR_SUPPORTED_FEATURES: 0})
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.aid == 1
|
||||
assert acc.category == 5 # Lightbulb
|
||||
@ -90,7 +79,7 @@ async def test_light_basic(hass, hk_driver, cls, events, driver):
|
||||
|
||||
char_on_iid = acc.char_on.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1}
|
||||
@ -109,7 +98,7 @@ async def test_light_basic(hass, hk_driver, cls, events, driver):
|
||||
hass.states.async_set(entity_id, STATE_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 0}
|
||||
@ -124,7 +113,7 @@ async def test_light_basic(hass, hk_driver, cls, events, driver):
|
||||
assert events[-1].data[ATTR_VALUE] == "Set state to 0"
|
||||
|
||||
|
||||
async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_brightness(hass, hk_driver, cls, events):
|
||||
"""Test light with brightness."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
@ -135,7 +124,7 @@ async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
|
||||
# brightness to 100 when turning on a light on a freshly booted up server.
|
||||
@ -155,7 +144,7 @@ async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
call_turn_off = async_mock_service(hass, DOMAIN, "turn_off")
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
|
||||
@ -178,7 +167,7 @@ async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
== f"Set state to 1, brightness at 20{UNIT_PERCENTAGE}"
|
||||
)
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
|
||||
@ -201,7 +190,7 @@ async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
== f"Set state to 1, brightness at 40{UNIT_PERCENTAGE}"
|
||||
)
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
|
||||
@ -247,7 +236,7 @@ async def test_light_brightness(hass, hk_driver, cls, events, driver):
|
||||
assert acc.char_brightness.value == 1
|
||||
|
||||
|
||||
async def test_light_color_temperature(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_color_temperature(hass, hk_driver, cls, events):
|
||||
"""Test light with color temperature."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
@ -258,7 +247,7 @@ async def test_light_color_temperature(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.char_color_temperature.value == 190
|
||||
|
||||
@ -271,7 +260,7 @@ async def test_light_color_temperature(hass, hk_driver, cls, events, driver):
|
||||
|
||||
char_color_temperature_iid = acc.char_color_temperature.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -313,7 +302,7 @@ async def test_light_color_temperature_and_rgb_color(hass, hk_driver, cls, event
|
||||
assert not hasattr(acc, "char_color_temperature")
|
||||
|
||||
|
||||
async def test_light_rgb_color(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_rgb_color(hass, hk_driver, cls, events):
|
||||
"""Test light with rgb_color."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
@ -324,7 +313,7 @@ async def test_light_rgb_color(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.char_hue.value == 260
|
||||
assert acc.char_saturation.value == 90
|
||||
@ -340,7 +329,7 @@ async def test_light_rgb_color(hass, hk_driver, cls, events, driver):
|
||||
char_hue_iid = acc.char_hue.to_HAP()[HAP_REPR_IID]
|
||||
char_saturation_iid = acc.char_saturation.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -365,7 +354,7 @@ async def test_light_rgb_color(hass, hk_driver, cls, events, driver):
|
||||
assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)"
|
||||
|
||||
|
||||
async def test_light_restore(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_restore(hass, hk_driver, cls, events):
|
||||
"""Test setting up an entity from state in the event registry."""
|
||||
hass.state = CoreState.not_running
|
||||
|
||||
@ -386,7 +375,7 @@ async def test_light_restore(hass, hk_driver, cls, events, driver):
|
||||
await hass.async_block_till_done()
|
||||
|
||||
acc = cls.light(hass, hk_driver, "Light", "light.simple", 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
assert acc.category == 5 # Lightbulb
|
||||
assert acc.chars == []
|
||||
@ -398,7 +387,7 @@ async def test_light_restore(hass, hk_driver, cls, events, driver):
|
||||
assert acc.char_on.value == 0
|
||||
|
||||
|
||||
async def test_light_set_brightness_and_color(hass, hk_driver, cls, events, driver):
|
||||
async def test_light_set_brightness_and_color(hass, hk_driver, cls, events):
|
||||
"""Test light with all chars in one go."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
@ -412,7 +401,7 @@ async def test_light_set_brightness_and_color(hass, hk_driver, cls, events, driv
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
|
||||
# brightness to 100 when turning on a light on a freshly booted up server.
|
||||
@ -438,7 +427,7 @@ async def test_light_set_brightness_and_color(hass, hk_driver, cls, events, driv
|
||||
# Set from HomeKit
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
|
||||
@ -474,9 +463,7 @@ async def test_light_set_brightness_and_color(hass, hk_driver, cls, events, driv
|
||||
)
|
||||
|
||||
|
||||
async def test_light_set_brightness_and_color_temp(
|
||||
hass, hk_driver, cls, events, driver
|
||||
):
|
||||
async def test_light_set_brightness_and_color_temp(hass, hk_driver, cls, events):
|
||||
"""Test light with all chars in one go."""
|
||||
entity_id = "light.demo"
|
||||
|
||||
@ -490,7 +477,7 @@ async def test_light_set_brightness_and_color_temp(
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.light(hass, hk_driver, "Light", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
# Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the
|
||||
# brightness to 100 when turning on a light on a freshly booted up server.
|
||||
@ -514,7 +501,7 @@ async def test_light_set_brightness_and_color_temp(
|
||||
# Set from HomeKit
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: 1},
|
||||
|
@ -2,7 +2,6 @@
|
||||
from collections import namedtuple
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyhap.accessory_driver import AccessoryDriver
|
||||
from pyhap.const import HAP_REPR_AID, HAP_REPR_CHARS, HAP_REPR_IID, HAP_REPR_VALUE
|
||||
import pytest
|
||||
|
||||
@ -62,15 +61,6 @@ from tests.common import async_mock_service
|
||||
from tests.components.homekit.common import patch_debounce
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def driver():
|
||||
"""Patch AccessoryDriver without zeroconf or HAPServer."""
|
||||
with patch("pyhap.accessory_driver.HAPServer"), patch(
|
||||
"pyhap.accessory_driver.Zeroconf"
|
||||
), patch("pyhap.accessory_driver.AccessoryDriver.persist"):
|
||||
yield AccessoryDriver()
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def cls():
|
||||
"""Patch debounce decorator during import of type_thermostats."""
|
||||
@ -85,7 +75,7 @@ def cls():
|
||||
patcher.stop()
|
||||
|
||||
|
||||
async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
async def test_thermostat(hass, hk_driver, cls, events):
|
||||
"""Test if accessory and HA are updated accordingly."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -106,7 +96,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -293,7 +283,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
char_target_temp_iid = acc.char_target_temp.to_HAP()[HAP_REPR_IID]
|
||||
char_heat_cool_iid = acc.char_target_heat_cool.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -313,7 +303,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
assert len(events) == 1
|
||||
assert events[-1].data[ATTR_VALUE] == "TargetTemperature to 19.0°C"
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -328,7 +318,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
await hass.async_block_till_done()
|
||||
assert not call_set_hvac_mode
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -348,7 +338,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
assert len(events) == 2
|
||||
assert events[-1].data[ATTR_VALUE] == "TargetHeatingCoolingState to 1"
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -369,7 +359,7 @@ async def test_thermostat(hass, hk_driver, cls, events, driver):
|
||||
assert events[-1].data[ATTR_VALUE] == "TargetHeatingCoolingState to 3"
|
||||
|
||||
|
||||
async def test_thermostat_auto(hass, hk_driver, cls, events, driver):
|
||||
async def test_thermostat_auto(hass, hk_driver, cls, events):
|
||||
"""Test if accessory and HA are updated accordingly."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -384,7 +374,7 @@ async def test_thermostat_auto(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -459,7 +449,7 @@ async def test_thermostat_auto(hass, hk_driver, cls, events, driver):
|
||||
char_heating_thresh_temp_iid = acc.char_heating_thresh_temp.to_HAP()[HAP_REPR_IID]
|
||||
char_cooling_thresh_temp_iid = acc.char_cooling_thresh_temp.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -491,7 +481,7 @@ async def test_thermostat_auto(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
|
||||
|
||||
async def test_thermostat_humidity(hass, hk_driver, cls, events, driver):
|
||||
async def test_thermostat_humidity(hass, hk_driver, cls, events):
|
||||
"""Test if accessory and HA are updated accordingly with humidity."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -499,7 +489,7 @@ async def test_thermostat_humidity(hass, hk_driver, cls, events, driver):
|
||||
hass.states.async_set(entity_id, HVAC_MODE_OFF, {ATTR_SUPPORTED_FEATURES: 4})
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -528,7 +518,7 @@ async def test_thermostat_humidity(hass, hk_driver, cls, events, driver):
|
||||
|
||||
char_target_humidity_iid = acc.char_target_humidity.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -550,7 +540,7 @@ async def test_thermostat_humidity(hass, hk_driver, cls, events, driver):
|
||||
assert events[-1].data[ATTR_VALUE] == "35%"
|
||||
|
||||
|
||||
async def test_thermostat_power_state(hass, hk_driver, cls, events, driver):
|
||||
async def test_thermostat_power_state(hass, hk_driver, cls, events):
|
||||
"""Test if accessory and HA are updated accordingly."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -574,7 +564,7 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events, driver):
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -627,7 +617,7 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events, driver):
|
||||
|
||||
char_target_heat_cool_iid = acc.char_target_heat_cool.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -648,7 +638,7 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events, driver):
|
||||
assert len(events) == 1
|
||||
assert events[-1].data[ATTR_VALUE] == "TargetHeatingCoolingState to 1"
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -670,7 +660,7 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events, driver):
|
||||
assert acc.char_target_heat_cool.value == 2
|
||||
|
||||
|
||||
async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
async def test_thermostat_fahrenheit(hass, hk_driver, cls, events):
|
||||
"""Test if accessory and HA are updated accordingly."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -686,7 +676,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
await hass.async_block_till_done()
|
||||
with patch.object(hass.config.units, CONF_TEMPERATURE_UNIT, new=TEMP_FAHRENHEIT):
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@ -717,7 +707,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
char_heating_thresh_temp_iid = acc.char_heating_thresh_temp.to_HAP()[HAP_REPR_IID]
|
||||
char_target_temp_iid = acc.char_target_temp.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -738,7 +728,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
assert len(events) == 1
|
||||
assert events[-1].data[ATTR_VALUE] == "CoolingThresholdTemperature to 23°C"
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -759,7 +749,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
assert len(events) == 2
|
||||
assert events[-1].data[ATTR_VALUE] == "HeatingThresholdTemperature to 22°C"
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -779,7 +769,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events, driver):
|
||||
assert events[-1].data[ATTR_VALUE] == "TargetTemperature to 24.0°C"
|
||||
|
||||
|
||||
async def test_thermostat_get_temperature_range(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_get_temperature_range(hass, hk_driver, cls):
|
||||
"""Test if temperature range is evaluated correctly."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -801,14 +791,14 @@ async def test_thermostat_get_temperature_range(hass, hk_driver, cls, driver):
|
||||
assert acc.get_temperature_range() == (15.5, 21.0)
|
||||
|
||||
|
||||
async def test_thermostat_temperature_step_whole(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_temperature_step_whole(hass, hk_driver, cls):
|
||||
"""Test climate device with single digit precision."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
hass.states.async_set(entity_id, HVAC_MODE_OFF, {ATTR_TARGET_TEMP_STEP: 1})
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -861,7 +851,7 @@ async def test_thermostat_restore(hass, hk_driver, cls, events):
|
||||
}
|
||||
|
||||
|
||||
async def test_thermostat_hvac_modes(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_hvac_modes(hass, hk_driver, cls):
|
||||
"""Test if unsupported HVAC modes are deactivated in HomeKit."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -871,7 +861,7 @@ async def test_thermostat_hvac_modes(hass, hk_driver, cls, driver):
|
||||
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -894,7 +884,7 @@ async def test_thermostat_hvac_modes(hass, hk_driver, cls, driver):
|
||||
assert acc.char_target_heat_cool.value == 1
|
||||
|
||||
|
||||
async def test_thermostat_hvac_modes_with_auto_heat_cool(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_hvac_modes_with_auto_heat_cool(hass, hk_driver, cls):
|
||||
"""Test we get heat cool over auto."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -914,7 +904,7 @@ async def test_thermostat_hvac_modes_with_auto_heat_cool(hass, hk_driver, cls, d
|
||||
await hass.async_block_till_done()
|
||||
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -937,7 +927,7 @@ async def test_thermostat_hvac_modes_with_auto_heat_cool(hass, hk_driver, cls, d
|
||||
|
||||
char_target_heat_cool_iid = acc.char_target_heat_cool.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -957,9 +947,7 @@ async def test_thermostat_hvac_modes_with_auto_heat_cool(hass, hk_driver, cls, d
|
||||
assert acc.char_target_heat_cool.value == 3
|
||||
|
||||
|
||||
async def test_thermostat_hvac_modes_with_auto_no_heat_cool(
|
||||
hass, hk_driver, cls, driver
|
||||
):
|
||||
async def test_thermostat_hvac_modes_with_auto_no_heat_cool(hass, hk_driver, cls):
|
||||
"""Test we get auto when there is no heat cool."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -972,7 +960,7 @@ async def test_thermostat_hvac_modes_with_auto_no_heat_cool(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -995,7 +983,7 @@ async def test_thermostat_hvac_modes_with_auto_no_heat_cool(
|
||||
|
||||
char_target_heat_cool_iid = acc.char_target_heat_cool.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -1015,7 +1003,7 @@ async def test_thermostat_hvac_modes_with_auto_no_heat_cool(
|
||||
assert acc.char_target_heat_cool.value == 3
|
||||
|
||||
|
||||
async def test_thermostat_hvac_modes_with_auto_only(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_hvac_modes_with_auto_only(hass, hk_driver, cls):
|
||||
"""Test if unsupported HVAC modes are deactivated in HomeKit."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -1025,7 +1013,7 @@ async def test_thermostat_hvac_modes_with_auto_only(hass, hk_driver, cls, driver
|
||||
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -1048,7 +1036,7 @@ async def test_thermostat_hvac_modes_with_auto_only(hass, hk_driver, cls, driver
|
||||
assert acc.char_target_heat_cool.value == 3
|
||||
|
||||
|
||||
async def test_thermostat_hvac_modes_without_off(hass, hk_driver, cls, driver):
|
||||
async def test_thermostat_hvac_modes_without_off(hass, hk_driver, cls):
|
||||
"""Test a thermostat that has no off."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -1058,7 +1046,7 @@ async def test_thermostat_hvac_modes_without_off(hass, hk_driver, cls, driver):
|
||||
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -1085,9 +1073,7 @@ async def test_thermostat_hvac_modes_without_off(hass, hk_driver, cls, driver):
|
||||
assert acc.char_target_heat_cool.value == 1
|
||||
|
||||
|
||||
async def test_thermostat_without_target_temp_only_range(
|
||||
hass, hk_driver, cls, events, driver
|
||||
):
|
||||
async def test_thermostat_without_target_temp_only_range(hass, hk_driver, cls, events):
|
||||
"""Test a thermostat that only supports a range."""
|
||||
entity_id = "climate.test"
|
||||
|
||||
@ -1099,7 +1085,7 @@ async def test_thermostat_without_target_temp_only_range(
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||
driver.add_accessory(acc)
|
||||
hk_driver.add_accessory(acc)
|
||||
|
||||
await acc.run_handler()
|
||||
await hass.async_block_till_done()
|
||||
@ -1176,7 +1162,7 @@ async def test_thermostat_without_target_temp_only_range(
|
||||
|
||||
char_target_temp_iid = acc.char_target_temp.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
@ -1222,7 +1208,7 @@ async def test_thermostat_without_target_temp_only_range(
|
||||
|
||||
char_target_temp_iid = acc.char_target_temp.to_HAP()[HAP_REPR_IID]
|
||||
|
||||
driver.set_characteristics(
|
||||
hk_driver.set_characteristics(
|
||||
{
|
||||
HAP_REPR_CHARS: [
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user