Skip to content

Commit

Permalink
Migrate bracketed IP addresses in ZHA config entry (#95917)
Browse files Browse the repository at this point in the history
* Automatically correct IP addresses surrounded by brackets

* Simplify regex

* Move pattern inline

* Maintain old behavior of stripping whitespace
  • Loading branch information
puddly authored Jul 6, 2023
1 parent 5964534 commit ecc0917
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
24 changes: 20 additions & 4 deletions homeassistant/components/zha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import copy
import logging
import os
import re

import voluptuous as vol
from zhaquirks import setup as setup_quirks
Expand Down Expand Up @@ -85,19 +86,34 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
return True


def _clean_serial_port_path(path: str) -> str:
"""Clean the serial port path, applying corrections where necessary."""

if path.startswith("socket://"):
path = path.strip()

# Removes extraneous brackets from IP addresses (they don't parse in CPython 3.11.4)
if re.match(r"^socket://\[\d+\.\d+\.\d+\.\d+\]:\d+$", path):
path = path.replace("[", "").replace("]", "")

return path


async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up ZHA.
Will automatically load components to support devices found on the network.
"""

# Strip whitespace around `socket://` URIs, this is no longer accepted by zigpy
# This will be removed in 2023.7.0
# Remove brackets around IP addresses, this no longer works in CPython 3.11.4
# This will be removed in 2023.11.0
path = config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
cleaned_path = _clean_serial_port_path(path)
data = copy.deepcopy(dict(config_entry.data))

if path.startswith("socket://") and path != path.strip():
data[CONF_DEVICE][CONF_DEVICE_PATH] = path.strip()
if path != cleaned_path:
_LOGGER.debug("Cleaned serial port path %r -> %r", path, cleaned_path)
data[CONF_DEVICE][CONF_DEVICE_PATH] = cleaned_path
hass.config_entries.async_update_entry(config_entry, data=data)

zha_data = hass.data.setdefault(DATA_ZHA, {})
Expand Down
12 changes: 10 additions & 2 deletions tests/components/zha/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,27 @@ async def test_config_depreciation(hass: HomeAssistant, zha_config) -> None:
@pytest.mark.parametrize(
("path", "cleaned_path"),
[
# No corrections
("/dev/path1", "/dev/path1"),
("/dev/path1[asd]", "/dev/path1[asd]"),
("/dev/path1 ", "/dev/path1 "),
("socket://1.2.3.4:5678", "socket://1.2.3.4:5678"),
# Brackets around URI
("socket://[1.2.3.4]:5678", "socket://1.2.3.4:5678"),
# Spaces
("socket://dev/path1 ", "socket://dev/path1"),
# Both
("socket://[1.2.3.4]:5678 ", "socket://1.2.3.4:5678"),
],
)
@patch("homeassistant.components.zha.setup_quirks", Mock(return_value=True))
@patch(
"homeassistant.components.zha.websocket_api.async_load_api", Mock(return_value=True)
)
async def test_setup_with_v3_spaces_in_uri(
async def test_setup_with_v3_cleaning_uri(
hass: HomeAssistant, path: str, cleaned_path: str
) -> None:
"""Test migration of config entry from v3 with spaces after `socket://` URI."""
"""Test migration of config entry from v3, applying corrections to the port path."""
config_entry_v3 = MockConfigEntry(
domain=DOMAIN,
data={
Expand Down

0 comments on commit ecc0917

Please sign in to comment.