Cleanup KNX integration (#68820)
* Cleanup KNX integration * Cleanup KNX integration * Update homeassistant/components/knx/__init__.py Co-authored-by: Matthias Alphart <farmio@alphart.net> Co-authored-by: Matthias Alphart <farmio@alphart.net>
This commit is contained in:
parent
62aa7fe10e
commit
cec3a08b95
9 changed files with 211 additions and 500 deletions
|
@ -21,7 +21,6 @@ from xknx.telegram.address import (
|
||||||
)
|
)
|
||||||
from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
|
from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
|
||||||
|
|
||||||
from homeassistant import config_entries
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_EVENT,
|
CONF_EVENT,
|
||||||
|
@ -43,7 +42,13 @@ from .const import (
|
||||||
CONF_KNX_CONNECTION_TYPE,
|
CONF_KNX_CONNECTION_TYPE,
|
||||||
CONF_KNX_EXPOSE,
|
CONF_KNX_EXPOSE,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS,
|
||||||
|
CONF_KNX_LOCAL_IP,
|
||||||
|
CONF_KNX_MCAST_GRP,
|
||||||
|
CONF_KNX_MCAST_PORT,
|
||||||
|
CONF_KNX_RATE_LIMIT,
|
||||||
|
CONF_KNX_ROUTE_BACK,
|
||||||
CONF_KNX_ROUTING,
|
CONF_KNX_ROUTING,
|
||||||
|
CONF_KNX_STATE_UPDATER,
|
||||||
CONF_KNX_TUNNELING,
|
CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_TUNNELING_TCP,
|
CONF_KNX_TUNNELING_TCP,
|
||||||
DATA_HASS_CONFIG,
|
DATA_HASS_CONFIG,
|
||||||
|
@ -57,7 +62,6 @@ from .schema import (
|
||||||
BinarySensorSchema,
|
BinarySensorSchema,
|
||||||
ButtonSchema,
|
ButtonSchema,
|
||||||
ClimateSchema,
|
ClimateSchema,
|
||||||
ConnectionSchema,
|
|
||||||
CoverSchema,
|
CoverSchema,
|
||||||
EventSchema,
|
EventSchema,
|
||||||
ExposeSchema,
|
ExposeSchema,
|
||||||
|
@ -77,9 +81,6 @@ from .schema import (
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CONF_KNX_FIRE_EVENT: Final = "fire_event"
|
|
||||||
CONF_KNX_EVENT_FILTER: Final = "event_filter"
|
|
||||||
|
|
||||||
SERVICE_KNX_SEND: Final = "send"
|
SERVICE_KNX_SEND: Final = "send"
|
||||||
SERVICE_KNX_ATTR_PAYLOAD: Final = "payload"
|
SERVICE_KNX_ATTR_PAYLOAD: Final = "payload"
|
||||||
SERVICE_KNX_ATTR_TYPE: Final = "type"
|
SERVICE_KNX_ATTR_TYPE: Final = "type"
|
||||||
|
@ -93,26 +94,21 @@ CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
DOMAIN: vol.All(
|
DOMAIN: vol.All(
|
||||||
# deprecated since 2021.12
|
# deprecated since 2021.12
|
||||||
cv.deprecated(ConnectionSchema.CONF_KNX_STATE_UPDATER),
|
cv.deprecated(CONF_KNX_STATE_UPDATER),
|
||||||
cv.deprecated(ConnectionSchema.CONF_KNX_RATE_LIMIT),
|
cv.deprecated(CONF_KNX_RATE_LIMIT),
|
||||||
cv.deprecated(CONF_KNX_ROUTING),
|
cv.deprecated(CONF_KNX_ROUTING),
|
||||||
cv.deprecated(CONF_KNX_TUNNELING),
|
cv.deprecated(CONF_KNX_TUNNELING),
|
||||||
cv.deprecated(CONF_KNX_INDIVIDUAL_ADDRESS),
|
cv.deprecated(CONF_KNX_INDIVIDUAL_ADDRESS),
|
||||||
cv.deprecated(ConnectionSchema.CONF_KNX_MCAST_GRP),
|
cv.deprecated(CONF_KNX_MCAST_GRP),
|
||||||
cv.deprecated(ConnectionSchema.CONF_KNX_MCAST_PORT),
|
cv.deprecated(CONF_KNX_MCAST_PORT),
|
||||||
cv.deprecated(CONF_KNX_EVENT_FILTER),
|
cv.deprecated("event_filter"),
|
||||||
# deprecated since 2021.4
|
# deprecated since 2021.4
|
||||||
cv.deprecated("config_file"),
|
cv.deprecated("config_file"),
|
||||||
# deprecated since 2021.2
|
# deprecated since 2021.2
|
||||||
cv.deprecated(CONF_KNX_FIRE_EVENT),
|
cv.deprecated("fire_event"),
|
||||||
cv.deprecated("fire_event_filter", replacement_key=CONF_KNX_EVENT_FILTER),
|
cv.deprecated("fire_event_filter"),
|
||||||
vol.Schema(
|
vol.Schema(
|
||||||
{
|
{
|
||||||
**ConnectionSchema.SCHEMA,
|
|
||||||
vol.Optional(CONF_KNX_FIRE_EVENT): cv.boolean,
|
|
||||||
vol.Optional(CONF_KNX_EVENT_FILTER, default=[]): vol.All(
|
|
||||||
cv.ensure_list, [cv.string]
|
|
||||||
),
|
|
||||||
**EventSchema.SCHEMA,
|
**EventSchema.SCHEMA,
|
||||||
**ExposeSchema.platform_node(),
|
**ExposeSchema.platform_node(),
|
||||||
**BinarySensorSchema.platform_node(),
|
**BinarySensorSchema.platform_node(),
|
||||||
|
@ -211,22 +207,13 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
|
||||||
conf = dict(conf)
|
conf = dict(conf)
|
||||||
hass.data[DATA_KNX_CONFIG] = conf
|
hass.data[DATA_KNX_CONFIG] = conf
|
||||||
|
|
||||||
# Only import if we haven't before.
|
|
||||||
if not hass.config_entries.async_entries(DOMAIN):
|
|
||||||
hass.async_create_task(
|
|
||||||
hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=conf
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Load a config entry."""
|
"""Load a config entry."""
|
||||||
# `conf` is None when reloading the integration or no `knx` key in configuration.yaml
|
# `config` is None when reloading the integration or no `knx` key in configuration.yaml
|
||||||
if (conf := hass.data.get(DATA_KNX_CONFIG)) is None:
|
if (config := hass.data.get(DATA_KNX_CONFIG)) is None:
|
||||||
_conf = await async_integration_yaml_config(hass, DOMAIN)
|
_conf = await async_integration_yaml_config(hass, DOMAIN)
|
||||||
if not _conf or DOMAIN not in _conf:
|
if not _conf or DOMAIN not in _conf:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
|
@ -235,18 +222,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"for KNX entity configuration documentation"
|
"for KNX entity configuration documentation"
|
||||||
)
|
)
|
||||||
# generate defaults
|
# generate defaults
|
||||||
conf = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
|
config = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
|
||||||
else:
|
else:
|
||||||
conf = _conf[DOMAIN]
|
config = _conf[DOMAIN]
|
||||||
config = {**conf, **entry.data}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
knx_module = KNXModule(hass, config, entry)
|
knx_module = KNXModule(hass, config, entry)
|
||||||
await knx_module.start()
|
await knx_module.start()
|
||||||
except XKNXException as ex:
|
except XKNXException as ex:
|
||||||
raise ConfigEntryNotReady from ex
|
raise ConfigEntryNotReady from ex
|
||||||
|
|
||||||
hass.data[DATA_KNX_CONFIG] = conf
|
hass.data[DATA_KNX_CONFIG] = config
|
||||||
hass.data[DOMAIN] = knx_module
|
hass.data[DOMAIN] = knx_module
|
||||||
|
|
||||||
if CONF_KNX_EXPOSE in config:
|
if CONF_KNX_EXPOSE in config:
|
||||||
|
@ -370,12 +355,12 @@ class KNXModule:
|
||||||
def init_xknx(self) -> None:
|
def init_xknx(self) -> None:
|
||||||
"""Initialize XKNX object."""
|
"""Initialize XKNX object."""
|
||||||
self.xknx = XKNX(
|
self.xknx = XKNX(
|
||||||
own_address=self.config[CONF_KNX_INDIVIDUAL_ADDRESS],
|
own_address=self.entry.data[CONF_KNX_INDIVIDUAL_ADDRESS],
|
||||||
rate_limit=self.config[ConnectionSchema.CONF_KNX_RATE_LIMIT],
|
rate_limit=self.entry.data[CONF_KNX_RATE_LIMIT],
|
||||||
multicast_group=self.config[ConnectionSchema.CONF_KNX_MCAST_GRP],
|
multicast_group=self.entry.data[CONF_KNX_MCAST_GRP],
|
||||||
multicast_port=self.config[ConnectionSchema.CONF_KNX_MCAST_PORT],
|
multicast_port=self.entry.data[CONF_KNX_MCAST_PORT],
|
||||||
connection_config=self.connection_config(),
|
connection_config=self.connection_config(),
|
||||||
state_updater=self.config[ConnectionSchema.CONF_KNX_STATE_UPDATER],
|
state_updater=self.entry.data[CONF_KNX_STATE_UPDATER],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
|
@ -388,29 +373,29 @@ class KNXModule:
|
||||||
|
|
||||||
def connection_config(self) -> ConnectionConfig:
|
def connection_config(self) -> ConnectionConfig:
|
||||||
"""Return the connection_config."""
|
"""Return the connection_config."""
|
||||||
_conn_type: str = self.config[CONF_KNX_CONNECTION_TYPE]
|
_conn_type: str = self.entry.data[CONF_KNX_CONNECTION_TYPE]
|
||||||
if _conn_type == CONF_KNX_ROUTING:
|
if _conn_type == CONF_KNX_ROUTING:
|
||||||
return ConnectionConfig(
|
return ConnectionConfig(
|
||||||
connection_type=ConnectionType.ROUTING,
|
connection_type=ConnectionType.ROUTING,
|
||||||
local_ip=self.config.get(ConnectionSchema.CONF_KNX_LOCAL_IP),
|
local_ip=self.entry.data.get(CONF_KNX_LOCAL_IP),
|
||||||
auto_reconnect=True,
|
auto_reconnect=True,
|
||||||
threaded=True,
|
threaded=True,
|
||||||
)
|
)
|
||||||
if _conn_type == CONF_KNX_TUNNELING:
|
if _conn_type == CONF_KNX_TUNNELING:
|
||||||
return ConnectionConfig(
|
return ConnectionConfig(
|
||||||
connection_type=ConnectionType.TUNNELING,
|
connection_type=ConnectionType.TUNNELING,
|
||||||
gateway_ip=self.config[CONF_HOST],
|
gateway_ip=self.entry.data[CONF_HOST],
|
||||||
gateway_port=self.config[CONF_PORT],
|
gateway_port=self.entry.data[CONF_PORT],
|
||||||
local_ip=self.config.get(ConnectionSchema.CONF_KNX_LOCAL_IP),
|
local_ip=self.entry.data.get(CONF_KNX_LOCAL_IP),
|
||||||
route_back=self.config.get(ConnectionSchema.CONF_KNX_ROUTE_BACK, False),
|
route_back=self.entry.data.get(CONF_KNX_ROUTE_BACK, False),
|
||||||
auto_reconnect=True,
|
auto_reconnect=True,
|
||||||
threaded=True,
|
threaded=True,
|
||||||
)
|
)
|
||||||
if _conn_type == CONF_KNX_TUNNELING_TCP:
|
if _conn_type == CONF_KNX_TUNNELING_TCP:
|
||||||
return ConnectionConfig(
|
return ConnectionConfig(
|
||||||
connection_type=ConnectionType.TUNNELING_TCP,
|
connection_type=ConnectionType.TUNNELING_TCP,
|
||||||
gateway_ip=self.config[CONF_HOST],
|
gateway_ip=self.entry.data[CONF_HOST],
|
||||||
gateway_port=self.config[CONF_PORT],
|
gateway_port=self.entry.data[CONF_PORT],
|
||||||
auto_reconnect=True,
|
auto_reconnect=True,
|
||||||
threaded=True,
|
threaded=True,
|
||||||
)
|
)
|
||||||
|
@ -475,9 +460,7 @@ class KNXModule:
|
||||||
|
|
||||||
def register_event_callback(self) -> TelegramQueue.Callback:
|
def register_event_callback(self) -> TelegramQueue.Callback:
|
||||||
"""Register callback for knx_event within XKNX TelegramQueue."""
|
"""Register callback for knx_event within XKNX TelegramQueue."""
|
||||||
# backwards compatibility for deprecated CONF_KNX_EVENT_FILTER
|
address_filters = []
|
||||||
# use `address_filters = []` when this is not needed anymore
|
|
||||||
address_filters = list(map(AddressFilter, self.config[CONF_KNX_EVENT_FILTER]))
|
|
||||||
for filter_set in self.config[CONF_EVENT]:
|
for filter_set in self.config[CONF_EVENT]:
|
||||||
_filters = list(map(AddressFilter, filter_set[KNX_ADDRESS]))
|
_filters = list(map(AddressFilter, filter_set[KNX_ADDRESS]))
|
||||||
address_filters.extend(_filters)
|
address_filters.extend(_filters)
|
||||||
|
|
|
@ -18,25 +18,32 @@ import homeassistant.helpers.config_validation as cv
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_KNX_AUTOMATIC,
|
CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_CONNECTION_TYPE,
|
CONF_KNX_CONNECTION_TYPE,
|
||||||
|
CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS,
|
||||||
CONF_KNX_INITIAL_CONNECTION_TYPES,
|
CONF_KNX_INITIAL_CONNECTION_TYPES,
|
||||||
|
CONF_KNX_LOCAL_IP,
|
||||||
|
CONF_KNX_MCAST_GRP,
|
||||||
|
CONF_KNX_MCAST_PORT,
|
||||||
|
CONF_KNX_RATE_LIMIT,
|
||||||
|
CONF_KNX_ROUTE_BACK,
|
||||||
CONF_KNX_ROUTING,
|
CONF_KNX_ROUTING,
|
||||||
|
CONF_KNX_STATE_UPDATER,
|
||||||
CONF_KNX_TUNNELING,
|
CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_TUNNELING_TCP,
|
CONF_KNX_TUNNELING_TCP,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from .schema import ConnectionSchema
|
|
||||||
|
|
||||||
CONF_KNX_GATEWAY: Final = "gateway"
|
CONF_KNX_GATEWAY: Final = "gateway"
|
||||||
CONF_MAX_RATE_LIMIT: Final = 60
|
CONF_MAX_RATE_LIMIT: Final = 60
|
||||||
CONF_DEFAULT_LOCAL_IP: Final = "0.0.0.0"
|
CONF_DEFAULT_LOCAL_IP: Final = "0.0.0.0"
|
||||||
|
|
||||||
DEFAULT_ENTRY_DATA: Final = {
|
DEFAULT_ENTRY_DATA: Final = {
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: ConnectionSchema.CONF_KNX_DEFAULT_STATE_UPDATER,
|
CONF_KNX_STATE_UPDATER: CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: ConnectionSchema.CONF_KNX_DEFAULT_RATE_LIMIT,
|
CONF_KNX_RATE_LIMIT: CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||||
}
|
}
|
||||||
|
|
||||||
CONF_KNX_TUNNELING_TYPE: Final = "tunneling_type"
|
CONF_KNX_TUNNELING_TYPE: Final = "tunneling_type"
|
||||||
|
@ -144,12 +151,10 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: user_input[
|
CONF_KNX_INDIVIDUAL_ADDRESS: user_input[
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS
|
CONF_KNX_INDIVIDUAL_ADDRESS
|
||||||
],
|
],
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: (
|
CONF_KNX_ROUTE_BACK: (
|
||||||
connection_type == CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
connection_type == CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
||||||
),
|
),
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: user_input.get(
|
CONF_KNX_LOCAL_IP: user_input.get(CONF_KNX_LOCAL_IP),
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP
|
|
||||||
),
|
|
||||||
CONF_KNX_CONNECTION_TYPE: (
|
CONF_KNX_CONNECTION_TYPE: (
|
||||||
CONF_KNX_TUNNELING_TCP
|
CONF_KNX_TUNNELING_TCP
|
||||||
if connection_type == CONF_KNX_LABEL_TUNNELING_TCP
|
if connection_type == CONF_KNX_LABEL_TUNNELING_TCP
|
||||||
|
@ -182,7 +187,7 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.show_advanced_options:
|
if self.show_advanced_options:
|
||||||
fields[vol.Optional(ConnectionSchema.CONF_KNX_LOCAL_IP)] = str
|
fields[vol.Optional(CONF_KNX_LOCAL_IP)] = str
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="manual_tunnel", data_schema=vol.Schema(fields), errors=errors
|
step_id="manual_tunnel", data_schema=vol.Schema(fields), errors=errors
|
||||||
|
@ -195,18 +200,12 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
title=CONF_KNX_ROUTING.capitalize(),
|
title=CONF_KNX_ROUTING.capitalize(),
|
||||||
data={
|
data={
|
||||||
**DEFAULT_ENTRY_DATA,
|
**DEFAULT_ENTRY_DATA,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: user_input[
|
CONF_KNX_MCAST_GRP: user_input[CONF_KNX_MCAST_GRP],
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP
|
CONF_KNX_MCAST_PORT: user_input[CONF_KNX_MCAST_PORT],
|
||||||
],
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: user_input[
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT
|
|
||||||
],
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: user_input[
|
CONF_KNX_INDIVIDUAL_ADDRESS: user_input[
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS
|
CONF_KNX_INDIVIDUAL_ADDRESS
|
||||||
],
|
],
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: user_input.get(
|
CONF_KNX_LOCAL_IP: user_input.get(CONF_KNX_LOCAL_IP),
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP
|
|
||||||
),
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -216,83 +215,17 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
vol.Required(
|
vol.Required(
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS, default=XKNX.DEFAULT_ADDRESS
|
CONF_KNX_INDIVIDUAL_ADDRESS, default=XKNX.DEFAULT_ADDRESS
|
||||||
): str,
|
): str,
|
||||||
vol.Required(
|
vol.Required(CONF_KNX_MCAST_GRP, default=DEFAULT_MCAST_GRP): str,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP, default=DEFAULT_MCAST_GRP
|
vol.Required(CONF_KNX_MCAST_PORT, default=DEFAULT_MCAST_PORT): cv.port,
|
||||||
): str,
|
|
||||||
vol.Required(
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT, default=DEFAULT_MCAST_PORT
|
|
||||||
): cv.port,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.show_advanced_options:
|
if self.show_advanced_options:
|
||||||
fields[vol.Optional(ConnectionSchema.CONF_KNX_LOCAL_IP)] = str
|
fields[vol.Optional(CONF_KNX_LOCAL_IP)] = str
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="routing", data_schema=vol.Schema(fields), errors=errors
|
step_id="routing", data_schema=vol.Schema(fields), errors=errors
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_step_import(self, config: dict | None = None) -> FlowResult:
|
|
||||||
"""Import a config entry.
|
|
||||||
|
|
||||||
Performs a one time import of the YAML configuration and creates a config entry based on it
|
|
||||||
if not already done before.
|
|
||||||
"""
|
|
||||||
if self._async_current_entries() or not config:
|
|
||||||
return self.async_abort(reason="single_instance_allowed")
|
|
||||||
|
|
||||||
data = {
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: min(
|
|
||||||
config[ConnectionSchema.CONF_KNX_RATE_LIMIT], CONF_MAX_RATE_LIMIT
|
|
||||||
),
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: config[
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER
|
|
||||||
],
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: config[
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP
|
|
||||||
],
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: config[
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT
|
|
||||||
],
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: config[CONF_KNX_INDIVIDUAL_ADDRESS],
|
|
||||||
}
|
|
||||||
|
|
||||||
if CONF_KNX_TUNNELING in config:
|
|
||||||
return self.async_create_entry(
|
|
||||||
title=f"{CONF_KNX_TUNNELING.capitalize()} @ {config[CONF_KNX_TUNNELING][CONF_HOST]}",
|
|
||||||
data={
|
|
||||||
**DEFAULT_ENTRY_DATA,
|
|
||||||
CONF_HOST: config[CONF_KNX_TUNNELING][CONF_HOST],
|
|
||||||
CONF_PORT: config[CONF_KNX_TUNNELING][CONF_PORT],
|
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: config[CONF_KNX_TUNNELING].get(
|
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP
|
|
||||||
),
|
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: config[CONF_KNX_TUNNELING][
|
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK
|
|
||||||
],
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
|
||||||
**data,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_KNX_ROUTING in config:
|
|
||||||
return self.async_create_entry(
|
|
||||||
title=CONF_KNX_ROUTING.capitalize(),
|
|
||||||
data={
|
|
||||||
**DEFAULT_ENTRY_DATA,
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
|
||||||
**data,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return self.async_create_entry(
|
|
||||||
title=CONF_KNX_AUTOMATIC.capitalize(),
|
|
||||||
data={
|
|
||||||
**DEFAULT_ENTRY_DATA,
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
|
||||||
**data,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class KNXOptionsFlowHandler(OptionsFlow):
|
class KNXOptionsFlowHandler(OptionsFlow):
|
||||||
"""Handle KNX options."""
|
"""Handle KNX options."""
|
||||||
|
@ -334,47 +267,44 @@ class KNXOptionsFlowHandler(OptionsFlow):
|
||||||
default=self.current_config[CONF_KNX_INDIVIDUAL_ADDRESS],
|
default=self.current_config[CONF_KNX_INDIVIDUAL_ADDRESS],
|
||||||
): str,
|
): str,
|
||||||
vol.Required(
|
vol.Required(
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP,
|
CONF_KNX_MCAST_GRP,
|
||||||
default=self.current_config.get(
|
default=self.current_config.get(CONF_KNX_MCAST_GRP, DEFAULT_MCAST_GRP),
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP, DEFAULT_MCAST_GRP
|
|
||||||
),
|
|
||||||
): str,
|
): str,
|
||||||
vol.Required(
|
vol.Required(
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT,
|
CONF_KNX_MCAST_PORT,
|
||||||
default=self.current_config.get(
|
default=self.current_config.get(
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT, DEFAULT_MCAST_PORT
|
CONF_KNX_MCAST_PORT, DEFAULT_MCAST_PORT
|
||||||
),
|
),
|
||||||
): cv.port,
|
): cv.port,
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.show_advanced_options:
|
if self.show_advanced_options:
|
||||||
local_ip = (
|
local_ip = (
|
||||||
self.current_config.get(ConnectionSchema.CONF_KNX_LOCAL_IP)
|
self.current_config.get(CONF_KNX_LOCAL_IP)
|
||||||
if self.current_config.get(ConnectionSchema.CONF_KNX_LOCAL_IP)
|
if self.current_config.get(CONF_KNX_LOCAL_IP) is not None
|
||||||
is not None
|
|
||||||
else CONF_DEFAULT_LOCAL_IP
|
else CONF_DEFAULT_LOCAL_IP
|
||||||
)
|
)
|
||||||
data_schema[
|
data_schema[
|
||||||
vol.Required(
|
vol.Required(
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP,
|
CONF_KNX_LOCAL_IP,
|
||||||
default=local_ip,
|
default=local_ip,
|
||||||
)
|
)
|
||||||
] = str
|
] = str
|
||||||
data_schema[
|
data_schema[
|
||||||
vol.Required(
|
vol.Required(
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER,
|
CONF_KNX_STATE_UPDATER,
|
||||||
default=self.current_config.get(
|
default=self.current_config.get(
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER,
|
CONF_KNX_STATE_UPDATER,
|
||||||
ConnectionSchema.CONF_KNX_DEFAULT_STATE_UPDATER,
|
CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
] = bool
|
] = bool
|
||||||
data_schema[
|
data_schema[
|
||||||
vol.Required(
|
vol.Required(
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT,
|
CONF_KNX_RATE_LIMIT,
|
||||||
default=self.current_config.get(
|
default=self.current_config.get(
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT,
|
CONF_KNX_RATE_LIMIT,
|
||||||
ConnectionSchema.CONF_KNX_DEFAULT_RATE_LIMIT,
|
CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
] = vol.All(vol.Coerce(int), vol.Range(min=1, max=CONF_MAX_RATE_LIMIT))
|
] = vol.All(vol.Coerce(int), vol.Range(min=1, max=CONF_MAX_RATE_LIMIT))
|
||||||
|
@ -421,11 +351,8 @@ class KNXOptionsFlowHandler(OptionsFlow):
|
||||||
entry_data = {
|
entry_data = {
|
||||||
**DEFAULT_ENTRY_DATA,
|
**DEFAULT_ENTRY_DATA,
|
||||||
**self.general_settings,
|
**self.general_settings,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: self.general_settings.get(
|
CONF_KNX_LOCAL_IP: self.general_settings.get(CONF_KNX_LOCAL_IP)
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP
|
if self.general_settings.get(CONF_KNX_LOCAL_IP) != CONF_DEFAULT_LOCAL_IP
|
||||||
)
|
|
||||||
if self.general_settings.get(ConnectionSchema.CONF_KNX_LOCAL_IP)
|
|
||||||
!= CONF_DEFAULT_LOCAL_IP
|
|
||||||
else None,
|
else None,
|
||||||
CONF_HOST: self.current_config.get(CONF_HOST, ""),
|
CONF_HOST: self.current_config.get(CONF_HOST, ""),
|
||||||
}
|
}
|
||||||
|
@ -436,7 +363,7 @@ class KNXOptionsFlowHandler(OptionsFlow):
|
||||||
**entry_data,
|
**entry_data,
|
||||||
CONF_HOST: user_input[CONF_HOST],
|
CONF_HOST: user_input[CONF_HOST],
|
||||||
CONF_PORT: user_input[CONF_PORT],
|
CONF_PORT: user_input[CONF_PORT],
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: (
|
CONF_KNX_ROUTE_BACK: (
|
||||||
connection_type == CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
connection_type == CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
||||||
),
|
),
|
||||||
CONF_KNX_CONNECTION_TYPE: (
|
CONF_KNX_CONNECTION_TYPE: (
|
||||||
|
@ -466,7 +393,7 @@ class KNXOptionsFlowHandler(OptionsFlow):
|
||||||
def get_knx_tunneling_type(config_entry_data: dict) -> str:
|
def get_knx_tunneling_type(config_entry_data: dict) -> str:
|
||||||
"""Obtain the knx tunneling type based on the data in the config entry data."""
|
"""Obtain the knx tunneling type based on the data in the config entry data."""
|
||||||
connection_type = config_entry_data[CONF_KNX_CONNECTION_TYPE]
|
connection_type = config_entry_data[CONF_KNX_CONNECTION_TYPE]
|
||||||
route_back = config_entry_data.get(ConnectionSchema.CONF_KNX_ROUTE_BACK, False)
|
route_back = config_entry_data.get(CONF_KNX_ROUTE_BACK, False)
|
||||||
if route_back and connection_type == CONF_KNX_TUNNELING:
|
if route_back and connection_type == CONF_KNX_TUNNELING:
|
||||||
return CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
return CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK
|
||||||
if connection_type == CONF_KNX_TUNNELING_TCP:
|
if connection_type == CONF_KNX_TUNNELING_TCP:
|
||||||
|
|
|
@ -30,11 +30,26 @@ KNX_ADDRESS: Final = "address"
|
||||||
CONF_INVERT: Final = "invert"
|
CONF_INVERT: Final = "invert"
|
||||||
CONF_KNX_EXPOSE: Final = "expose"
|
CONF_KNX_EXPOSE: Final = "expose"
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: Final = "individual_address"
|
CONF_KNX_INDIVIDUAL_ADDRESS: Final = "individual_address"
|
||||||
|
|
||||||
|
##
|
||||||
|
# Connection constants
|
||||||
|
##
|
||||||
CONF_KNX_CONNECTION_TYPE: Final = "connection_type"
|
CONF_KNX_CONNECTION_TYPE: Final = "connection_type"
|
||||||
CONF_KNX_AUTOMATIC: Final = "automatic"
|
CONF_KNX_AUTOMATIC: Final = "automatic"
|
||||||
CONF_KNX_ROUTING: Final = "routing"
|
CONF_KNX_ROUTING: Final = "routing"
|
||||||
CONF_KNX_TUNNELING: Final = "tunneling"
|
CONF_KNX_TUNNELING: Final = "tunneling"
|
||||||
CONF_KNX_TUNNELING_TCP: Final = "tunneling_tcp"
|
CONF_KNX_TUNNELING_TCP: Final = "tunneling_tcp"
|
||||||
|
CONF_KNX_LOCAL_IP = "local_ip"
|
||||||
|
CONF_KNX_MCAST_GRP = "multicast_group"
|
||||||
|
CONF_KNX_MCAST_PORT = "multicast_port"
|
||||||
|
|
||||||
|
CONF_KNX_RATE_LIMIT = "rate_limit"
|
||||||
|
CONF_KNX_ROUTE_BACK = "route_back"
|
||||||
|
CONF_KNX_STATE_UPDATER = "state_updater"
|
||||||
|
CONF_KNX_DEFAULT_STATE_UPDATER = True
|
||||||
|
CONF_KNX_DEFAULT_RATE_LIMIT = 20
|
||||||
|
|
||||||
|
|
||||||
CONF_PAYLOAD: Final = "payload"
|
CONF_PAYLOAD: Final = "payload"
|
||||||
CONF_PAYLOAD_LENGTH: Final = "payload_length"
|
CONF_PAYLOAD_LENGTH: Final = "payload_length"
|
||||||
CONF_RESET_AFTER: Final = "reset_after"
|
CONF_RESET_AFTER: Final = "reset_after"
|
||||||
|
|
|
@ -6,11 +6,9 @@ from collections import OrderedDict
|
||||||
from typing import Any, ClassVar, Final
|
from typing import Any, ClassVar, Final
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from xknx import XKNX
|
|
||||||
from xknx.devices.climate import SetpointShiftMode
|
from xknx.devices.climate import SetpointShiftMode
|
||||||
from xknx.dpt import DPTBase, DPTNumeric
|
from xknx.dpt import DPTBase, DPTNumeric
|
||||||
from xknx.exceptions import ConversionError, CouldNotParseAddress
|
from xknx.exceptions import ConversionError, CouldNotParseAddress
|
||||||
from xknx.io import DEFAULT_MCAST_GRP, DEFAULT_MCAST_PORT
|
|
||||||
from xknx.telegram.address import IndividualAddress, parse_device_group_address
|
from xknx.telegram.address import IndividualAddress, parse_device_group_address
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
|
@ -27,10 +25,8 @@ from homeassistant.const import (
|
||||||
CONF_ENTITY_CATEGORY,
|
CONF_ENTITY_CATEGORY,
|
||||||
CONF_ENTITY_ID,
|
CONF_ENTITY_ID,
|
||||||
CONF_EVENT,
|
CONF_EVENT,
|
||||||
CONF_HOST,
|
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PORT,
|
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
|
@ -40,9 +36,6 @@ from homeassistant.helpers.entity import validate_entity_category
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_INVERT,
|
CONF_INVERT,
|
||||||
CONF_KNX_EXPOSE,
|
CONF_KNX_EXPOSE,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
|
||||||
CONF_KNX_ROUTING,
|
|
||||||
CONF_KNX_TUNNELING,
|
|
||||||
CONF_PAYLOAD,
|
CONF_PAYLOAD,
|
||||||
CONF_PAYLOAD_LENGTH,
|
CONF_PAYLOAD_LENGTH,
|
||||||
CONF_RESET_AFTER,
|
CONF_RESET_AFTER,
|
||||||
|
@ -196,57 +189,6 @@ sync_state_validator = vol.Any(
|
||||||
cv.matches_regex(r"^(init|expire|every)( \d*)?$"),
|
cv.matches_regex(r"^(init|expire|every)( \d*)?$"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
##############
|
|
||||||
# CONNECTION
|
|
||||||
##############
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionSchema:
|
|
||||||
"""
|
|
||||||
Voluptuous schema for KNX connection.
|
|
||||||
|
|
||||||
DEPRECATED: Migrated to config and options flow. Will be removed in a future version of Home Assistant.
|
|
||||||
"""
|
|
||||||
|
|
||||||
CONF_KNX_LOCAL_IP = "local_ip"
|
|
||||||
CONF_KNX_MCAST_GRP = "multicast_group"
|
|
||||||
CONF_KNX_MCAST_PORT = "multicast_port"
|
|
||||||
CONF_KNX_RATE_LIMIT = "rate_limit"
|
|
||||||
CONF_KNX_ROUTE_BACK = "route_back"
|
|
||||||
CONF_KNX_STATE_UPDATER = "state_updater"
|
|
||||||
|
|
||||||
CONF_KNX_DEFAULT_STATE_UPDATER = True
|
|
||||||
CONF_KNX_DEFAULT_RATE_LIMIT = 20
|
|
||||||
|
|
||||||
TUNNELING_SCHEMA = vol.Schema(
|
|
||||||
{
|
|
||||||
vol.Optional(CONF_PORT, default=DEFAULT_MCAST_PORT): cv.port,
|
|
||||||
vol.Required(CONF_HOST): cv.string,
|
|
||||||
vol.Optional(CONF_KNX_LOCAL_IP): cv.string,
|
|
||||||
vol.Optional(CONF_KNX_ROUTE_BACK, default=False): cv.boolean,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
ROUTING_SCHEMA = vol.Maybe(vol.Schema({vol.Optional(CONF_KNX_LOCAL_IP): cv.string}))
|
|
||||||
|
|
||||||
SCHEMA = {
|
|
||||||
vol.Exclusive(CONF_KNX_ROUTING, "connection_type"): ROUTING_SCHEMA,
|
|
||||||
vol.Exclusive(CONF_KNX_TUNNELING, "connection_type"): TUNNELING_SCHEMA,
|
|
||||||
vol.Optional(
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS, default=XKNX.DEFAULT_ADDRESS
|
|
||||||
): ia_validator,
|
|
||||||
vol.Optional(CONF_KNX_MCAST_GRP, default=DEFAULT_MCAST_GRP): cv.string,
|
|
||||||
vol.Optional(CONF_KNX_MCAST_PORT, default=DEFAULT_MCAST_PORT): cv.port,
|
|
||||||
vol.Optional(
|
|
||||||
CONF_KNX_STATE_UPDATER, default=CONF_KNX_DEFAULT_STATE_UPDATER
|
|
||||||
): cv.boolean,
|
|
||||||
vol.Optional(CONF_KNX_RATE_LIMIT, default=CONF_KNX_DEFAULT_RATE_LIMIT): vol.All(
|
|
||||||
vol.Coerce(int), vol.Range(min=1, max=100)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# EVENT
|
# EVENT
|
||||||
#########
|
#########
|
||||||
|
|
|
@ -13,11 +13,16 @@ from xknx.telegram import Telegram, TelegramDirection
|
||||||
from xknx.telegram.address import GroupAddress, IndividualAddress
|
from xknx.telegram.address import GroupAddress, IndividualAddress
|
||||||
from xknx.telegram.apci import APCI, GroupValueRead, GroupValueResponse, GroupValueWrite
|
from xknx.telegram.apci import APCI, GroupValueRead, GroupValueResponse, GroupValueWrite
|
||||||
|
|
||||||
from homeassistant.components.knx import ConnectionSchema
|
|
||||||
from homeassistant.components.knx.const import (
|
from homeassistant.components.knx.const import (
|
||||||
CONF_KNX_AUTOMATIC,
|
CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_CONNECTION_TYPE,
|
CONF_KNX_CONNECTION_TYPE,
|
||||||
|
CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS,
|
||||||
|
CONF_KNX_MCAST_GRP,
|
||||||
|
CONF_KNX_MCAST_PORT,
|
||||||
|
CONF_KNX_RATE_LIMIT,
|
||||||
|
CONF_KNX_STATE_UPDATER,
|
||||||
DOMAIN as KNX_DOMAIN,
|
DOMAIN as KNX_DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -208,10 +213,12 @@ def mock_config_entry() -> MockConfigEntry:
|
||||||
title="KNX",
|
title="KNX",
|
||||||
domain=KNX_DOMAIN,
|
domain=KNX_DOMAIN,
|
||||||
data={
|
data={
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
|
CONF_KNX_RATE_LIMIT: CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_STATE_UPDATER: CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
|
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||||
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
|
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from xknx import XKNX
|
|
||||||
from xknx.io import DEFAULT_MCAST_GRP
|
from xknx.io import DEFAULT_MCAST_GRP
|
||||||
from xknx.io.gateway_scanner import GatewayDescriptor
|
from xknx.io.gateway_scanner import GatewayDescriptor
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.knx import ConnectionSchema
|
|
||||||
from homeassistant.components.knx.config_flow import (
|
from homeassistant.components.knx.config_flow import (
|
||||||
CONF_DEFAULT_LOCAL_IP,
|
CONF_DEFAULT_LOCAL_IP,
|
||||||
CONF_KNX_GATEWAY,
|
CONF_KNX_GATEWAY,
|
||||||
|
@ -22,7 +20,13 @@ from homeassistant.components.knx.const import (
|
||||||
CONF_KNX_AUTOMATIC,
|
CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_CONNECTION_TYPE,
|
CONF_KNX_CONNECTION_TYPE,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS,
|
||||||
|
CONF_KNX_LOCAL_IP,
|
||||||
|
CONF_KNX_MCAST_GRP,
|
||||||
|
CONF_KNX_MCAST_PORT,
|
||||||
|
CONF_KNX_RATE_LIMIT,
|
||||||
|
CONF_KNX_ROUTE_BACK,
|
||||||
CONF_KNX_ROUTING,
|
CONF_KNX_ROUTING,
|
||||||
|
CONF_KNX_STATE_UPDATER,
|
||||||
CONF_KNX_TUNNELING,
|
CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_TUNNELING_TCP,
|
CONF_KNX_TUNNELING_TCP,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
@ -89,8 +93,8 @@ async def test_routing_setup(hass: HomeAssistant) -> None:
|
||||||
result3 = await hass.config_entries.flow.async_configure(
|
result3 = await hass.config_entries.flow.async_configure(
|
||||||
result2["flow_id"],
|
result2["flow_id"],
|
||||||
{
|
{
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -100,9 +104,9 @@ async def test_routing_setup(hass: HomeAssistant) -> None:
|
||||||
assert result3["data"] == {
|
assert result3["data"] == {
|
||||||
**DEFAULT_ENTRY_DATA,
|
**DEFAULT_ENTRY_DATA,
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +145,10 @@ async def test_routing_setup_advanced(hass: HomeAssistant) -> None:
|
||||||
result3 = await hass.config_entries.flow.async_configure(
|
result3 = await hass.config_entries.flow.async_configure(
|
||||||
result2["flow_id"],
|
result2["flow_id"],
|
||||||
{
|
{
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
@ -153,9 +157,9 @@ async def test_routing_setup_advanced(hass: HomeAssistant) -> None:
|
||||||
assert result3["data"] == {
|
assert result3["data"] == {
|
||||||
**DEFAULT_ENTRY_DATA,
|
**DEFAULT_ENTRY_DATA,
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "1.1.110",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +181,8 @@ async def test_routing_setup_advanced(hass: HomeAssistant) -> None:
|
||||||
CONF_HOST: "192.168.0.1",
|
CONF_HOST: "192.168.0.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -193,8 +197,8 @@ async def test_routing_setup_advanced(hass: HomeAssistant) -> None:
|
||||||
CONF_HOST: "192.168.0.1",
|
CONF_HOST: "192.168.0.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -209,8 +213,8 @@ async def test_routing_setup_advanced(hass: HomeAssistant) -> None:
|
||||||
CONF_HOST: "192.168.0.1",
|
CONF_HOST: "192.168.0.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: True,
|
CONF_KNX_ROUTE_BACK: True,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -291,7 +295,7 @@ async def test_tunneling_setup_for_local_ip(hass: HomeAssistant) -> None:
|
||||||
CONF_KNX_TUNNELING_TYPE: CONF_KNX_LABEL_TUNNELING_UDP,
|
CONF_KNX_TUNNELING_TYPE: CONF_KNX_LABEL_TUNNELING_UDP,
|
||||||
CONF_HOST: "192.168.0.2",
|
CONF_HOST: "192.168.0.2",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
@ -303,8 +307,8 @@ async def test_tunneling_setup_for_local_ip(hass: HomeAssistant) -> None:
|
||||||
CONF_HOST: "192.168.0.2",
|
CONF_HOST: "192.168.0.2",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
}
|
}
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
@ -361,8 +365,8 @@ async def test_tunneling_setup_for_multiple_found_gateways(hass: HomeAssistant)
|
||||||
CONF_HOST: "192.168.0.1",
|
CONF_HOST: "192.168.0.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
@ -422,191 +426,6 @@ async def test_form_with_automatic_connection_handling(hass: HomeAssistant) -> N
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Import Tests
|
|
||||||
##
|
|
||||||
async def test_import_config_tunneling(hass: HomeAssistant) -> None:
|
|
||||||
"""Test tunneling import from config.yaml."""
|
|
||||||
config = {
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True, # has a default in the original config
|
|
||||||
CONF_KNX_TUNNELING: {
|
|
||||||
CONF_HOST: "192.168.1.1",
|
|
||||||
CONF_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: True,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.knx.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == "Tunneling @ 192.168.1.1"
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
|
||||||
CONF_HOST: "192.168.1.1",
|
|
||||||
CONF_PORT: 3675,
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: True,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_config_routing(hass: HomeAssistant) -> None:
|
|
||||||
"""Test routing import from config.yaml."""
|
|
||||||
config = {
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True, # has a default in the original config
|
|
||||||
CONF_KNX_ROUTING: {}, # is required when using routing
|
|
||||||
}
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.knx.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == CONF_KNX_ROUTING.capitalize()
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_config_automatic(hass: HomeAssistant) -> None:
|
|
||||||
"""Test automatic import from config.yaml."""
|
|
||||||
config = {
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True, # has a default in the original config
|
|
||||||
}
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.knx.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == CONF_KNX_AUTOMATIC.capitalize()
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_rate_limit_out_of_range(hass: HomeAssistant) -> None:
|
|
||||||
"""Test automatic import from config.yaml."""
|
|
||||||
config = {
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 80,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True, # has a default in the original config
|
|
||||||
}
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.knx.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == CONF_KNX_AUTOMATIC.capitalize()
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 60,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_options(hass: HomeAssistant) -> None:
|
|
||||||
"""Test import from config.yaml with options."""
|
|
||||||
config = {
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675, # has a default in the original config
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 30,
|
|
||||||
}
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.knx.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
) as mock_setup_entry:
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == CONF_KNX_AUTOMATIC.capitalize()
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 30,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
|
|
||||||
async def test_abort_if_entry_exists_already(hass: HomeAssistant) -> None:
|
|
||||||
"""Test routing import from config.yaml."""
|
|
||||||
MockConfigEntry(domain=DOMAIN).add_to_hass(hass)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}
|
|
||||||
)
|
|
||||||
assert result["type"] == "abort"
|
|
||||||
assert result["reason"] == "single_instance_allowed"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow(
|
async def test_options_flow(
|
||||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -629,8 +448,8 @@ async def test_options_flow(
|
||||||
user_input={
|
user_input={
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -642,11 +461,11 @@ async def test_options_flow(
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
CONF_HOST: "",
|
CONF_HOST: "",
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
CONF_KNX_RATE_LIMIT: 20,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
CONF_KNX_STATE_UPDATER: True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -662,14 +481,14 @@ async def test_options_flow(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
CONF_KNX_RATE_LIMIT: 20,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
CONF_KNX_STATE_UPDATER: True,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
CONF_HOST: "192.168.1.1",
|
CONF_HOST: "192.168.1.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: True,
|
CONF_KNX_ROUTE_BACK: True,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -681,14 +500,14 @@ async def test_options_flow(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
CONF_KNX_RATE_LIMIT: 20,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
CONF_KNX_STATE_UPDATER: True,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
CONF_HOST: "192.168.1.1",
|
CONF_HOST: "192.168.1.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -700,14 +519,14 @@ async def test_options_flow(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING_TCP,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING_TCP,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 20,
|
CONF_KNX_RATE_LIMIT: 20,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: True,
|
CONF_KNX_STATE_UPDATER: True,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
CONF_HOST: "192.168.1.1",
|
CONF_HOST: "192.168.1.1",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -737,8 +556,8 @@ async def test_tunneling_options_flow(
|
||||||
user_input={
|
user_input={
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.255",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -765,42 +584,42 @@ async def test_tunneling_options_flow(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 25,
|
CONF_KNX_RATE_LIMIT: 25,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
CONF_KNX_STATE_UPDATER: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
CONF_HOST: "",
|
CONF_HOST: "",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 25,
|
CONF_KNX_RATE_LIMIT: 25,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
CONF_KNX_STATE_UPDATER: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 25,
|
CONF_KNX_RATE_LIMIT: 25,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
CONF_KNX_STATE_UPDATER: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: CONF_DEFAULT_LOCAL_IP,
|
CONF_KNX_LOCAL_IP: CONF_DEFAULT_LOCAL_IP,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
CONF_KNX_INDIVIDUAL_ADDRESS: "15.15.250",
|
||||||
CONF_HOST: "",
|
CONF_HOST: "",
|
||||||
ConnectionSchema.CONF_KNX_MCAST_PORT: 3675,
|
CONF_KNX_MCAST_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
ConnectionSchema.CONF_KNX_RATE_LIMIT: 25,
|
CONF_KNX_RATE_LIMIT: 25,
|
||||||
ConnectionSchema.CONF_KNX_STATE_UPDATER: False,
|
CONF_KNX_STATE_UPDATER: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: None,
|
CONF_KNX_LOCAL_IP: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -843,21 +662,21 @@ async def test_advanced_options(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
},
|
},
|
||||||
CONF_KNX_LABEL_TUNNELING_UDP,
|
CONF_KNX_LABEL_TUNNELING_UDP,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: True,
|
CONF_KNX_ROUTE_BACK: True,
|
||||||
},
|
},
|
||||||
CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK,
|
CONF_KNX_LABEL_TUNNELING_UDP_ROUTE_BACK,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING_TCP,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING_TCP,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
},
|
},
|
||||||
CONF_KNX_LABEL_TUNNELING_TCP,
|
CONF_KNX_LABEL_TUNNELING_TCP,
|
||||||
),
|
),
|
||||||
|
|
|
@ -30,6 +30,8 @@ async def test_diagnostics(
|
||||||
"individual_address": "15.15.250",
|
"individual_address": "15.15.250",
|
||||||
"multicast_group": "224.0.23.12",
|
"multicast_group": "224.0.23.12",
|
||||||
"multicast_port": 3671,
|
"multicast_port": 3671,
|
||||||
|
"rate_limit": 20,
|
||||||
|
"state_updater": True,
|
||||||
},
|
},
|
||||||
"configuration_error": None,
|
"configuration_error": None,
|
||||||
"configuration_yaml": None,
|
"configuration_yaml": None,
|
||||||
|
@ -60,6 +62,8 @@ async def test_diagnostic_config_error(
|
||||||
"individual_address": "15.15.250",
|
"individual_address": "15.15.250",
|
||||||
"multicast_group": "224.0.23.12",
|
"multicast_group": "224.0.23.12",
|
||||||
"multicast_port": 3671,
|
"multicast_port": 3671,
|
||||||
|
"rate_limit": 20,
|
||||||
|
"state_updater": True,
|
||||||
},
|
},
|
||||||
"configuration_error": "extra keys not allowed @ data['knx']['wrong_key']",
|
"configuration_error": "extra keys not allowed @ data['knx']['wrong_key']",
|
||||||
"configuration_yaml": {"wrong_key": {}},
|
"configuration_yaml": {"wrong_key": {}},
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
"""Test KNX events."""
|
"""Test KNX events."""
|
||||||
|
|
||||||
from homeassistant.components.knx import (
|
from homeassistant.components.knx import CONF_EVENT, CONF_TYPE, KNX_ADDRESS
|
||||||
CONF_EVENT,
|
|
||||||
CONF_KNX_EVENT_FILTER,
|
|
||||||
CONF_TYPE,
|
|
||||||
KNX_ADDRESS,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .conftest import KNXTestKit
|
from .conftest import KNXTestKit
|
||||||
|
@ -25,7 +20,6 @@ async def test_knx_event(hass: HomeAssistant, knx: KNXTestKit):
|
||||||
test_address_c_1 = "2/6/4"
|
test_address_c_1 = "2/6/4"
|
||||||
test_address_c_2 = "2/6/5"
|
test_address_c_2 = "2/6/5"
|
||||||
test_address_d = "5/4/3"
|
test_address_d = "5/4/3"
|
||||||
test_address_e = "6/4/3"
|
|
||||||
events = async_capture_events(hass, "knx_event")
|
events = async_capture_events(hass, "knx_event")
|
||||||
|
|
||||||
async def test_event_data(address, payload, value=None):
|
async def test_event_data(address, payload, value=None):
|
||||||
|
@ -63,8 +57,6 @@ async def test_knx_event(hass: HomeAssistant, knx: KNXTestKit):
|
||||||
KNX_ADDRESS: [test_address_d],
|
KNX_ADDRESS: [test_address_d],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
# test legacy `event_filter` config
|
|
||||||
CONF_KNX_EVENT_FILTER: [test_address_e],
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -97,10 +89,6 @@ async def test_knx_event(hass: HomeAssistant, knx: KNXTestKit):
|
||||||
await knx.receive_write(test_address_d, True)
|
await knx.receive_write(test_address_d, True)
|
||||||
await test_event_data(test_address_d, True)
|
await test_event_data(test_address_d, True)
|
||||||
|
|
||||||
# test legacy `event_filter` config
|
|
||||||
await knx.receive_write(test_address_e, (89, 43, 34, 11))
|
|
||||||
await test_event_data(test_address_e, (89, 43, 34, 11))
|
|
||||||
|
|
||||||
# receive telegrams for group addresses not matching any filter
|
# receive telegrams for group addresses not matching any filter
|
||||||
await knx.receive_write("0/5/0", True)
|
await knx.receive_write("0/5/0", True)
|
||||||
await knx.receive_write("1/7/0", True)
|
await knx.receive_write("1/7/0", True)
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
"""Test KNX init."""
|
"""Test KNX init."""
|
||||||
import pytest
|
import pytest
|
||||||
from xknx import XKNX
|
from xknx import XKNX
|
||||||
from xknx.io import ConnectionConfig, ConnectionType
|
from xknx.io import (
|
||||||
|
DEFAULT_MCAST_GRP,
|
||||||
|
DEFAULT_MCAST_PORT,
|
||||||
|
ConnectionConfig,
|
||||||
|
ConnectionType,
|
||||||
|
)
|
||||||
|
|
||||||
from homeassistant.components.knx.const import (
|
from homeassistant.components.knx.const import (
|
||||||
CONF_KNX_AUTOMATIC,
|
CONF_KNX_AUTOMATIC,
|
||||||
CONF_KNX_CONNECTION_TYPE,
|
CONF_KNX_CONNECTION_TYPE,
|
||||||
|
CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS,
|
CONF_KNX_INDIVIDUAL_ADDRESS,
|
||||||
|
CONF_KNX_LOCAL_IP,
|
||||||
|
CONF_KNX_MCAST_GRP,
|
||||||
|
CONF_KNX_MCAST_PORT,
|
||||||
|
CONF_KNX_RATE_LIMIT,
|
||||||
|
CONF_KNX_ROUTE_BACK,
|
||||||
CONF_KNX_ROUTING,
|
CONF_KNX_ROUTING,
|
||||||
|
CONF_KNX_STATE_UPDATER,
|
||||||
CONF_KNX_TUNNELING,
|
CONF_KNX_TUNNELING,
|
||||||
DOMAIN as KNX_DOMAIN,
|
DOMAIN as KNX_DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.components.knx.schema import ConnectionSchema
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
@ -25,15 +37,24 @@ from tests.common import MockConfigEntry
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||||
|
CONF_KNX_RATE_LIMIT: CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_STATE_UPDATER: CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
|
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||||
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
|
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
||||||
},
|
},
|
||||||
ConnectionConfig(threaded=True),
|
ConnectionConfig(threaded=True),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_ROUTING,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.1",
|
CONF_KNX_LOCAL_IP: "192.168.1.1",
|
||||||
|
CONF_KNX_RATE_LIMIT: CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_STATE_UPDATER: CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
|
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||||
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
|
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
||||||
},
|
},
|
||||||
ConnectionConfig(
|
ConnectionConfig(
|
||||||
connection_type=ConnectionType.ROUTING,
|
connection_type=ConnectionType.ROUTING,
|
||||||
|
@ -46,8 +67,13 @@ from tests.common import MockConfigEntry
|
||||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
CONF_KNX_CONNECTION_TYPE: CONF_KNX_TUNNELING,
|
||||||
CONF_HOST: "192.168.0.2",
|
CONF_HOST: "192.168.0.2",
|
||||||
CONF_PORT: 3675,
|
CONF_PORT: 3675,
|
||||||
ConnectionSchema.CONF_KNX_ROUTE_BACK: False,
|
CONF_KNX_ROUTE_BACK: False,
|
||||||
ConnectionSchema.CONF_KNX_LOCAL_IP: "192.168.1.112",
|
CONF_KNX_LOCAL_IP: "192.168.1.112",
|
||||||
|
CONF_KNX_RATE_LIMIT: CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||||
|
CONF_KNX_STATE_UPDATER: CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||||
|
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||||
|
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||||
|
CONF_KNX_INDIVIDUAL_ADDRESS: XKNX.DEFAULT_ADDRESS,
|
||||||
},
|
},
|
||||||
ConnectionConfig(
|
ConnectionConfig(
|
||||||
connection_type=ConnectionType.TUNNELING,
|
connection_type=ConnectionType.TUNNELING,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue