mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Add homekit configuration option to bind to default interface (#33999)
* Add homekit configuration option to bind to default interface Homekit can fail to be discoverable because the zeroconf default is to bind to all interfaces (InterfaceChoice.All). This does not work on some systems and (InterfaceChoice.Default) which binds to 0.0.0.0 is needed for homekit to zeroconf to function. A new option is available for homekit zeroconf_default_interface: true * Update tests * Update homeassistant/components/homekit/__init__.py Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com> * Update homeassistant/components/homekit/__init__.py Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com> * Review items * has a default * Revert "has a default" This reverts commit 24ecf0920f05f2793abe8a4242ca3f101306b93a. Breaks the tests Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
This commit is contained in:
parent
fc670e46d9
commit
5aca16ef01
@ -4,6 +4,7 @@ import logging
|
||||
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
|
||||
@ -39,9 +40,11 @@ from .const import (
|
||||
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,
|
||||
@ -98,6 +101,10 @@ CONFIG_SCHEMA = vol.Schema(
|
||||
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,
|
||||
}
|
||||
)
|
||||
},
|
||||
@ -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,
|
||||
@ -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)
|
||||
|
||||
@ -287,6 +298,7 @@ class HomeKit:
|
||||
entity_config,
|
||||
safe_mode,
|
||||
advertise_ip=None,
|
||||
interface_choice=None,
|
||||
):
|
||||
"""Initialize a HomeKit object."""
|
||||
self.hass = hass
|
||||
@ -297,6 +309,7 @@ class HomeKit:
|
||||
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
|
||||
@ -317,6 +330,7 @@ class HomeKit:
|
||||
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:
|
||||
|
@ -21,12 +21,14 @@ CONF_FILTER = "filter"
|
||||
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"
|
||||
|
@ -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 (
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
|
||||
@ -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)
|
||||
@ -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()
|
||||
|
||||
@ -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"}
|
||||
@ -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
|
||||
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user