Homekit component cleanup (#17627)

* hass.async_add_executor_job
* Fix accessories.run -> async_track_state_change
* Fixed media_player test
* Flags are now local vars
* consistent use of " and '
pull/17634/head
cdce8p 2018-10-20 00:14:05 +02:00 committed by GitHub
parent 3655fefec2
commit a9a8cbbd10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 120 additions and 114 deletions

View File

@ -78,7 +78,7 @@ async def async_setup(hass, config):
homekit = HomeKit(hass, name, port, ip_address, entity_filter,
entity_config)
await hass.async_add_job(homekit.setup)
await hass.async_add_executor_job(homekit.setup)
if auto_start:
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, homekit.start)

View File

@ -35,7 +35,7 @@ def debounce(func):
"""Handle call_later callback."""
debounce_params = self.debounce.pop(func.__name__, None)
if debounce_params:
self.hass.async_add_job(func, self, *debounce_params[1:])
self.hass.async_add_executor_job(func, self, *debounce_params[1:])
@wraps(func)
def wrapper(self, *args):
@ -94,8 +94,15 @@ class HomeAccessory(Accessory):
Run inside the HAP-python event loop.
"""
self.hass.add_job(self.run_handler)
async def run_handler(self):
"""Handle accessory driver started event.
Run inside the Home Assistant event loop.
"""
state = self.hass.states.get(self.entity_id)
self.hass.add_job(self.update_state_callback, None, None, state)
self.hass.async_add_job(self.update_state_callback, None, None, state)
async_track_state_change(
self.hass, self.entity_id, self.update_state_callback)
@ -107,8 +114,8 @@ class HomeAccessory(Accessory):
if new_state is None:
return
if self._support_battery_level:
self.hass.async_add_job(self.update_battery, new_state)
self.hass.async_add_job(self.update_state, new_state)
self.hass.async_add_executor_job(self.update_battery, new_state)
self.hass.async_add_executor_job(self.update_state, new_state)
def update_battery(self, new_state):
"""Update battery service if available.

View File

@ -31,7 +31,7 @@ class GarageDoorOpener(HomeAccessory):
def __init__(self, *args):
"""Initialize a GarageDoorOpener accessory object."""
super().__init__(*args, category=CATEGORY_GARAGE_DOOR_OPENER)
self.flag_target_state = False
self._flag_state = False
serv_garage_door = self.add_preload_service(SERV_GARAGE_DOOR_OPENER)
self.char_current_state = serv_garage_door.configure_char(
@ -42,7 +42,7 @@ class GarageDoorOpener(HomeAccessory):
def set_state(self, value):
"""Change garage state if call came from HomeKit."""
_LOGGER.debug('%s: Set state to %d', self.entity_id, value)
self.flag_target_state = True
self._flag_state = True
params = {ATTR_ENTITY_ID: self.entity_id}
if value == 0:
@ -58,9 +58,9 @@ class GarageDoorOpener(HomeAccessory):
if hass_state in (STATE_OPEN, STATE_CLOSED):
current_state = 0 if hass_state == STATE_OPEN else 1
self.char_current_state.set_value(current_state)
if not self.flag_target_state:
if not self._flag_state:
self.char_target_state.set_value(current_state)
self.flag_target_state = False
self._flag_state = False
@TYPES.register('WindowCovering')
@ -73,7 +73,7 @@ class WindowCovering(HomeAccessory):
def __init__(self, *args):
"""Initialize a WindowCovering accessory object."""
super().__init__(*args, category=CATEGORY_WINDOW_COVERING)
self.homekit_target = None
self._homekit_target = None
serv_cover = self.add_preload_service(SERV_WINDOW_COVERING)
self.char_current_position = serv_cover.configure_char(
@ -85,7 +85,7 @@ class WindowCovering(HomeAccessory):
def move_cover(self, value):
"""Move cover to value if call came from HomeKit."""
_LOGGER.debug('%s: Set position to %d', self.entity_id, value)
self.homekit_target = value
self._homekit_target = value
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_POSITION: value}
self.call_service(DOMAIN, SERVICE_SET_COVER_POSITION, params, value)
@ -95,10 +95,10 @@ class WindowCovering(HomeAccessory):
current_position = new_state.attributes.get(ATTR_CURRENT_POSITION)
if isinstance(current_position, int):
self.char_current_position.set_value(current_position)
if self.homekit_target is None or \
abs(current_position - self.homekit_target) < 6:
if self._homekit_target is None or \
abs(current_position - self._homekit_target) < 6:
self.char_target_position.set_value(current_position)
self.homekit_target = None
self._homekit_target = None
@TYPES.register('WindowCoveringBasic')
@ -114,7 +114,7 @@ class WindowCoveringBasic(HomeAccessory):
super().__init__(*args, category=CATEGORY_WINDOW_COVERING)
features = self.hass.states.get(self.entity_id) \
.attributes.get(ATTR_SUPPORTED_FEATURES)
self.supports_stop = features & SUPPORT_STOP
self._supports_stop = features & SUPPORT_STOP
serv_cover = self.add_preload_service(SERV_WINDOW_COVERING)
self.char_current_position = serv_cover.configure_char(
@ -129,7 +129,7 @@ class WindowCoveringBasic(HomeAccessory):
"""Move cover to value if call came from HomeKit."""
_LOGGER.debug('%s: Set position to %d', self.entity_id, value)
if self.supports_stop:
if self._supports_stop:
if value > 70:
service, position = (SERVICE_OPEN_COVER, 100)
elif value < 30:

View File

@ -34,24 +34,27 @@ class Fan(HomeAccessory):
CHAR_SWING_MODE: False}
self._state = 0
self.chars = []
chars = []
features = self.hass.states.get(self.entity_id) \
.attributes.get(ATTR_SUPPORTED_FEATURES)
if features & SUPPORT_DIRECTION:
self.chars.append(CHAR_ROTATION_DIRECTION)
chars.append(CHAR_ROTATION_DIRECTION)
if features & SUPPORT_OSCILLATE:
self.chars.append(CHAR_SWING_MODE)
chars.append(CHAR_SWING_MODE)
serv_fan = self.add_preload_service(SERV_FANV2, self.chars)
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)
if CHAR_ROTATION_DIRECTION in self.chars:
self.char_direction = None
self.char_swing = None
if CHAR_ROTATION_DIRECTION in chars:
self.char_direction = serv_fan.configure_char(
CHAR_ROTATION_DIRECTION, value=0,
setter_callback=self.set_direction)
if CHAR_SWING_MODE in self.chars:
if CHAR_SWING_MODE in chars:
self.char_swing = serv_fan.configure_char(
CHAR_SWING_MODE, value=0, setter_callback=self.set_oscillating)
@ -92,7 +95,7 @@ class Fan(HomeAccessory):
self._flag[CHAR_ACTIVE] = False
# Handle Direction
if CHAR_ROTATION_DIRECTION in self.chars:
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):
@ -102,7 +105,7 @@ class Fan(HomeAccessory):
self._flag[CHAR_ROTATION_DIRECTION] = False
# Handle Oscillating
if CHAR_SWING_MODE in self.chars:
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):

View File

@ -95,7 +95,7 @@ class Light(HomeAccessory):
return
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_BRIGHTNESS_PCT: value}
self.call_service(DOMAIN, SERVICE_TURN_ON, params,
"brightness at {}%".format(value))
'brightness at {}%'.format(value))
def set_color_temperature(self, value):
"""Set color temperature if call came from HomeKit."""
@ -103,7 +103,7 @@ class Light(HomeAccessory):
self._flag[CHAR_COLOR_TEMPERATURE] = True
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_COLOR_TEMP: value}
self.call_service(DOMAIN, SERVICE_TURN_ON, params,
"color temperature at {}".format(value))
'color temperature at {}'.format(value))
def set_saturation(self, value):
"""Set saturation if call came from HomeKit."""
@ -129,7 +129,7 @@ class Light(HomeAccessory):
CHAR_HUE: False, CHAR_SATURATION: False, RGB_COLOR: True})
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_HS_COLOR: color}
self.call_service(DOMAIN, SERVICE_TURN_ON, params,
"set color at {}".format(color))
'set color at {}'.format(color))
def update_state(self, new_state):
"""Update light after state change."""

View File

@ -33,7 +33,7 @@ class Lock(HomeAccessory):
"""Initialize a Lock accessory object."""
super().__init__(*args, category=CATEGORY_DOOR_LOCK)
self._code = self.config.get(ATTR_CODE)
self.flag_target_state = False
self._flag_state = False
serv_lock_mechanism = self.add_preload_service(SERV_LOCK)
self.char_current_state = serv_lock_mechanism.configure_char(
@ -45,8 +45,8 @@ class Lock(HomeAccessory):
def set_state(self, value):
"""Set lock state to value if call came from HomeKit."""
_LOGGER.debug("%s: Set state to %d", self.entity_id, value)
self.flag_target_state = True
_LOGGER.debug('%s: Set state to %d', self.entity_id, value)
self._flag_state = True
hass_value = HOMEKIT_TO_HASS.get(value)
service = STATE_TO_SERVICE[hass_value]
@ -67,6 +67,6 @@ class Lock(HomeAccessory):
# LockTargetState only supports locked and unlocked
if hass_state in (STATE_LOCKED, STATE_UNLOCKED):
if not self.flag_target_state:
if not self._flag_state:
self.char_target_state.set_value(current_lock_state)
self.flag_target_state = False
self._flag_state = False

View File

@ -39,7 +39,7 @@ class SecuritySystem(HomeAccessory):
"""Initialize a SecuritySystem accessory object."""
super().__init__(*args, category=CATEGORY_ALARM_SYSTEM)
self._alarm_code = self.config.get(ATTR_CODE)
self.flag_target_state = False
self._flag_state = False
serv_alarm = self.add_preload_service(SERV_SECURITY_SYSTEM)
self.char_current_state = serv_alarm.configure_char(
@ -52,7 +52,7 @@ class SecuritySystem(HomeAccessory):
"""Move security state to value if call came from HomeKit."""
_LOGGER.debug('%s: Set security state to %d',
self.entity_id, value)
self.flag_target_state = True
self._flag_state = True
hass_value = HOMEKIT_TO_HASS[value]
service = STATE_TO_SERVICE[hass_value]
@ -71,7 +71,7 @@ class SecuritySystem(HomeAccessory):
self.entity_id, hass_state, current_security_state)
# SecuritySystemTargetState does not support triggered
if not self.flag_target_state and \
if not self._flag_state and \
hass_state != STATE_ALARM_TRIGGERED:
self.char_target_state.set_value(current_security_state)
self.flag_target_state = False
self._flag_state = False

View File

@ -58,7 +58,6 @@ class TemperatureSensor(HomeAccessory):
serv_temp = self.add_preload_service(SERV_TEMPERATURE_SENSOR)
self.char_temp = serv_temp.configure_char(
CHAR_CURRENT_TEMPERATURE, value=0, properties=PROP_CELSIUS)
self.unit = None
def update_state(self, new_state):
"""Update temperature after state changed."""

View File

@ -36,7 +36,7 @@ class Outlet(HomeAccessory):
def __init__(self, *args):
"""Initialize an Outlet accessory object."""
super().__init__(*args, category=CATEGORY_OUTLET)
self.flag_target_state = False
self._flag_state = False
serv_outlet = self.add_preload_service(SERV_OUTLET)
self.char_on = serv_outlet.configure_char(
@ -48,7 +48,7 @@ class Outlet(HomeAccessory):
"""Move switch state to value if call came from HomeKit."""
_LOGGER.debug('%s: Set switch state to %s',
self.entity_id, value)
self.flag_target_state = True
self._flag_state = True
params = {ATTR_ENTITY_ID: self.entity_id}
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
self.call_service(DOMAIN, service, params)
@ -56,11 +56,11 @@ class Outlet(HomeAccessory):
def update_state(self, new_state):
"""Update switch state after state changed."""
current_state = (new_state.state == STATE_ON)
if not self.flag_target_state:
if not self._flag_state:
_LOGGER.debug('%s: Set current state to %s',
self.entity_id, current_state)
self.char_on.set_value(current_state)
self.flag_target_state = False
self._flag_state = False
@TYPES.register('Switch')
@ -71,7 +71,7 @@ class Switch(HomeAccessory):
"""Initialize a Switch accessory object."""
super().__init__(*args, category=CATEGORY_SWITCH)
self._domain = split_entity_id(self.entity_id)[0]
self.flag_target_state = False
self._flag_state = False
serv_switch = self.add_preload_service(SERV_SWITCH)
self.char_on = serv_switch.configure_char(
@ -81,7 +81,7 @@ class Switch(HomeAccessory):
"""Move switch state to value if call came from HomeKit."""
_LOGGER.debug('%s: Set switch state to %s',
self.entity_id, value)
self.flag_target_state = True
self._flag_state = True
params = {ATTR_ENTITY_ID: self.entity_id}
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
self.call_service(self._domain, service, params)
@ -89,11 +89,11 @@ class Switch(HomeAccessory):
def update_state(self, new_state):
"""Update switch state after state changed."""
current_state = (new_state.state == STATE_ON)
if not self.flag_target_state:
if not self._flag_state:
_LOGGER.debug('%s: Set current state to %s',
self.entity_id, current_state)
self.char_on.set_value(current_state)
self.flag_target_state = False
self._flag_state = False
@TYPES.register('Valve')
@ -103,7 +103,7 @@ class Valve(HomeAccessory):
def __init__(self, *args):
"""Initialize a Valve accessory object."""
super().__init__(*args)
self.flag_target_state = False
self._flag_state = False
valve_type = self.config[CONF_TYPE]
self.category = VALVE_TYPE[valve_type][0]
@ -119,7 +119,7 @@ class Valve(HomeAccessory):
"""Move value state to value if call came from HomeKit."""
_LOGGER.debug('%s: Set switch state to %s',
self.entity_id, value)
self.flag_target_state = True
self._flag_state = True
self.char_in_use.set_value(value)
params = {ATTR_ENTITY_ID: self.entity_id}
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
@ -128,9 +128,9 @@ class Valve(HomeAccessory):
def update_state(self, new_state):
"""Update switch state after state changed."""
current_state = (new_state.state == STATE_ON)
if not self.flag_target_state:
if not self._flag_state:
_LOGGER.debug('%s: Set current state to %s',
self.entity_id, current_state)
self.char_active.set_value(current_state)
self.char_in_use.set_value(current_state)
self.flag_target_state = False
self._flag_state = False

View File

@ -51,11 +51,11 @@ class Thermostat(HomeAccessory):
"""Initialize a Thermostat accessory object."""
super().__init__(*args, category=CATEGORY_THERMOSTAT)
self._unit = self.hass.config.units.temperature_unit
self._flag_heat_cool = False
self._flag_temperature = False
self._flag_coolingthresh = False
self._flag_heatingthresh = False
self.support_power_state = False
self.heat_cool_flag_target_state = False
self.temperature_flag_target_state = False
self.coolingthresh_flag_target_state = False
self.heatingthresh_flag_target_state = False
min_temp, max_temp = self.get_temperature_range()
# Add additional characteristics if auto mode is supported
@ -122,28 +122,27 @@ class Thermostat(HomeAccessory):
def set_heat_cool(self, value):
"""Change operation mode to value if call came from HomeKit."""
if value in HC_HOMEKIT_TO_HASS:
_LOGGER.debug('%s: Set heat-cool to %d', self.entity_id, value)
self.heat_cool_flag_target_state = True
hass_value = HC_HOMEKIT_TO_HASS[value]
if self.support_power_state is True:
params = {ATTR_ENTITY_ID: self.entity_id}
if hass_value == STATE_OFF:
self.call_service(DOMAIN_CLIMATE, SERVICE_TURN_OFF, params)
return
self.call_service(DOMAIN_CLIMATE, SERVICE_TURN_ON, params)
params = {ATTR_ENTITY_ID: self.entity_id,
ATTR_OPERATION_MODE: hass_value}
self.call_service(
DOMAIN_CLIMATE, SERVICE_SET_OPERATION_MODE_THERMOSTAT,
params, hass_value)
_LOGGER.debug('%s: Set heat-cool to %d', self.entity_id, value)
self._flag_heat_cool = True
hass_value = HC_HOMEKIT_TO_HASS[value]
if self.support_power_state is True:
params = {ATTR_ENTITY_ID: self.entity_id}
if hass_value == STATE_OFF:
self.call_service(DOMAIN_CLIMATE, SERVICE_TURN_OFF, params)
return
self.call_service(DOMAIN_CLIMATE, SERVICE_TURN_ON, params)
params = {ATTR_ENTITY_ID: self.entity_id,
ATTR_OPERATION_MODE: hass_value}
self.call_service(
DOMAIN_CLIMATE, SERVICE_SET_OPERATION_MODE_THERMOSTAT,
params, hass_value)
@debounce
def set_cooling_threshold(self, value):
"""Set cooling threshold temp to value if call came from HomeKit."""
_LOGGER.debug('%s: Set cooling threshold temperature to %.2f°C',
self.entity_id, value)
self.coolingthresh_flag_target_state = True
self._flag_coolingthresh = True
low = self.char_heating_thresh_temp.value
temperature = temperature_to_states(value, self._unit)
params = {
@ -159,7 +158,7 @@ class Thermostat(HomeAccessory):
"""Set heating threshold temp to value if call came from HomeKit."""
_LOGGER.debug('%s: Set heating threshold temperature to %.2f°C',
self.entity_id, value)
self.heatingthresh_flag_target_state = True
self._flag_heatingthresh = True
high = self.char_cooling_thresh_temp.value
temperature = temperature_to_states(value, self._unit)
params = {
@ -175,14 +174,14 @@ class Thermostat(HomeAccessory):
"""Set target temperature to value if call came from HomeKit."""
_LOGGER.debug('%s: Set target temperature to %.2f°C',
self.entity_id, value)
self.temperature_flag_target_state = True
self._flag_temperature = True
temperature = temperature_to_states(value, self._unit)
params = {
ATTR_ENTITY_ID: self.entity_id,
ATTR_TEMPERATURE: temperature}
self.call_service(
DOMAIN_CLIMATE, SERVICE_SET_TEMPERATURE_THERMOSTAT,
params, 'target {}{}'.format(temperature, self._unit))
params, '{}{}'.format(temperature, self._unit))
def update_state(self, new_state):
"""Update thermostat state after state changed."""
@ -196,9 +195,9 @@ class Thermostat(HomeAccessory):
target_temp = new_state.attributes.get(ATTR_TEMPERATURE)
if isinstance(target_temp, (int, float)):
target_temp = temperature_to_homekit(target_temp, self._unit)
if not self.temperature_flag_target_state:
if not self._flag_temperature:
self.char_target_temp.set_value(target_temp)
self.temperature_flag_target_state = False
self._flag_temperature = False
# Update cooling threshold temperature if characteristic exists
if self.char_cooling_thresh_temp:
@ -206,9 +205,9 @@ class Thermostat(HomeAccessory):
if isinstance(cooling_thresh, (int, float)):
cooling_thresh = temperature_to_homekit(cooling_thresh,
self._unit)
if not self.coolingthresh_flag_target_state:
if not self._flag_coolingthresh:
self.char_cooling_thresh_temp.set_value(cooling_thresh)
self.coolingthresh_flag_target_state = False
self._flag_coolingthresh = False
# Update heating threshold temperature if characteristic exists
if self.char_heating_thresh_temp:
@ -216,9 +215,9 @@ class Thermostat(HomeAccessory):
if isinstance(heating_thresh, (int, float)):
heating_thresh = temperature_to_homekit(heating_thresh,
self._unit)
if not self.heatingthresh_flag_target_state:
if not self._flag_heatingthresh:
self.char_heating_thresh_temp.set_value(heating_thresh)
self.heatingthresh_flag_target_state = False
self._flag_heatingthresh = False
# Update display units
if self._unit and self._unit in UNIT_HASS_TO_HOMEKIT:
@ -227,13 +226,12 @@ class Thermostat(HomeAccessory):
# Update target operation mode
operation_mode = new_state.attributes.get(ATTR_OPERATION_MODE)
if self.support_power_state is True and new_state.state == STATE_OFF:
self.char_target_heat_cool.set_value(
HC_HASS_TO_HOMEKIT[STATE_OFF])
self.char_target_heat_cool.set_value(0) # Off
elif operation_mode and operation_mode in HC_HASS_TO_HOMEKIT:
if not self.heat_cool_flag_target_state:
if not self._flag_heat_cool:
self.char_target_heat_cool.set_value(
HC_HASS_TO_HOMEKIT[operation_mode])
self.heat_cool_flag_target_state = False
self._flag_heat_cool = False
# Set current operation mode based on temperatures and target mode
if self.support_power_state is True and new_state.state == STATE_OFF:
@ -286,8 +284,8 @@ class WaterHeater(HomeAccessory):
"""Initialize a WaterHeater accessory object."""
super().__init__(*args, category=CATEGORY_THERMOSTAT)
self._unit = self.hass.config.units.temperature_unit
self.flag_heat_cool = False
self.flag_temperature = False
self._flag_heat_cool = False
self._flag_temperature = False
min_temp, max_temp = self.get_temperature_range()
serv_thermostat = self.add_preload_service(SERV_THERMOSTAT)
@ -326,7 +324,7 @@ class WaterHeater(HomeAccessory):
def set_heat_cool(self, value):
"""Change operation mode to value if call came from HomeKit."""
_LOGGER.debug('%s: Set heat-cool to %d', self.entity_id, value)
self.flag_heat_cool = True
self._flag_heat_cool = True
hass_value = HC_HOMEKIT_TO_HASS[value]
if hass_value != STATE_HEAT:
self.char_target_heat_cool.set_value(1) # Heat
@ -336,14 +334,14 @@ class WaterHeater(HomeAccessory):
"""Set target temperature to value if call came from HomeKit."""
_LOGGER.debug('%s: Set target temperature to %.2f°C',
self.entity_id, value)
self.flag_temperature = True
self._flag_temperature = True
temperature = temperature_to_states(value, self._unit)
params = {
ATTR_ENTITY_ID: self.entity_id,
ATTR_TEMPERATURE: temperature}
self.call_service(
DOMAIN_WATER_HEATER, SERVICE_SET_TEMPERATURE_WATER_HEATER,
params, 'target {}{}'.format(temperature, self._unit))
params, '{}{}'.format(temperature, self._unit))
def update_state(self, new_state):
"""Update water_heater state after state change."""
@ -352,9 +350,9 @@ class WaterHeater(HomeAccessory):
if isinstance(temperature, (int, float)):
temperature = temperature_to_homekit(temperature, self._unit)
self.char_current_temp.set_value(temperature)
if not self.flag_temperature:
if not self._flag_temperature:
self.char_target_temp.set_value(temperature)
self.flag_temperature = False
self._flag_temperature = False
# Update display units
if self._unit and self._unit in UNIT_HASS_TO_HOMEKIT:
@ -362,6 +360,6 @@ class WaterHeater(HomeAccessory):
# Update target operation mode
operation_mode = new_state.attributes.get(ATTR_OPERATION_MODE)
if operation_mode and not self.flag_heat_cool:
if operation_mode and not self._flag_heat_cool:
self.char_target_heat_cool.set_value(1) # Heat
self.flag_heat_cool = False
self._flag_heat_cool = False

View File

@ -104,7 +104,7 @@ def validate_media_player_features(state, feature_list):
error_list.append(feature)
if error_list:
_LOGGER.error("%s does not support features: %s",
_LOGGER.error('%s does not support features: %s',
state.entity_id, error_list)
return False
return True

View File

@ -4,7 +4,7 @@ from unittest.mock import patch
import pytest
from homeassistant.components.homekit.const import EVENT_HOMEKIT_CHANGED
from homeassistant.core import callback
from homeassistant.core import callback as ha_callback
from pyhap.accessory_driver import AccessoryDriver
@ -25,5 +25,5 @@ def events(hass):
events = []
hass.bus.async_listen(
EVENT_HOMEKIT_CHANGED,
callback(lambda e: events.append(e)))
ha_callback(lambda e: events.append(e)))
yield events

View File

@ -80,7 +80,6 @@ async def test_light_basic(hass, hk_driver, cls, events):
async def test_light_brightness(hass, hk_driver, cls, events):
"""Test light with brightness."""
entity_id = 'light.demo'
event_value = "brightness at "
hass.states.async_set(entity_id, STATE_ON, {
ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
@ -108,7 +107,7 @@ async def test_light_brightness(hass, hk_driver, cls, events):
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[0].data[ATTR_BRIGHTNESS_PCT] == 20
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == "{}20%".format(event_value)
assert events[-1].data[ATTR_VALUE] == 'brightness at 20%'
await hass.async_add_job(acc.char_on.client_update_value, 1)
await hass.async_add_job(acc.char_brightness.client_update_value, 40)
@ -117,7 +116,7 @@ async def test_light_brightness(hass, hk_driver, cls, events):
assert call_turn_on[1].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[1].data[ATTR_BRIGHTNESS_PCT] == 40
assert len(events) == 2
assert events[-1].data[ATTR_VALUE] == "{}40%".format(event_value)
assert events[-1].data[ATTR_VALUE] == 'brightness at 40%'
await hass.async_add_job(acc.char_on.client_update_value, 1)
await hass.async_add_job(acc.char_brightness.client_update_value, 0)
@ -154,7 +153,7 @@ async def test_light_color_temperature(hass, hk_driver, cls, events):
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[0].data[ATTR_COLOR_TEMP] == 250
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == "color temperature at 250"
assert events[-1].data[ATTR_VALUE] == 'color temperature at 250'
async def test_light_rgb_color(hass, hk_driver, cls, events):
@ -185,4 +184,4 @@ async def test_light_rgb_color(hass, hk_driver, cls, events):
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
assert call_turn_on[0].data[ATTR_HS_COLOR] == (145, 75)
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == "set color at (145, 75)"
assert events[-1].data[ATTR_VALUE] == 'set color at (145, 75)'

View File

@ -29,32 +29,32 @@ async def test_media_player_set_state(hass, hk_driver, events):
assert acc.aid == 2
assert acc.category == 8 # Switch
assert acc.chars[FEATURE_ON_OFF].value == 0
assert acc.chars[FEATURE_PLAY_PAUSE].value == 0
assert acc.chars[FEATURE_PLAY_STOP].value == 0
assert acc.chars[FEATURE_TOGGLE_MUTE].value == 0
assert acc.chars[FEATURE_ON_OFF].value is False
assert acc.chars[FEATURE_PLAY_PAUSE].value is False
assert acc.chars[FEATURE_PLAY_STOP].value is False
assert acc.chars[FEATURE_TOGGLE_MUTE].value is False
hass.states.async_set(entity_id, STATE_ON, {ATTR_MEDIA_VOLUME_MUTED: True})
await hass.async_block_till_done()
assert acc.chars[FEATURE_ON_OFF].value == 1
assert acc.chars[FEATURE_TOGGLE_MUTE].value == 1
assert acc.chars[FEATURE_ON_OFF].value is True
assert acc.chars[FEATURE_TOGGLE_MUTE].value is True
hass.states.async_set(entity_id, STATE_OFF)
await hass.async_block_till_done()
assert acc.chars[FEATURE_ON_OFF].value == 0
assert acc.chars[FEATURE_ON_OFF].value is False
hass.states.async_set(entity_id, STATE_PLAYING)
await hass.async_block_till_done()
assert acc.chars[FEATURE_PLAY_PAUSE].value == 1
assert acc.chars[FEATURE_PLAY_STOP].value == 1
assert acc.chars[FEATURE_PLAY_PAUSE].value is True
assert acc.chars[FEATURE_PLAY_STOP].value is True
hass.states.async_set(entity_id, STATE_PAUSED)
await hass.async_block_till_done()
assert acc.chars[FEATURE_PLAY_PAUSE].value == 0
assert acc.chars[FEATURE_PLAY_PAUSE].value is False
hass.states.async_set(entity_id, STATE_IDLE)
await hass.async_block_till_done()
assert acc.chars[FEATURE_PLAY_STOP].value == 0
assert acc.chars[FEATURE_PLAY_STOP].value is False
# Set from HomeKit
call_turn_on = async_mock_service(hass, DOMAIN, 'turn_on')

View File

@ -163,7 +163,7 @@ async def test_thermostat(hass, hk_driver, cls, events):
assert call_set_temperature[0].data[ATTR_TEMPERATURE] == 19.0
assert acc.char_target_temp.value == 19.0
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == 'target 19.0°C'
assert events[-1].data[ATTR_VALUE] == '19.0°C'
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
await hass.async_block_till_done()
@ -379,7 +379,7 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events):
assert call_set_temperature[2].data[ATTR_ENTITY_ID] == entity_id
assert call_set_temperature[2].data[ATTR_TEMPERATURE] == 75.2
assert len(events) == 3
assert events[-1].data[ATTR_VALUE] == 'target 75.2°F'
assert events[-1].data[ATTR_VALUE] == '75.2°F'
async def test_thermostat_get_temperature_range(hass, hk_driver, cls):
@ -453,7 +453,7 @@ async def test_water_heater(hass, hk_driver, cls, events):
assert call_set_temperature[0].data[ATTR_TEMPERATURE] == 52.0
assert acc.char_target_temp.value == 52.0
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == 'target 52.0°C'
assert events[-1].data[ATTR_VALUE] == '52.0°C'
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 0)
await hass.async_block_till_done()
@ -499,7 +499,7 @@ async def test_water_heater_fahrenheit(hass, hk_driver, cls, events):
assert call_set_temperature[0].data[ATTR_TEMPERATURE] == 140.0
assert acc.char_target_temp.value == 60.0
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] == 'target 140.0°F'
assert events[-1].data[ATTR_VALUE] == '140.0°F'
async def test_water_heater_get_temperature_range(hass, hk_driver, cls):