Homekit style cleanup (#14556)

* Style cleanup

* Sorted imports
* Harmonized service calls

* Test improvements

* Small update
This commit is contained in:
cdce8p 2018-05-21 04:25:53 +02:00 committed by Paulus Schoutsen
parent ee7e59fe68
commit 0589379de5
24 changed files with 209 additions and 214 deletions

View File

@ -13,17 +13,18 @@ from homeassistant.components.cover import (
SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_SET_POSITION) SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_SET_POSITION)
from homeassistant.const import ( from homeassistant.const import (
ATTR_DEVICE_CLASS, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, ATTR_DEVICE_CLASS, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
CONF_IP_ADDRESS, CONF_NAME, CONF_PORT, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_IP_ADDRESS, CONF_NAME, CONF_PORT,
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE) TEMP_CELSIUS, TEMP_FAHRENHEIT)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import FILTER_SCHEMA from homeassistant.helpers.entityfilter import FILTER_SCHEMA
from homeassistant.util import get_local_ip from homeassistant.util import get_local_ip
from homeassistant.util.decorator import Registry from homeassistant.util.decorator import Registry
from .const import ( from .const import (
CONF_AUTO_START, CONF_ENTITY_CONFIG, CONF_FILTER, DEFAULT_PORT, CONF_AUTO_START, CONF_ENTITY_CONFIG, CONF_FILTER, DEFAULT_AUTO_START,
DEFAULT_AUTO_START, DOMAIN, HOMEKIT_FILE, SERVICE_HOMEKIT_START, DEFAULT_PORT, DEVICE_CLASS_CO2, DEVICE_CLASS_PM25, DOMAIN, HOMEKIT_FILE,
DEVICE_CLASS_CO2, DEVICE_CLASS_PM25) SERVICE_HOMEKIT_START)
from .util import show_setup_message, validate_entity_config from .util import show_setup_message, validate_entity_config
TYPES = Registry() TYPES = Registry()

View File

@ -84,20 +84,21 @@ class HomeAccessory(Accessory):
async_track_state_change( async_track_state_change(
self.hass, self.entity_id, self.update_state_callback) self.hass, self.entity_id, self.update_state_callback)
@ha_callback
def update_state_callback(self, entity_id=None, old_state=None, def update_state_callback(self, entity_id=None, old_state=None,
new_state=None): new_state=None):
"""Callback from state change listener.""" """Callback from state change listener."""
_LOGGER.debug('New_state: %s', new_state) _LOGGER.debug('New_state: %s', new_state)
if new_state is None: if new_state is None:
return return
self.update_state(new_state) self.hass.async_add_job(self.update_state, new_state)
def update_state(self, new_state): def update_state(self, new_state):
"""Method called on state change to update HomeKit value. """Method called on state change to update HomeKit value.
Overridden by accessory types. Overridden by accessory types.
""" """
pass raise NotImplementedError()
class HomeBridge(Bridge): class HomeBridge(Bridge):

View File

@ -1,23 +1,23 @@
"""Constants used be the HomeKit component.""" """Constants used be the HomeKit component."""
# #### MISC #### # #### Misc ####
DEBOUNCE_TIMEOUT = 0.5 DEBOUNCE_TIMEOUT = 0.5
DOMAIN = 'homekit' DOMAIN = 'homekit'
HOMEKIT_FILE = '.homekit.state' HOMEKIT_FILE = '.homekit.state'
HOMEKIT_NOTIFY_ID = 4663548 HOMEKIT_NOTIFY_ID = 4663548
# #### CONFIG #### # #### Config ####
CONF_AUTO_START = 'auto_start' CONF_AUTO_START = 'auto_start'
CONF_ENTITY_CONFIG = 'entity_config' CONF_ENTITY_CONFIG = 'entity_config'
CONF_FILTER = 'filter' CONF_FILTER = 'filter'
# #### CONFIG DEFAULTS #### # #### Config Defaults ####
DEFAULT_AUTO_START = True DEFAULT_AUTO_START = True
DEFAULT_PORT = 51827 DEFAULT_PORT = 51827
# #### HOMEKIT COMPONENT SERVICES #### # #### HomeKit Component Services ####
SERVICE_HOMEKIT_START = 'start' SERVICE_HOMEKIT_START = 'start'
# #### STRING CONSTANTS #### # #### String Constants ####
BRIDGE_MODEL = 'Bridge' BRIDGE_MODEL = 'Bridge'
BRIDGE_NAME = 'Home Assistant Bridge' BRIDGE_NAME = 'Home Assistant Bridge'
BRIDGE_SERIAL_NUMBER = 'homekit.bridge' BRIDGE_SERIAL_NUMBER = 'homekit.bridge'
@ -31,10 +31,10 @@ SERV_CARBON_MONOXIDE_SENSOR = 'CarbonMonoxideSensor'
SERV_CONTACT_SENSOR = 'ContactSensor' SERV_CONTACT_SENSOR = 'ContactSensor'
SERV_FANV2 = 'Fanv2' SERV_FANV2 = 'Fanv2'
SERV_GARAGE_DOOR_OPENER = 'GarageDoorOpener' SERV_GARAGE_DOOR_OPENER = 'GarageDoorOpener'
SERV_HUMIDITY_SENSOR = 'HumiditySensor' # CurrentRelativeHumidity SERV_HUMIDITY_SENSOR = 'HumiditySensor'
SERV_LEAK_SENSOR = 'LeakSensor' SERV_LEAK_SENSOR = 'LeakSensor'
SERV_LIGHT_SENSOR = 'LightSensor' SERV_LIGHT_SENSOR = 'LightSensor'
SERV_LIGHTBULB = 'Lightbulb' # On | Brightness, Hue, Saturation, Name SERV_LIGHTBULB = 'Lightbulb'
SERV_LOCK = 'LockMechanism' SERV_LOCK = 'LockMechanism'
SERV_MOTION_SENSOR = 'MotionSensor' SERV_MOTION_SENSOR = 'MotionSensor'
SERV_OCCUPANCY_SENSOR = 'OccupancySensor' SERV_OCCUPANCY_SENSOR = 'OccupancySensor'
@ -44,13 +44,12 @@ SERV_SWITCH = 'Switch'
SERV_TEMPERATURE_SENSOR = 'TemperatureSensor' SERV_TEMPERATURE_SENSOR = 'TemperatureSensor'
SERV_THERMOSTAT = 'Thermostat' SERV_THERMOSTAT = 'Thermostat'
SERV_WINDOW_COVERING = 'WindowCovering' SERV_WINDOW_COVERING = 'WindowCovering'
# CurrentPosition, TargetPosition, PositionState
# #### Characteristics #### # #### Characteristics ####
CHAR_ACTIVE = 'Active' CHAR_ACTIVE = 'Active'
CHAR_AIR_PARTICULATE_DENSITY = 'AirParticulateDensity' CHAR_AIR_PARTICULATE_DENSITY = 'AirParticulateDensity'
CHAR_AIR_QUALITY = 'AirQuality' CHAR_AIR_QUALITY = 'AirQuality'
CHAR_BRIGHTNESS = 'Brightness' # Int | [0, 100] CHAR_BRIGHTNESS = 'Brightness'
CHAR_CARBON_DIOXIDE_DETECTED = 'CarbonDioxideDetected' CHAR_CARBON_DIOXIDE_DETECTED = 'CarbonDioxideDetected'
CHAR_CARBON_DIOXIDE_LEVEL = 'CarbonDioxideLevel' CHAR_CARBON_DIOXIDE_LEVEL = 'CarbonDioxideLevel'
CHAR_CARBON_DIOXIDE_PEAK_LEVEL = 'CarbonDioxidePeakLevel' CHAR_CARBON_DIOXIDE_PEAK_LEVEL = 'CarbonDioxidePeakLevel'
@ -61,13 +60,13 @@ CHAR_COOLING_THRESHOLD_TEMPERATURE = 'CoolingThresholdTemperature'
CHAR_CURRENT_AMBIENT_LIGHT_LEVEL = 'CurrentAmbientLightLevel' CHAR_CURRENT_AMBIENT_LIGHT_LEVEL = 'CurrentAmbientLightLevel'
CHAR_CURRENT_DOOR_STATE = 'CurrentDoorState' CHAR_CURRENT_DOOR_STATE = 'CurrentDoorState'
CHAR_CURRENT_HEATING_COOLING = 'CurrentHeatingCoolingState' CHAR_CURRENT_HEATING_COOLING = 'CurrentHeatingCoolingState'
CHAR_CURRENT_POSITION = 'CurrentPosition' # Int | [0, 100] CHAR_CURRENT_POSITION = 'CurrentPosition'
CHAR_CURRENT_HUMIDITY = 'CurrentRelativeHumidity' # percent CHAR_CURRENT_HUMIDITY = 'CurrentRelativeHumidity'
CHAR_CURRENT_SECURITY_STATE = 'SecuritySystemCurrentState' CHAR_CURRENT_SECURITY_STATE = 'SecuritySystemCurrentState'
CHAR_CURRENT_TEMPERATURE = 'CurrentTemperature' CHAR_CURRENT_TEMPERATURE = 'CurrentTemperature'
CHAR_FIRMWARE_REVISION = 'FirmwareRevision' CHAR_FIRMWARE_REVISION = 'FirmwareRevision'
CHAR_HEATING_THRESHOLD_TEMPERATURE = 'HeatingThresholdTemperature' CHAR_HEATING_THRESHOLD_TEMPERATURE = 'HeatingThresholdTemperature'
CHAR_HUE = 'Hue' # arcdegress | [0, 360] CHAR_HUE = 'Hue'
CHAR_LEAK_DETECTED = 'LeakDetected' CHAR_LEAK_DETECTED = 'LeakDetected'
CHAR_LOCK_CURRENT_STATE = 'LockCurrentState' CHAR_LOCK_CURRENT_STATE = 'LockCurrentState'
CHAR_LOCK_TARGET_STATE = 'LockTargetState' CHAR_LOCK_TARGET_STATE = 'LockTargetState'
@ -77,16 +76,16 @@ CHAR_MODEL = 'Model'
CHAR_MOTION_DETECTED = 'MotionDetected' CHAR_MOTION_DETECTED = 'MotionDetected'
CHAR_NAME = 'Name' CHAR_NAME = 'Name'
CHAR_OCCUPANCY_DETECTED = 'OccupancyDetected' CHAR_OCCUPANCY_DETECTED = 'OccupancyDetected'
CHAR_ON = 'On' # boolean CHAR_ON = 'On'
CHAR_POSITION_STATE = 'PositionState' CHAR_POSITION_STATE = 'PositionState'
CHAR_ROTATION_DIRECTION = 'RotationDirection' CHAR_ROTATION_DIRECTION = 'RotationDirection'
CHAR_SATURATION = 'Saturation' # percent CHAR_SATURATION = 'Saturation'
CHAR_SERIAL_NUMBER = 'SerialNumber' CHAR_SERIAL_NUMBER = 'SerialNumber'
CHAR_SMOKE_DETECTED = 'SmokeDetected' CHAR_SMOKE_DETECTED = 'SmokeDetected'
CHAR_SWING_MODE = 'SwingMode' CHAR_SWING_MODE = 'SwingMode'
CHAR_TARGET_DOOR_STATE = 'TargetDoorState' CHAR_TARGET_DOOR_STATE = 'TargetDoorState'
CHAR_TARGET_HEATING_COOLING = 'TargetHeatingCoolingState' CHAR_TARGET_HEATING_COOLING = 'TargetHeatingCoolingState'
CHAR_TARGET_POSITION = 'TargetPosition' # Int | [0, 100] CHAR_TARGET_POSITION = 'TargetPosition'
CHAR_TARGET_SECURITY_STATE = 'SecuritySystemTargetState' CHAR_TARGET_SECURITY_STATE = 'SecuritySystemTargetState'
CHAR_TARGET_TEMPERATURE = 'TargetTemperature' CHAR_TARGET_TEMPERATURE = 'TargetTemperature'
CHAR_TEMP_DISPLAY_UNITS = 'TemperatureDisplayUnits' CHAR_TEMP_DISPLAY_UNITS = 'TemperatureDisplayUnits'
@ -94,21 +93,17 @@ CHAR_TEMP_DISPLAY_UNITS = 'TemperatureDisplayUnits'
# #### Properties #### # #### Properties ####
PROP_MAX_VALUE = 'maxValue' PROP_MAX_VALUE = 'maxValue'
PROP_MIN_VALUE = 'minValue' PROP_MIN_VALUE = 'minValue'
PROP_CELSIUS = {'minValue': -273, 'maxValue': 999} PROP_CELSIUS = {'minValue': -273, 'maxValue': 999}
# #### Device Class #### # #### Device Classes ####
DEVICE_CLASS_CO2 = 'co2' DEVICE_CLASS_CO2 = 'co2'
DEVICE_CLASS_DOOR = 'door' DEVICE_CLASS_DOOR = 'door'
DEVICE_CLASS_GARAGE_DOOR = 'garage_door' DEVICE_CLASS_GARAGE_DOOR = 'garage_door'
DEVICE_CLASS_GAS = 'gas' DEVICE_CLASS_GAS = 'gas'
DEVICE_CLASS_HUMIDITY = 'humidity'
DEVICE_CLASS_LIGHT = 'light'
DEVICE_CLASS_MOISTURE = 'moisture' DEVICE_CLASS_MOISTURE = 'moisture'
DEVICE_CLASS_MOTION = 'motion' DEVICE_CLASS_MOTION = 'motion'
DEVICE_CLASS_OCCUPANCY = 'occupancy' DEVICE_CLASS_OCCUPANCY = 'occupancy'
DEVICE_CLASS_OPENING = 'opening' DEVICE_CLASS_OPENING = 'opening'
DEVICE_CLASS_PM25 = 'pm25' DEVICE_CLASS_PM25 = 'pm25'
DEVICE_CLASS_SMOKE = 'smoke' DEVICE_CLASS_SMOKE = 'smoke'
DEVICE_CLASS_TEMPERATURE = 'temperature'
DEVICE_CLASS_WINDOW = 'window' DEVICE_CLASS_WINDOW = 'window'

View File

@ -1,21 +1,21 @@
"""Class to hold all cover accessories.""" """Class to hold all cover accessories."""
import logging import logging
from pyhap.const import CATEGORY_WINDOW_COVERING, CATEGORY_GARAGE_DOOR_OPENER from pyhap.const import CATEGORY_GARAGE_DOOR_OPENER, CATEGORY_WINDOW_COVERING
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN, SUPPORT_STOP) ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN, SUPPORT_STOP)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, SERVICE_SET_COVER_POSITION, STATE_OPEN, STATE_CLOSED, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, SERVICE_CLOSE_COVER,
SERVICE_OPEN_COVER, SERVICE_CLOSE_COVER, SERVICE_STOP_COVER, SERVICE_OPEN_COVER, SERVICE_SET_COVER_POSITION, SERVICE_STOP_COVER,
ATTR_SUPPORTED_FEATURES) STATE_CLOSED, STATE_OPEN)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory, debounce from .accessories import debounce, HomeAccessory
from .const import ( from .const import (
SERV_WINDOW_COVERING, CHAR_CURRENT_POSITION, CHAR_CURRENT_DOOR_STATE, CHAR_CURRENT_POSITION, CHAR_POSITION_STATE,
CHAR_TARGET_POSITION, CHAR_POSITION_STATE, CHAR_TARGET_DOOR_STATE, CHAR_TARGET_POSITION,
SERV_GARAGE_DOOR_OPENER, CHAR_CURRENT_DOOR_STATE, CHAR_TARGET_DOOR_STATE) SERV_GARAGE_DOOR_OPENER, SERV_WINDOW_COVERING)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -44,12 +44,13 @@ class GarageDoorOpener(HomeAccessory):
_LOGGER.debug('%s: Set state to %d', self.entity_id, value) _LOGGER.debug('%s: Set state to %d', self.entity_id, value)
self.flag_target_state = True self.flag_target_state = True
params = {ATTR_ENTITY_ID: self.entity_id}
if value == 0: if value == 0:
self.char_current_state.set_value(3) self.char_current_state.set_value(3)
self.hass.components.cover.open_cover(self.entity_id) self.hass.services.call(DOMAIN, SERVICE_OPEN_COVER, params)
elif value == 1: elif value == 1:
self.char_current_state.set_value(2) self.char_current_state.set_value(2)
self.hass.components.cover.close_cover(self.entity_id) self.hass.services.call(DOMAIN, SERVICE_CLOSE_COVER, params)
def update_state(self, new_state): def update_state(self, new_state):
"""Update cover state after state changed.""" """Update cover state after state changed."""
@ -141,8 +142,8 @@ class WindowCoveringBasic(HomeAccessory):
else: else:
service, position = (SERVICE_CLOSE_COVER, 0) service, position = (SERVICE_CLOSE_COVER, 0)
self.hass.services.call(DOMAIN, service, params = {ATTR_ENTITY_ID: self.entity_id}
{ATTR_ENTITY_ID: self.entity_id}) self.hass.services.call(DOMAIN, service, params)
# Snap the current/target position to the expected final position. # Snap the current/target position to the expected final position.
self.char_current_position.set_value(position) self.char_current_position.set_value(position)

View File

@ -4,12 +4,12 @@ import logging
from pyhap.const import CATEGORY_FAN from pyhap.const import CATEGORY_FAN
from homeassistant.components.fan import ( from homeassistant.components.fan import (
ATTR_DIRECTION, ATTR_OSCILLATING, ATTR_DIRECTION, ATTR_OSCILLATING, DIRECTION_FORWARD, DIRECTION_REVERSE,
DIRECTION_FORWARD, DIRECTION_REVERSE, DOMAIN, SERVICE_OSCILLATE, DOMAIN, SERVICE_OSCILLATE, SERVICE_SET_DIRECTION, SUPPORT_DIRECTION,
SERVICE_SET_DIRECTION, SUPPORT_DIRECTION, SUPPORT_OSCILLATE) SUPPORT_OSCILLATE)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, STATE_OFF, STATE_ON, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, SERVICE_TURN_OFF,
SERVICE_TURN_OFF, SERVICE_TURN_ON) SERVICE_TURN_ON, STATE_OFF, STATE_ON)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory from .accessories import HomeAccessory
@ -71,8 +71,7 @@ class Fan(HomeAccessory):
_LOGGER.debug('%s: Set direction to %d', self.entity_id, value) _LOGGER.debug('%s: Set direction to %d', self.entity_id, value)
self._flag[CHAR_ROTATION_DIRECTION] = True self._flag[CHAR_ROTATION_DIRECTION] = True
direction = DIRECTION_REVERSE if value == 1 else DIRECTION_FORWARD direction = DIRECTION_REVERSE if value == 1 else DIRECTION_FORWARD
params = {ATTR_ENTITY_ID: self.entity_id, params = {ATTR_ENTITY_ID: self.entity_id, ATTR_DIRECTION: direction}
ATTR_DIRECTION: direction}
self.hass.services.call(DOMAIN, SERVICE_SET_DIRECTION, params) self.hass.services.call(DOMAIN, SERVICE_SET_DIRECTION, params)
def set_oscillating(self, value): def set_oscillating(self, value):

View File

@ -4,16 +4,18 @@ import logging
from pyhap.const import CATEGORY_LIGHTBULB from pyhap.const import CATEGORY_LIGHTBULB
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_HS_COLOR, ATTR_COLOR_TEMP, ATTR_BRIGHTNESS, ATTR_MIN_MIREDS, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_TEMP, ATTR_HS_COLOR,
ATTR_MAX_MIREDS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_BRIGHTNESS) ATTR_MAX_MIREDS, ATTR_MIN_MIREDS, DOMAIN,
from homeassistant.const import ATTR_SUPPORTED_FEATURES, STATE_ON, STATE_OFF SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP)
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, SERVICE_TURN_ON,
SERVICE_TURN_OFF, STATE_OFF, STATE_ON)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory, debounce from .accessories import debounce, HomeAccessory
from .const import ( from .const import (
SERV_LIGHTBULB, CHAR_COLOR_TEMPERATURE, CHAR_BRIGHTNESS, CHAR_COLOR_TEMPERATURE, CHAR_HUE, CHAR_ON,
CHAR_BRIGHTNESS, CHAR_HUE, CHAR_ON, CHAR_SATURATION, CHAR_SATURATION, SERV_LIGHTBULB, PROP_MAX_VALUE, PROP_MIN_VALUE)
PROP_MAX_VALUE, PROP_MIN_VALUE)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -79,28 +81,27 @@ class Light(HomeAccessory):
_LOGGER.debug('%s: Set state to %d', self.entity_id, value) _LOGGER.debug('%s: Set state to %d', self.entity_id, value)
self._flag[CHAR_ON] = True self._flag[CHAR_ON] = True
params = {ATTR_ENTITY_ID: self.entity_id}
if value == 1: service = SERVICE_TURN_ON if value == 1 else SERVICE_TURN_OFF
self.hass.components.light.turn_on(self.entity_id) self.hass.services.call(DOMAIN, service, params)
elif value == 0:
self.hass.components.light.turn_off(self.entity_id)
@debounce @debounce
def set_brightness(self, value): def set_brightness(self, value):
"""Set brightness if call came from HomeKit.""" """Set brightness if call came from HomeKit."""
_LOGGER.debug('%s: Set brightness to %d', self.entity_id, value) _LOGGER.debug('%s: Set brightness to %d', self.entity_id, value)
self._flag[CHAR_BRIGHTNESS] = True self._flag[CHAR_BRIGHTNESS] = True
if value != 0: if value == 0:
self.hass.components.light.turn_on( self.set_state(0) # Turn off light
self.entity_id, brightness_pct=value) return
else: params = {ATTR_ENTITY_ID: self.entity_id, ATTR_BRIGHTNESS_PCT: value}
self.hass.components.light.turn_off(self.entity_id) self.hass.services.call(DOMAIN, SERVICE_TURN_ON, params)
def set_color_temperature(self, value): def set_color_temperature(self, value):
"""Set color temperature if call came from HomeKit.""" """Set color temperature if call came from HomeKit."""
_LOGGER.debug('%s: Set color temp to %s', self.entity_id, value) _LOGGER.debug('%s: Set color temp to %s', self.entity_id, value)
self._flag[CHAR_COLOR_TEMPERATURE] = True self._flag[CHAR_COLOR_TEMPERATURE] = True
self.hass.components.light.turn_on(self.entity_id, color_temp=value) params = {ATTR_ENTITY_ID: self.entity_id, ATTR_COLOR_TEMP: value}
self.hass.services.call(DOMAIN, SERVICE_TURN_ON, params)
def set_saturation(self, value): def set_saturation(self, value):
"""Set saturation if call came from HomeKit.""" """Set saturation if call came from HomeKit."""
@ -118,15 +119,14 @@ class Light(HomeAccessory):
def set_color(self): def set_color(self):
"""Set color if call came from HomeKit.""" """Set color if call came from HomeKit."""
# Handle Color
if self._features & SUPPORT_COLOR and self._flag[CHAR_HUE] and \ if self._features & SUPPORT_COLOR and self._flag[CHAR_HUE] and \
self._flag[CHAR_SATURATION]: self._flag[CHAR_SATURATION]:
color = (self._hue, self._saturation) color = (self._hue, self._saturation)
_LOGGER.debug('%s: Set hs_color to %s', self.entity_id, color) _LOGGER.debug('%s: Set hs_color to %s', self.entity_id, color)
self._flag.update({ self._flag.update({
CHAR_HUE: False, CHAR_SATURATION: False, RGB_COLOR: True}) CHAR_HUE: False, CHAR_SATURATION: False, RGB_COLOR: True})
self.hass.components.light.turn_on( params = {ATTR_ENTITY_ID: self.entity_id, ATTR_HS_COLOR: color}
self.entity_id, hs_color=color) self.hass.services.call(DOMAIN, SERVICE_TURN_ON, params)
def update_state(self, new_state): def update_state(self, new_state):
"""Update light after state change.""" """Update light after state change."""

View File

@ -4,13 +4,12 @@ import logging
from pyhap.const import CATEGORY_DOOR_LOCK from pyhap.const import CATEGORY_DOOR_LOCK
from homeassistant.components.lock import ( from homeassistant.components.lock import (
ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN) ATTR_ENTITY_ID, DOMAIN, STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN)
from homeassistant.const import ATTR_CODE from homeassistant.const import ATTR_CODE
from . import TYPES from . import TYPES
from .accessories import HomeAccessory from .accessories import HomeAccessory
from .const import ( from .const import CHAR_LOCK_CURRENT_STATE, CHAR_LOCK_TARGET_STATE, SERV_LOCK
SERV_LOCK, CHAR_LOCK_CURRENT_STATE, CHAR_LOCK_TARGET_STATE)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -55,7 +54,7 @@ class Lock(HomeAccessory):
params = {ATTR_ENTITY_ID: self.entity_id} params = {ATTR_ENTITY_ID: self.entity_id}
if self._code: if self._code:
params[ATTR_CODE] = self._code params[ATTR_CODE] = self._code
self.hass.services.call('lock', service, params) self.hass.services.call(DOMAIN, service, params)
def update_state(self, new_state): def update_state(self, new_state):
"""Update lock after state changed.""" """Update lock after state changed."""

View File

@ -3,16 +3,16 @@ import logging
from pyhap.const import CATEGORY_ALARM_SYSTEM from pyhap.const import CATEGORY_ALARM_SYSTEM
from homeassistant.components.alarm_control_panel import DOMAIN
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, ATTR_ENTITY_ID, ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_TRIGGERED, STATE_ALARM_DISARMED)
STATE_ALARM_TRIGGERED, ATTR_ENTITY_ID, ATTR_CODE)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory from .accessories import HomeAccessory
from .const import ( from .const import (
SERV_SECURITY_SYSTEM, CHAR_CURRENT_SECURITY_STATE, CHAR_CURRENT_SECURITY_STATE, CHAR_TARGET_SECURITY_STATE,
CHAR_TARGET_SECURITY_STATE) SERV_SECURITY_SYSTEM)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -56,7 +56,7 @@ class SecuritySystem(HomeAccessory):
params = {ATTR_ENTITY_ID: self.entity_id} params = {ATTR_ENTITY_ID: self.entity_id}
if self._alarm_code: if self._alarm_code:
params[ATTR_CODE] = self._alarm_code params[ATTR_CODE] = self._alarm_code
self.hass.services.call('alarm_control_panel', service, params) self.hass.services.call(DOMAIN, service, params)
def update_state(self, new_state): def update_state(self, new_state):
"""Update security state after state changed.""" """Update security state after state changed."""

View File

@ -4,26 +4,26 @@ import logging
from pyhap.const import CATEGORY_SENSOR from pyhap.const import CATEGORY_SENSOR
from homeassistant.const import ( from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, ATTR_DEVICE_CLASS, ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_HOME,
ATTR_DEVICE_CLASS, STATE_ON, STATE_HOME) TEMP_CELSIUS)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory from .accessories import HomeAccessory
from .const import ( from .const import (
SERV_HUMIDITY_SENSOR, SERV_TEMPERATURE_SENSOR, CHAR_AIR_PARTICULATE_DENSITY, CHAR_AIR_QUALITY,
CHAR_CURRENT_HUMIDITY, CHAR_CURRENT_TEMPERATURE, PROP_CELSIUS, CHAR_CARBON_DIOXIDE_DETECTED, CHAR_CARBON_DIOXIDE_LEVEL,
SERV_AIR_QUALITY_SENSOR, CHAR_AIR_QUALITY, CHAR_AIR_PARTICULATE_DENSITY, CHAR_CARBON_DIOXIDE_PEAK_LEVEL, CHAR_CARBON_MONOXIDE_DETECTED,
CHAR_CARBON_DIOXIDE_LEVEL, CHAR_CARBON_DIOXIDE_PEAK_LEVEL, CHAR_CONTACT_SENSOR_STATE, CHAR_CURRENT_AMBIENT_LIGHT_LEVEL,
SERV_LIGHT_SENSOR, CHAR_CURRENT_AMBIENT_LIGHT_LEVEL, CHAR_CURRENT_HUMIDITY, CHAR_CURRENT_TEMPERATURE, CHAR_LEAK_DETECTED,
DEVICE_CLASS_CO2, SERV_CARBON_DIOXIDE_SENSOR, CHAR_CARBON_DIOXIDE_DETECTED, CHAR_MOTION_DETECTED, CHAR_OCCUPANCY_DETECTED, CHAR_SMOKE_DETECTED,
DEVICE_CLASS_GAS, SERV_CARBON_MONOXIDE_SENSOR, DEVICE_CLASS_CO2, DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE_DOOR,
CHAR_CARBON_MONOXIDE_DETECTED, DEVICE_CLASS_GAS, DEVICE_CLASS_MOISTURE, DEVICE_CLASS_MOTION,
DEVICE_CLASS_MOISTURE, SERV_LEAK_SENSOR, CHAR_LEAK_DETECTED, DEVICE_CLASS_OCCUPANCY, DEVICE_CLASS_OPENING, DEVICE_CLASS_SMOKE,
DEVICE_CLASS_MOTION, SERV_MOTION_SENSOR, CHAR_MOTION_DETECTED, DEVICE_CLASS_WINDOW, PROP_CELSIUS, SERV_AIR_QUALITY_SENSOR,
DEVICE_CLASS_OCCUPANCY, SERV_OCCUPANCY_SENSOR, CHAR_OCCUPANCY_DETECTED, SERV_CARBON_DIOXIDE_SENSOR, SERV_CARBON_MONOXIDE_SENSOR,
DEVICE_CLASS_OPENING, SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, SERV_CONTACT_SENSOR, SERV_HUMIDITY_SENSOR, SERV_LEAK_SENSOR,
DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE_DOOR, DEVICE_CLASS_WINDOW, SERV_LIGHT_SENSOR, SERV_MOTION_SENSOR, SERV_OCCUPANCY_SENSOR,
DEVICE_CLASS_SMOKE, SERV_SMOKE_SENSOR, CHAR_SMOKE_DETECTED) SERV_SMOKE_SENSOR, SERV_TEMPERATURE_SENSOR)
from .util import ( from .util import (
convert_to_float, temperature_to_homekit, density_to_air_quality) convert_to_float, temperature_to_homekit, density_to_air_quality)
@ -108,7 +108,7 @@ class AirQualitySensor(HomeAccessory):
def update_state(self, new_state): def update_state(self, new_state):
"""Update accessory after state change.""" """Update accessory after state change."""
density = convert_to_float(new_state.state) density = convert_to_float(new_state.state)
if density is not None: if density:
self.char_density.set_value(density) self.char_density.set_value(density)
self.char_quality.set_value(density_to_air_quality(density)) self.char_quality.set_value(density_to_air_quality(density))
_LOGGER.debug('%s: Set to %d', self.entity_id, density) _LOGGER.debug('%s: Set to %d', self.entity_id, density)
@ -134,7 +134,7 @@ class CarbonDioxideSensor(HomeAccessory):
def update_state(self, new_state): def update_state(self, new_state):
"""Update accessory after state change.""" """Update accessory after state change."""
co2 = convert_to_float(new_state.state) co2 = convert_to_float(new_state.state)
if co2 is not None: if co2:
self.char_co2.set_value(co2) self.char_co2.set_value(co2)
if co2 > self.char_peak.value: if co2 > self.char_peak.value:
self.char_peak.set_value(co2) self.char_peak.set_value(co2)
@ -157,7 +157,7 @@ class LightSensor(HomeAccessory):
def update_state(self, new_state): def update_state(self, new_state):
"""Update accessory after state change.""" """Update accessory after state change."""
luminance = convert_to_float(new_state.state) luminance = convert_to_float(new_state.state)
if luminance is not None: if luminance:
self.char_light.set_value(luminance) self.char_light.set_value(luminance)
_LOGGER.debug('%s: Set to %d', self.entity_id, luminance) _LOGGER.debug('%s: Set to %d', self.entity_id, luminance)

View File

@ -33,9 +33,9 @@ class Switch(HomeAccessory):
_LOGGER.debug('%s: Set switch state to %s', _LOGGER.debug('%s: Set switch state to %s',
self.entity_id, value) self.entity_id, value)
self.flag_target_state = True self.flag_target_state = True
params = {ATTR_ENTITY_ID: self.entity_id}
service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF service = SERVICE_TURN_ON if value else SERVICE_TURN_OFF
self.hass.services.call(self._domain, service, self.hass.services.call(self._domain, service, params)
{ATTR_ENTITY_ID: self.entity_id})
def update_state(self, new_state): def update_state(self, new_state):
"""Update switch state after state changed.""" """Update switch state after state changed."""

View File

@ -4,22 +4,23 @@ import logging
from pyhap.const import CATEGORY_THERMOSTAT from pyhap.const import CATEGORY_THERMOSTAT
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE, ATTR_CURRENT_TEMPERATURE, ATTR_OPERATION_LIST, ATTR_OPERATION_MODE,
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, ATTR_TEMPERATURE, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
ATTR_OPERATION_MODE, ATTR_OPERATION_LIST, DOMAIN, SERVICE_SET_TEMPERATURE, SERVICE_SET_OPERATION_MODE, STATE_AUTO,
STATE_HEAT, STATE_COOL, STATE_AUTO, SUPPORT_ON_OFF, STATE_COOL, STATE_HEAT, SUPPORT_ON_OFF, SUPPORT_TARGET_TEMPERATURE_HIGH,
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW) SUPPORT_TARGET_TEMPERATURE_LOW)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT) SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_OFF,
TEMP_CELSIUS, TEMP_FAHRENHEIT)
from . import TYPES from . import TYPES
from .accessories import HomeAccessory, debounce from .accessories import debounce, HomeAccessory
from .const import ( from .const import (
SERV_THERMOSTAT, CHAR_CURRENT_HEATING_COOLING, CHAR_COOLING_THRESHOLD_TEMPERATURE, CHAR_CURRENT_HEATING_COOLING,
CHAR_TARGET_HEATING_COOLING, CHAR_CURRENT_TEMPERATURE, CHAR_CURRENT_TEMPERATURE, CHAR_TARGET_HEATING_COOLING,
CHAR_TARGET_TEMPERATURE, CHAR_TEMP_DISPLAY_UNITS, CHAR_HEATING_THRESHOLD_TEMPERATURE, CHAR_TARGET_TEMPERATURE,
CHAR_COOLING_THRESHOLD_TEMPERATURE, CHAR_HEATING_THRESHOLD_TEMPERATURE) CHAR_TEMP_DISPLAY_UNITS, SERV_THERMOSTAT)
from .util import temperature_to_homekit, temperature_to_states from .util import temperature_to_homekit, temperature_to_states
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -99,12 +100,13 @@ class Thermostat(HomeAccessory):
if self.support_power_state is True: if self.support_power_state is True:
params = {ATTR_ENTITY_ID: self.entity_id} params = {ATTR_ENTITY_ID: self.entity_id}
if hass_value == STATE_OFF: if hass_value == STATE_OFF:
self.hass.services.call('climate', 'turn_off', params) self.hass.services.call(DOMAIN, SERVICE_TURN_OFF, params)
return return
else: else:
self.hass.services.call('climate', 'turn_on', params) self.hass.services.call(DOMAIN, SERVICE_TURN_ON, params)
self.hass.components.climate.set_operation_mode( params = {ATTR_ENTITY_ID: self.entity_id,
operation_mode=hass_value, entity_id=self.entity_id) ATTR_OPERATION_MODE: hass_value}
self.hass.services.call(DOMAIN, SERVICE_SET_OPERATION_MODE, params)
@debounce @debounce
def set_cooling_threshold(self, value): def set_cooling_threshold(self, value):
@ -113,11 +115,11 @@ class Thermostat(HomeAccessory):
self.entity_id, value) self.entity_id, value)
self.coolingthresh_flag_target_state = True self.coolingthresh_flag_target_state = True
low = self.char_heating_thresh_temp.value low = self.char_heating_thresh_temp.value
low = temperature_to_states(low, self._unit) params = {
value = temperature_to_states(value, self._unit) ATTR_ENTITY_ID: self.entity_id,
self.hass.components.climate.set_temperature( ATTR_TARGET_TEMP_HIGH: temperature_to_states(value, self._unit),
entity_id=self.entity_id, target_temp_high=value, ATTR_TARGET_TEMP_LOW: temperature_to_states(low, self._unit)}
target_temp_low=low) self.hass.services.call(DOMAIN, SERVICE_SET_TEMPERATURE, params)
@debounce @debounce
def set_heating_threshold(self, value): def set_heating_threshold(self, value):
@ -125,13 +127,12 @@ class Thermostat(HomeAccessory):
_LOGGER.debug('%s: Set heating threshold temperature to %.2f°C', _LOGGER.debug('%s: Set heating threshold temperature to %.2f°C',
self.entity_id, value) self.entity_id, value)
self.heatingthresh_flag_target_state = True self.heatingthresh_flag_target_state = True
# Home assistant always wants to set low and high at the same time
high = self.char_cooling_thresh_temp.value high = self.char_cooling_thresh_temp.value
high = temperature_to_states(high, self._unit) params = {
value = temperature_to_states(value, self._unit) ATTR_ENTITY_ID: self.entity_id,
self.hass.components.climate.set_temperature( ATTR_TARGET_TEMP_HIGH: temperature_to_states(high, self._unit),
entity_id=self.entity_id, target_temp_high=high, ATTR_TARGET_TEMP_LOW: temperature_to_states(value, self._unit)}
target_temp_low=value) self.hass.services.call(DOMAIN, SERVICE_SET_TEMPERATURE, params)
@debounce @debounce
def set_target_temperature(self, value): def set_target_temperature(self, value):
@ -139,9 +140,10 @@ class Thermostat(HomeAccessory):
_LOGGER.debug('%s: Set target temperature to %.2f°C', _LOGGER.debug('%s: Set target temperature to %.2f°C',
self.entity_id, value) self.entity_id, value)
self.temperature_flag_target_state = True self.temperature_flag_target_state = True
value = temperature_to_states(value, self._unit) params = {
self.hass.components.climate.set_temperature( ATTR_ENTITY_ID: self.entity_id,
temperature=value, entity_id=self.entity_id) ATTR_TEMPERATURE: temperature_to_states(value, self._unit)}
self.hass.services.call(DOMAIN, SERVICE_SET_TEMPERATURE, params)
def update_state(self, new_state): def update_state(self, new_state):
"""Update security state after state changed.""" """Update security state after state changed."""

View File

@ -0,0 +1,8 @@
"""Collection of fixtures and functions for the HomeKit tests."""
from unittest.mock import patch
def patch_debounce():
"""Return patch for debounce method."""
return patch('homeassistant.components.homekit.accessories.debounce',
lambda f: lambda *args, **kwargs: f(*args, **kwargs))

View File

@ -5,22 +5,18 @@ This includes tests for all mock object types.
from datetime import datetime, timedelta from datetime import datetime, timedelta
from unittest.mock import patch, Mock from unittest.mock import patch, Mock
import pytest
from homeassistant.components.homekit.accessories import ( from homeassistant.components.homekit.accessories import (
debounce, HomeAccessory, HomeBridge, HomeDriver) debounce, HomeAccessory, HomeBridge, HomeDriver)
from homeassistant.components.homekit.const import ( from homeassistant.components.homekit.const import (
BRIDGE_MODEL, BRIDGE_NAME, BRIDGE_SERIAL_NUMBER, SERV_ACCESSORY_INFO, BRIDGE_MODEL, BRIDGE_NAME, BRIDGE_SERIAL_NUMBER, CHAR_FIRMWARE_REVISION,
CHAR_FIRMWARE_REVISION, CHAR_MANUFACTURER, CHAR_MODEL, CHAR_NAME, CHAR_MANUFACTURER, CHAR_MODEL, CHAR_NAME, CHAR_SERIAL_NUMBER,
CHAR_SERIAL_NUMBER, MANUFACTURER) MANUFACTURER, SERV_ACCESSORY_INFO)
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
def patch_debounce():
"""Return patch for debounce method."""
return patch('homeassistant.components.homekit.accessories.debounce',
lambda f: lambda *args, **kwargs: f(*args, **kwargs))
async def test_debounce(hass): async def test_debounce(hass):
"""Test add_timeout decorator function.""" """Test add_timeout decorator function."""
def demo_func(*args): def demo_func(*args):
@ -74,20 +70,23 @@ async def test_home_accessory(hass):
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \ assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
'homekit.accessory' 'homekit.accessory'
hass.states.async_set('homekit.accessory', 'on') hass.states.async_set(entity_id, 'on')
await hass.async_block_till_done()
await hass.async_add_job(acc.run)
hass.states.async_set('homekit.accessory', 'off')
await hass.async_block_till_done() await hass.async_block_till_done()
with patch('homeassistant.components.homekit.accessories.'
'HomeAccessory.update_state') as mock_update_state:
await hass.async_add_job(acc.run)
state = hass.states.get(entity_id)
mock_update_state.assert_called_with(state)
entity_id = 'test_model.demo' hass.states.async_remove(entity_id)
hass.states.async_set(entity_id, None) await hass.async_block_till_done()
await hass.async_block_till_done() assert mock_update_state.call_count == 1
acc = HomeAccessory('hass', 'test_name', entity_id, 2, None) with pytest.raises(NotImplementedError):
assert acc.display_name == 'test_name' acc.update_state('new_state')
assert acc.aid == 2
assert len(acc.services) == 1 # Test model name from domain
acc = HomeAccessory('hass', 'test_name', 'test_model.demo', 2, None)
serv = acc.services[0] # SERV_ACCESSORY_INFO serv = acc.services[0] # SERV_ACCESSORY_INFO
assert serv.get_characteristic(CHAR_MODEL).value == 'Test Model' assert serv.get_characteristic(CHAR_MODEL).value == 'Test Model'

View File

@ -4,13 +4,13 @@ from unittest.mock import patch, Mock
import pytest import pytest
from homeassistant.core import State from homeassistant.core import State
from homeassistant.components.cover import SUPPORT_OPEN, SUPPORT_CLOSE from homeassistant.components.cover import SUPPORT_CLOSE, SUPPORT_OPEN
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_DEVICE_CLASS, ATTR_SUPPORTED_FEATURES, ATTR_CODE, ATTR_DEVICE_CLASS, ATTR_SUPPORTED_FEATURES,
ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_NAME) ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, TEMP_CELSIUS, TEMP_FAHRENHEIT)
def test_not_supported(caplog): def test_not_supported(caplog):
@ -40,14 +40,12 @@ def test_customize_options(config, name):
('Fan', 'fan.test', 'on', {}, {}), ('Fan', 'fan.test', 'on', {}, {}),
('Light', 'light.test', 'on', {}, {}), ('Light', 'light.test', 'on', {}, {}),
('Lock', 'lock.test', 'locked', {}, {ATTR_CODE: '1234'}), ('Lock', 'lock.test', 'locked', {}, {ATTR_CODE: '1234'}),
('SecuritySystem', 'alarm_control_panel.test', 'armed', {},
{ATTR_CODE: '1234'}),
('Thermostat', 'climate.test', 'auto', {}, {}), ('Thermostat', 'climate.test', 'auto', {}, {}),
('Thermostat', 'climate.test', 'auto', ('Thermostat', 'climate.test', 'auto',
{ATTR_SUPPORTED_FEATURES: SUPPORT_TARGET_TEMPERATURE_LOW | {ATTR_SUPPORTED_FEATURES: SUPPORT_TARGET_TEMPERATURE_LOW |
SUPPORT_TARGET_TEMPERATURE_HIGH}, {}), SUPPORT_TARGET_TEMPERATURE_HIGH}, {}),
('SecuritySystem', 'alarm_control_panel.test', 'armed', {},
{ATTR_CODE: '1234'}),
]) ])
def test_types(type_name, entity_id, state, attrs, config): def test_types(type_name, entity_id, state, attrs, config):
"""Test if types are associated correctly.""" """Test if types are associated correctly."""
@ -83,22 +81,17 @@ def test_type_covers(type_name, entity_id, state, attrs):
('BinarySensor', 'binary_sensor.opening', 'on', ('BinarySensor', 'binary_sensor.opening', 'on',
{ATTR_DEVICE_CLASS: 'opening'}), {ATTR_DEVICE_CLASS: 'opening'}),
('BinarySensor', 'device_tracker.someone', 'not_home', {}), ('BinarySensor', 'device_tracker.someone', 'not_home', {}),
('AirQualitySensor', 'sensor.air_quality_pm25', '40', {}), ('AirQualitySensor', 'sensor.air_quality_pm25', '40', {}),
('AirQualitySensor', 'sensor.air_quality', '40', ('AirQualitySensor', 'sensor.air_quality', '40',
{ATTR_DEVICE_CLASS: 'pm25'}), {ATTR_DEVICE_CLASS: 'pm25'}),
('CarbonDioxideSensor', 'sensor.airmeter_co2', '500', {}), ('CarbonDioxideSensor', 'sensor.airmeter_co2', '500', {}),
('CarbonDioxideSensor', 'sensor.airmeter', '500', ('CarbonDioxideSensor', 'sensor.airmeter', '500',
{ATTR_DEVICE_CLASS: 'co2'}), {ATTR_DEVICE_CLASS: 'co2'}),
('HumiditySensor', 'sensor.humidity', '20', ('HumiditySensor', 'sensor.humidity', '20',
{ATTR_DEVICE_CLASS: 'humidity', ATTR_UNIT_OF_MEASUREMENT: '%'}), {ATTR_DEVICE_CLASS: 'humidity', ATTR_UNIT_OF_MEASUREMENT: '%'}),
('LightSensor', 'sensor.light', '900', {ATTR_DEVICE_CLASS: 'illuminance'}), ('LightSensor', 'sensor.light', '900', {ATTR_DEVICE_CLASS: 'illuminance'}),
('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lm'}), ('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lm'}),
('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lx'}), ('LightSensor', 'sensor.light', '900', {ATTR_UNIT_OF_MEASUREMENT: 'lx'}),
('TemperatureSensor', 'sensor.temperature', '23', ('TemperatureSensor', 'sensor.temperature', '23',
{ATTR_DEVICE_CLASS: 'temperature'}), {ATTR_DEVICE_CLASS: 'temperature'}),
('TemperatureSensor', 'sensor.temperature', '23', ('TemperatureSensor', 'sensor.temperature', '23',

View File

@ -6,29 +6,28 @@ import pytest
from homeassistant import setup from homeassistant import setup
from homeassistant.core import State from homeassistant.core import State
from homeassistant.components.homekit import ( from homeassistant.components.homekit import (
HomeKit, generate_aid, generate_aid, HomeKit, STATUS_READY, STATUS_RUNNING,
STATUS_READY, STATUS_RUNNING, STATUS_STOPPED, STATUS_WAIT) STATUS_STOPPED, STATUS_WAIT)
from homeassistant.components.homekit.accessories import HomeBridge from homeassistant.components.homekit.accessories import HomeBridge
from homeassistant.components.homekit.const import ( from homeassistant.components.homekit.const import (
DOMAIN, HOMEKIT_FILE, CONF_AUTO_START, CONF_AUTO_START, DEFAULT_PORT, DOMAIN, HOMEKIT_FILE, SERVICE_HOMEKIT_START)
DEFAULT_PORT, SERVICE_HOMEKIT_START)
from homeassistant.helpers.entityfilter import generate_filter from homeassistant.helpers.entityfilter import generate_filter
from homeassistant.const import ( 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.components.homekit.test_accessories import patch_debounce from tests.components.homekit.common 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'
@pytest.fixture('module') @pytest.fixture(scope='module')
def debounce_patcher(request): def debounce_patcher():
"""Patch debounce method.""" """Patch debounce method."""
patcher = patch_debounce() patcher = patch_debounce()
patcher.start() yield patcher.start()
request.addfinalizer(patcher.stop) patcher.stop()
def test_generate_aid(): def test_generate_aid():
@ -124,27 +123,25 @@ async def test_homekit_setup_ip_address(hass):
hass, ANY, port=DEFAULT_PORT, address='172.0.0.0', persist_file=ANY) hass, ANY, port=DEFAULT_PORT, address='172.0.0.0', persist_file=ANY)
async def test_homekit_add_accessory(hass): async def test_homekit_add_accessory():
"""Add accessory if config exists and get_acc returns an accessory.""" """Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit(hass, None, None, lambda entity_id: True, {}) homekit = HomeKit('hass', None, None, lambda entity_id: True, {})
homekit.bridge = HomeBridge(hass) homekit.bridge = mock_bridge = Mock()
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \ with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
as mock_add_acc, \
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.side_effect = [None, 'acc', None] mock_get_acc.side_effect = [None, 'acc', None]
homekit.add_bridge_accessory(State('light.demo', 'on')) homekit.add_bridge_accessory(State('light.demo', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 363398124, {}) mock_get_acc.assert_called_with('hass', ANY, 363398124, {})
assert mock_add_acc.called is False assert not mock_bridge.add_accessory.called
homekit.add_bridge_accessory(State('demo.test', 'on')) homekit.add_bridge_accessory(State('demo.test', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 294192020, {}) mock_get_acc.assert_called_with('hass', ANY, 294192020, {})
assert mock_add_acc.called is True assert mock_bridge.add_accessory.called
homekit.add_bridge_accessory(State('demo.test_2', 'on')) homekit.add_bridge_accessory(State('demo.test_2', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 429982757, {}) mock_get_acc.assert_called_with('hass', ANY, 429982757, {})
mock_add_acc.assert_called_with('acc') mock_bridge.add_accessory.assert_called_with('acc')
async def test_homekit_entity_filter(hass): async def test_homekit_entity_filter(hass):
@ -171,8 +168,8 @@ async def test_homekit_start(hass, debounce_patcher):
"""Test HomeKit start method.""" """Test HomeKit start method."""
pin = b'123-45-678' pin = b'123-45-678'
homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}}) homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}})
homekit.bridge = HomeBridge(hass) homekit.bridge = Mock()
homekit.driver = Mock(state=Mock(paired=False, pincode=pin)) homekit.driver = mock_driver = Mock(state=Mock(paired=False, pincode=pin))
hass.states.async_set('light.demo', 'on') hass.states.async_set('light.demo', 'on')
state = hass.states.async_all()[0] state = hass.states.async_all()[0]
@ -184,13 +181,13 @@ async def test_homekit_start(hass, debounce_patcher):
mock_add_acc.assert_called_with(state) mock_add_acc.assert_called_with(state)
mock_setup_msg.assert_called_with(hass, pin) mock_setup_msg.assert_called_with(hass, pin)
assert homekit.driver.start.called is True assert mock_driver.start.called is True
assert homekit.status == STATUS_RUNNING assert homekit.status == STATUS_RUNNING
# Test start() if already started # Test start() if already started
homekit.driver.reset_mock() mock_driver.reset_mock()
await hass.async_add_job(homekit.start) await hass.async_add_job(homekit.start)
assert homekit.driver.start.called is False assert mock_driver.start.called is False
async def test_homekit_stop(hass): async def test_homekit_stop(hass):

View File

@ -4,13 +4,13 @@ from collections import namedtuple
import pytest import pytest
from homeassistant.components.cover import ( from homeassistant.components.cover import (
DOMAIN, ATTR_CURRENT_POSITION, ATTR_POSITION, SUPPORT_STOP) ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN, SUPPORT_STOP)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES,
STATE_CLOSED, STATE_OPEN, STATE_UNAVAILABLE, STATE_UNKNOWN) STATE_CLOSED, STATE_OPEN, STATE_UNAVAILABLE, STATE_UNKNOWN)
from tests.common import async_mock_service from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.common import patch_debounce
@pytest.fixture(scope='module') @pytest.fixture(scope='module')

View File

@ -4,15 +4,15 @@ from collections import namedtuple
import pytest import pytest
from homeassistant.components.fan import ( from homeassistant.components.fan import (
ATTR_DIRECTION, ATTR_OSCILLATING, ATTR_DIRECTION, ATTR_OSCILLATING, DIRECTION_FORWARD, DIRECTION_REVERSE,
DIRECTION_FORWARD, DIRECTION_REVERSE, DOMAIN, SERVICE_OSCILLATE, DOMAIN, SERVICE_OSCILLATE, SERVICE_SET_DIRECTION,
SERVICE_SET_DIRECTION, SUPPORT_DIRECTION, SUPPORT_OSCILLATE) SUPPORT_DIRECTION, SUPPORT_OSCILLATE)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, STATE_ON, STATE_OFF,
STATE_ON, STATE_OFF, STATE_UNKNOWN, SERVICE_TURN_ON, SERVICE_TURN_OFF) STATE_UNKNOWN, SERVICE_TURN_ON, SERVICE_TURN_OFF)
from tests.common import async_mock_service from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.common import patch_debounce
@pytest.fixture(scope='module') @pytest.fixture(scope='module')

View File

@ -4,14 +4,14 @@ from collections import namedtuple
import pytest import pytest
from homeassistant.components.light import ( from homeassistant.components.light import (
DOMAIN, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_TEMP, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_COLOR_TEMP, ATTR_HS_COLOR,
ATTR_HS_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR) DOMAIN, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES,
STATE_ON, STATE_OFF, STATE_UNKNOWN) STATE_ON, STATE_OFF, STATE_UNKNOWN)
from tests.common import async_mock_service from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.common import patch_debounce
@pytest.fixture(scope='module') @pytest.fixture(scope='module')

View File

@ -4,7 +4,7 @@ import pytest
from homeassistant.components.homekit.type_locks import Lock from homeassistant.components.homekit.type_locks import Lock
from homeassistant.components.lock import DOMAIN from homeassistant.components.lock import DOMAIN
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN, STATE_UNLOCKED, STATE_LOCKED) ATTR_CODE, ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNKNOWN, STATE_UNLOCKED)
from tests.common import async_mock_service from tests.common import async_mock_service

View File

@ -2,12 +2,12 @@
import pytest import pytest
from homeassistant.components.alarm_control_panel import DOMAIN 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_ENTITY_ID, STATE_UNKNOWN, STATE_ALARM_ARMED_AWAY, ATTR_CODE, ATTR_ENTITY_ID, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED,
STATE_ALARM_TRIGGERED) STATE_UNKNOWN)
from tests.common import async_mock_service from tests.common import async_mock_service

View File

@ -1,11 +1,11 @@
"""Test different accessory types: Sensors.""" """Test different accessory types: Sensors."""
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, AirQualitySensor, BinarySensor, CarbonDioxideSensor, HumiditySensor,
LightSensor, BinarySensor, BINARY_SENSOR_SERVICE_MAP) LightSensor, TemperatureSensor, BINARY_SENSOR_SERVICE_MAP)
from homeassistant.const import ( from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_DEVICE_CLASS, STATE_UNKNOWN, STATE_ON, ATTR_DEVICE_CLASS, ATTR_UNIT_OF_MEASUREMENT, STATE_HOME, STATE_NOT_HOME,
STATE_OFF, STATE_HOME, STATE_NOT_HOME, TEMP_CELSIUS, TEMP_FAHRENHEIT) STATE_OFF, STATE_ON, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT)
async def test_temperature(hass): async def test_temperature(hass):

View File

@ -3,7 +3,7 @@ import pytest
from homeassistant.core import 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 ATTR_ENTITY_ID, STATE_ON, STATE_OFF from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON
from tests.common import async_mock_service from tests.common import async_mock_service

View File

@ -4,15 +4,15 @@ from collections import namedtuple
import pytest import pytest
from homeassistant.components.climate import ( from homeassistant.components.climate import (
DOMAIN, ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE, ATTR_CURRENT_TEMPERATURE, ATTR_TEMPERATURE, ATTR_TARGET_TEMP_LOW,
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH, ATTR_OPERATION_MODE, ATTR_TARGET_TEMP_HIGH, ATTR_OPERATION_MODE, ATTR_OPERATION_LIST,
ATTR_OPERATION_LIST, STATE_COOL, STATE_HEAT, STATE_AUTO) DOMAIN, STATE_AUTO, STATE_COOL, STATE_HEAT)
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT) STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from tests.common import async_mock_service from tests.common import async_mock_service
from tests.components.homekit.test_accessories import patch_debounce from tests.components.homekit.common import patch_debounce
@pytest.fixture(scope='module') @pytest.fixture(scope='module')

View File

@ -4,14 +4,14 @@ import voluptuous as vol
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, convert_to_float, density_to_air_quality, dismiss_setup_message,
temperature_to_homekit, temperature_to_states, density_to_air_quality) show_setup_message, temperature_to_homekit, temperature_to_states)
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 (
DOMAIN, ATTR_MESSAGE, ATTR_NOTIFICATION_ID) ATTR_MESSAGE, ATTR_NOTIFICATION_ID, DOMAIN)
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_NAME) ATTR_CODE, CONF_NAME, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from tests.common import async_mock_service from tests.common import async_mock_service