Netgear try all ports (#64170)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>pull/64374/head
parent
88261c6c14
commit
37caa22a36
|
@ -1,6 +1,8 @@
|
|||
"""Support for Netgear routers."""
|
||||
import logging
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
@ -9,6 +11,8 @@ from .const import DOMAIN, PLATFORMS
|
|||
from .errors import CannotLoginException
|
||||
from .router import NetgearRouter
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Netgear component."""
|
||||
|
@ -18,6 +22,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
except CannotLoginException as ex:
|
||||
raise ConfigEntryNotReady from ex
|
||||
|
||||
port = entry.data.get(CONF_PORT)
|
||||
ssl = entry.data.get(CONF_SSL)
|
||||
if port != router.port or ssl != router.ssl:
|
||||
data = entry.data.copy()
|
||||
data[CONF_PORT] = router.port
|
||||
data[CONF_SSL] = router.ssl
|
||||
hass.config_entries.async_update_entry(entry, data=data)
|
||||
_LOGGER.info(
|
||||
"Netgear port-SSL combination updated from (%i, %r) to (%i, %r), this should only occur after a firmware update",
|
||||
port,
|
||||
ssl,
|
||||
router.port,
|
||||
router.ssl,
|
||||
)
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
hass.data[DOMAIN][entry.unique_id] = router
|
||||
|
||||
|
|
|
@ -38,11 +38,7 @@ def _discovery_schema_with_defaults(discovery_info):
|
|||
|
||||
|
||||
def _user_schema_with_defaults(user_input):
|
||||
user_schema = {
|
||||
vol.Optional(CONF_HOST, default=user_input.get(CONF_HOST, "")): str,
|
||||
vol.Optional(CONF_PORT, default=user_input.get(CONF_PORT, DEFAULT_PORT)): int,
|
||||
vol.Optional(CONF_SSL, default=user_input.get(CONF_SSL, False)): bool,
|
||||
}
|
||||
user_schema = {vol.Optional(CONF_HOST, default=user_input.get(CONF_HOST, "")): str}
|
||||
user_schema.update(_ordered_shared_schema(user_input))
|
||||
|
||||
return vol.Schema(user_schema)
|
||||
|
@ -169,8 +165,8 @@ class NetgearFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return await self._show_setup_form()
|
||||
|
||||
host = user_input.get(CONF_HOST, self.placeholders[CONF_HOST])
|
||||
port = user_input.get(CONF_PORT, self.placeholders[CONF_PORT])
|
||||
ssl = user_input.get(CONF_SSL, self.placeholders[CONF_SSL])
|
||||
port = self.placeholders[CONF_PORT]
|
||||
ssl = self.placeholders[CONF_SSL]
|
||||
username = user_input.get(CONF_USERNAME, self.placeholders[CONF_USERNAME])
|
||||
password = user_input[CONF_PASSWORD]
|
||||
if not username:
|
||||
|
@ -196,8 +192,8 @@ class NetgearFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
CONF_USERNAME: username,
|
||||
CONF_PASSWORD: password,
|
||||
CONF_HOST: host,
|
||||
CONF_PORT: port,
|
||||
CONF_SSL: ssl,
|
||||
CONF_PORT: api.port,
|
||||
CONF_SSL: api.ssl,
|
||||
}
|
||||
|
||||
if info.get("ModelName") is not None and info.get("DeviceName") is not None:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"domain": "netgear",
|
||||
"name": "NETGEAR",
|
||||
"documentation": "https://www.home-assistant.io/integrations/netgear",
|
||||
"requirements": ["pynetgear==0.8.0"],
|
||||
"requirements": ["pynetgear==0.9.0"],
|
||||
"codeowners": ["@hacf-fr", "@Quentame", "@starkillerOG"],
|
||||
"iot_class": "local_polling",
|
||||
"config_flow": true,
|
||||
|
|
|
@ -52,7 +52,7 @@ def get_api(
|
|||
"""Get the Netgear API and login to it."""
|
||||
api: Netgear = Netgear(password, host, username, port, ssl)
|
||||
|
||||
if not api.login():
|
||||
if not api.login_try_port():
|
||||
raise CannotLoginException
|
||||
|
||||
return api
|
||||
|
@ -244,6 +244,16 @@ class NetgearRouter:
|
|||
"""Event specific per Netgear entry to signal updates in devices."""
|
||||
return f"{DOMAIN}-{self._host}-device-update"
|
||||
|
||||
@property
|
||||
def port(self) -> int:
|
||||
"""Port used by the API."""
|
||||
return self._api.port
|
||||
|
||||
@property
|
||||
def ssl(self) -> bool:
|
||||
"""SSL used by the API."""
|
||||
return self._api.ssl
|
||||
|
||||
|
||||
class NetgearDeviceEntity(Entity):
|
||||
"""Base class for a device connected to a Netgear router."""
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
"description": "Default host: {host}\nDefault port: {port}\nDefault username: {username}",
|
||||
"data": {
|
||||
"host": "[%key:common::config_flow::data::host%] (Optional)",
|
||||
"port": "[%key:common::config_flow::data::port%] (Optional)",
|
||||
"ssl": "[%key:common::config_flow::data::ssl%]",
|
||||
"username": "[%key:common::config_flow::data::username%] (Optional)",
|
||||
"password": "[%key:common::config_flow::data::password%]"
|
||||
}
|
||||
|
|
|
@ -1690,7 +1690,7 @@ pymyq==3.1.4
|
|||
pymysensors==0.22.1
|
||||
|
||||
# homeassistant.components.netgear
|
||||
pynetgear==0.8.0
|
||||
pynetgear==0.9.0
|
||||
|
||||
# homeassistant.components.netio
|
||||
pynetio==0.1.9.1
|
||||
|
|
|
@ -1059,7 +1059,7 @@ pymyq==3.1.4
|
|||
pymysensors==0.22.1
|
||||
|
||||
# homeassistant.components.netgear
|
||||
pynetgear==0.8.0
|
||||
pynetgear==0.9.0
|
||||
|
||||
# homeassistant.components.nina
|
||||
pynina==0.1.4
|
||||
|
|
|
@ -69,6 +69,20 @@ def mock_controller_service():
|
|||
"homeassistant.components.netgear.async_setup_entry", return_value=True
|
||||
), patch("homeassistant.components.netgear.router.Netgear") as service_mock:
|
||||
service_mock.return_value.get_info = Mock(return_value=ROUTER_INFOS)
|
||||
service_mock.return_value.port = 80
|
||||
service_mock.return_value.ssl = False
|
||||
yield service_mock
|
||||
|
||||
|
||||
@pytest.fixture(name="service_5555")
|
||||
def mock_controller_service_5555():
|
||||
"""Mock a successful service."""
|
||||
with patch(
|
||||
"homeassistant.components.netgear.async_setup_entry", return_value=True
|
||||
), patch("homeassistant.components.netgear.router.Netgear") as service_mock:
|
||||
service_mock.return_value.get_info = Mock(return_value=ROUTER_INFOS)
|
||||
service_mock.return_value.port = 5555
|
||||
service_mock.return_value.ssl = True
|
||||
yield service_mock
|
||||
|
||||
|
||||
|
@ -81,6 +95,8 @@ def mock_controller_service_incomplete():
|
|||
"homeassistant.components.netgear.async_setup_entry", return_value=True
|
||||
), patch("homeassistant.components.netgear.router.Netgear") as service_mock:
|
||||
service_mock.return_value.get_info = Mock(return_value=router_infos)
|
||||
service_mock.return_value.port = 80
|
||||
service_mock.return_value.ssl = False
|
||||
yield service_mock
|
||||
|
||||
|
||||
|
@ -88,7 +104,7 @@ def mock_controller_service_incomplete():
|
|||
def mock_controller_service_failed():
|
||||
"""Mock a failed service."""
|
||||
with patch("homeassistant.components.netgear.router.Netgear") as service_mock:
|
||||
service_mock.return_value.login = Mock(return_value=None)
|
||||
service_mock.return_value.login_try_port = Mock(return_value=None)
|
||||
service_mock.return_value.get_info = Mock(return_value=None)
|
||||
yield service_mock
|
||||
|
||||
|
@ -106,8 +122,6 @@ async def test_user(hass, service):
|
|||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: HOST,
|
||||
CONF_PORT: PORT,
|
||||
CONF_SSL: SSL,
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
},
|
||||
|
@ -135,8 +149,6 @@ async def test_user_connect_error(hass, service_failed):
|
|||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: HOST,
|
||||
CONF_PORT: PORT,
|
||||
CONF_SSL: SSL,
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
},
|
||||
|
@ -159,8 +171,6 @@ async def test_user_incomplete_info(hass, service_incomplete):
|
|||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: HOST,
|
||||
CONF_PORT: PORT,
|
||||
CONF_SSL: SSL,
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
},
|
||||
|
@ -256,7 +266,7 @@ async def test_ssdp(hass, service):
|
|||
assert result["data"][CONF_PASSWORD] == PASSWORD
|
||||
|
||||
|
||||
async def test_ssdp_port_5555(hass, service):
|
||||
async def test_ssdp_port_5555(hass, service_5555):
|
||||
"""Test ssdp step with port 5555."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
|
|
Loading…
Reference in New Issue