Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions homeassistant/components/homekit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from zlib import adler32

import voluptuous as vol
from zeroconf import InterfaceChoice

from homeassistant.components import cover
from homeassistant.components.cover import DEVICE_CLASS_GARAGE, DEVICE_CLASS_GATE
Expand Down Expand Up @@ -39,9 +40,11 @@
CONF_FEATURE_LIST,
CONF_FILTER,
CONF_SAFE_MODE,
CONF_ZEROCONF_DEFAULT_INTERFACE,
DEFAULT_AUTO_START,
DEFAULT_PORT,
DEFAULT_SAFE_MODE,
DEFAULT_ZEROCONF_DEFAULT_INTERFACE,
DEVICE_CLASS_CO,
DEVICE_CLASS_CO2,
DEVICE_CLASS_PM25,
Expand Down Expand Up @@ -98,6 +101,10 @@
vol.Optional(CONF_SAFE_MODE, default=DEFAULT_SAFE_MODE): cv.boolean,
vol.Optional(CONF_FILTER, default={}): FILTER_SCHEMA,
vol.Optional(CONF_ENTITY_CONFIG, default={}): validate_entity_config,
vol.Optional(
CONF_ZEROCONF_DEFAULT_INTERFACE,
default=DEFAULT_ZEROCONF_DEFAULT_INTERFACE,
): cv.boolean,
}
)
},
Expand All @@ -122,6 +129,9 @@ async def async_setup(hass, config):
safe_mode = conf[CONF_SAFE_MODE]
entity_filter = conf[CONF_FILTER]
entity_config = conf[CONF_ENTITY_CONFIG]
interface_choice = (
InterfaceChoice.Default if config.get(CONF_ZEROCONF_DEFAULT_INTERFACE) else None
)

homekit = HomeKit(
hass,
Expand All @@ -132,6 +142,7 @@ async def async_setup(hass, config):
entity_config,
safe_mode,
advertise_ip,
interface_choice,
)
await hass.async_add_executor_job(homekit.setup)

Expand Down Expand Up @@ -287,6 +298,7 @@ def __init__(
entity_config,
safe_mode,
advertise_ip=None,
interface_choice=None,
):
"""Initialize a HomeKit object."""
self.hass = hass
Expand All @@ -297,6 +309,7 @@ def __init__(
self._config = entity_config
self._safe_mode = safe_mode
self._advertise_ip = advertise_ip
self._interface_choice = interface_choice
self.status = STATUS_READY

self.bridge = None
Expand All @@ -317,6 +330,7 @@ def setup(self):
port=self._port,
persist_file=path,
advertised_address=self._advertise_ip,
interface_choice=self._interface_choice,
)
self.bridge = HomeBridge(self.hass, self.driver, self._name)
if self._safe_mode:
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/homekit/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
CONF_LINKED_BATTERY_SENSOR = "linked_battery_sensor"
CONF_LOW_BATTERY_THRESHOLD = "low_battery_threshold"
CONF_SAFE_MODE = "safe_mode"
CONF_ZEROCONF_DEFAULT_INTERFACE = "zeroconf_default_interface"

# #### Config Defaults ####
DEFAULT_AUTO_START = True
DEFAULT_LOW_BATTERY_THRESHOLD = 20
DEFAULT_PORT = 51827
DEFAULT_SAFE_MODE = False
DEFAULT_ZEROCONF_DEFAULT_INTERFACE = False

# #### Features ####
FEATURE_ON_OFF = "on_off"
Expand Down
46 changes: 39 additions & 7 deletions tests/components/homekit/test_homekit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest.mock import ANY, Mock, patch

import pytest
from zeroconf import InterfaceChoice

from homeassistant import setup
from homeassistant.components.homekit import (
Expand Down Expand Up @@ -67,7 +68,7 @@ async def test_setup_min(hass):
assert await setup.async_setup_component(hass, DOMAIN, {DOMAIN: {}})

mock_homekit.assert_any_call(
hass, BRIDGE_NAME, DEFAULT_PORT, None, ANY, {}, DEFAULT_SAFE_MODE, None
hass, BRIDGE_NAME, DEFAULT_PORT, None, ANY, {}, DEFAULT_SAFE_MODE, None, None
)
assert mock_homekit().setup.called is True

Expand Down Expand Up @@ -96,7 +97,7 @@ async def test_setup_auto_start_disabled(hass):
assert await setup.async_setup_component(hass, DOMAIN, config)

mock_homekit.assert_any_call(
hass, "Test Name", 11111, "172.0.0.0", ANY, {}, DEFAULT_SAFE_MODE, None
hass, "Test Name", 11111, "172.0.0.0", ANY, {}, DEFAULT_SAFE_MODE, None, None
)
assert mock_homekit().setup.called is True

Expand Down Expand Up @@ -139,6 +140,7 @@ async def test_homekit_setup(hass, hk_driver):
port=DEFAULT_PORT,
persist_file=path,
advertised_address=None,
interface_choice=None,
)
assert homekit.driver.safe_mode is False

Expand All @@ -160,6 +162,7 @@ async def test_homekit_setup_ip_address(hass, hk_driver):
port=DEFAULT_PORT,
persist_file=ANY,
advertised_address=None,
interface_choice=None,
)


Expand All @@ -179,12 +182,41 @@ async def test_homekit_setup_advertise_ip(hass, hk_driver):
port=DEFAULT_PORT,
persist_file=ANY,
advertised_address="192.168.1.100",
interface_choice=None,
)


async def test_homekit_setup_interface_choice(hass, hk_driver):
"""Test setup with interface choice of Default."""
homekit = HomeKit(
hass,
BRIDGE_NAME,
DEFAULT_PORT,
"0.0.0.0",
{},
{},
None,
None,
InterfaceChoice.Default,
)

with patch(
f"{PATH_HOMEKIT}.accessories.HomeDriver", return_value=hk_driver
) as mock_driver:
await hass.async_add_executor_job(homekit.setup)
mock_driver.assert_called_with(
hass,
address="0.0.0.0",
port=DEFAULT_PORT,
persist_file=ANY,
advertised_address=None,
interface_choice=InterfaceChoice.Default,
)


async def test_homekit_setup_safe_mode(hass, hk_driver):
"""Test if safe_mode flag is set."""
homekit = HomeKit(hass, BRIDGE_NAME, DEFAULT_PORT, None, {}, {}, True)
homekit = HomeKit(hass, BRIDGE_NAME, DEFAULT_PORT, None, {}, {}, True, None)

with patch(f"{PATH_HOMEKIT}.accessories.HomeDriver", return_value=hk_driver):
await hass.async_add_executor_job(homekit.setup)
Expand All @@ -193,7 +225,7 @@ async def test_homekit_setup_safe_mode(hass, hk_driver):

async def test_homekit_add_accessory():
"""Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit("hass", None, None, None, lambda entity_id: True, {}, None)
homekit = HomeKit("hass", None, None, None, lambda entity_id: True, {}, None, None)
homekit.driver = "driver"
homekit.bridge = mock_bridge = Mock()

Expand All @@ -215,7 +247,7 @@ async def test_homekit_add_accessory():

async def test_homekit_remove_accessory():
"""Remove accessory from bridge."""
homekit = HomeKit("hass", None, None, None, lambda entity_id: True, {}, None)
homekit = HomeKit("hass", None, None, None, lambda entity_id: True, {}, None, None)
homekit.driver = "driver"
homekit.bridge = mock_bridge = Mock()
mock_bridge.accessories = {"light.demo": "acc"}
Expand All @@ -228,7 +260,7 @@ async def test_homekit_remove_accessory():
async def test_homekit_entity_filter(hass):
"""Test the entity filter."""
entity_filter = generate_filter(["cover"], ["demo.test"], [], [])
homekit = HomeKit(hass, None, None, None, entity_filter, {}, None)
homekit = HomeKit(hass, None, None, None, entity_filter, {}, None, None)

with patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc:
mock_get_acc.return_value = None
Expand All @@ -248,7 +280,7 @@ async def test_homekit_entity_filter(hass):
async def test_homekit_start(hass, hk_driver, debounce_patcher):
"""Test HomeKit start method."""
pin = b"123-45-678"
homekit = HomeKit(hass, None, None, None, {}, {"cover.demo": {}}, None)
homekit = HomeKit(hass, None, None, None, {}, {"cover.demo": {}}, None, None)
homekit.bridge = Mock()
homekit.bridge.accessories = []
homekit.driver = hk_driver
Expand Down