Skip to content
13 changes: 11 additions & 2 deletions homeassistant/components/plugwise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import voluptuous as vol

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_SCAN_INTERVAL
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
Expand All @@ -21,7 +21,13 @@
UpdateFailed,
)

from .const import COORDINATOR, DEFAULT_SCAN_INTERVAL, DOMAIN, UNDO_UPDATE_LISTENER
from .const import (
COORDINATOR,
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
UNDO_UPDATE_LISTENER,
)

CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)

Expand All @@ -39,9 +45,12 @@ async def async_setup(hass: HomeAssistant, config: dict):
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Plugwise Smiles from a config entry."""
websession = async_get_clientsession(hass, verify_ssl=False)

api = Smile(
host=entry.data[CONF_HOST],
password=entry.data[CONF_PASSWORD],
port=entry.data.get(CONF_PORT, DEFAULT_PORT),
timeout=30,
websession=websession,
)

Expand Down
13 changes: 11 additions & 2 deletions homeassistant/components/plugwise/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import voluptuous as vol

from homeassistant import config_entries, core, exceptions
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_SCAN_INTERVAL
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_SCAN_INTERVAL
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.typing import DiscoveryInfoType

from .const import DEFAULT_SCAN_INTERVAL, DOMAIN # pylint:disable=unused-import
from .const import ( # pylint:disable=unused-import
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
)

_LOGGER = logging.getLogger(__name__)

Expand All @@ -27,6 +31,7 @@ def _base_schema(discovery_info):

if not discovery_info:
base_schema[vol.Required(CONF_HOST)] = str
base_schema[vol.Optional(CONF_PORT, default=DEFAULT_PORT)] = int

base_schema[vol.Required(CONF_PASSWORD)] = str

Expand All @@ -40,9 +45,11 @@ async def validate_input(hass: core.HomeAssistant, data):
Data has the keys from _base_schema() with values provided by the user.
"""
websession = async_get_clientsession(hass, verify_ssl=False)

api = Smile(
host=data[CONF_HOST],
password=data[CONF_PASSWORD],
port=data[CONF_PORT],
timeout=30,
websession=websession,
)
Expand Down Expand Up @@ -83,6 +90,7 @@ async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["title_placeholders"] = {
CONF_HOST: discovery_info[CONF_HOST],
CONF_PORT: discovery_info.get(CONF_PORT, DEFAULT_PORT),
"name": _name,
}
return await self.async_step_user()
Expand All @@ -95,6 +103,7 @@ async def async_step_user(self, user_input=None):

if self.discovery_info:
user_input[CONF_HOST] = self.discovery_info[CONF_HOST]
user_input[CONF_PORT] = self.discovery_info.get(CONF_PORT, DEFAULT_PORT)

for entry in self._async_current_entries():
if entry.data.get(CONF_HOST) == user_input[CONF_HOST]:
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/plugwise/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
"step": {
"user": {
"title": "Connect to the Smile",
"description": "Details",
"description": "Please enter:",
"data": {
"password": "Smile ID",
"host": "Smile IP address",
"password": "Smile ID"
"port": "Smile port number"
}
}
},
Expand Down
29 changes: 28 additions & 1 deletion tests/components/plugwise/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import pytest

from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components.plugwise.const import DEFAULT_SCAN_INTERVAL, DOMAIN
from homeassistant.components.plugwise.const import (
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_SCAN_INTERVAL

Expand All @@ -13,8 +17,11 @@
TEST_HOST = "1.1.1.1"
TEST_HOSTNAME = "smileabcdef"
TEST_PASSWORD = "test_password"
TEST_PORT = 81

TEST_DISCOVERY = {
"host": TEST_HOST,
"port": DEFAULT_PORT,
"hostname": f"{TEST_HOSTNAME}.local.",
"server": f"{TEST_HOSTNAME}.local.",
"properties": {
Expand Down Expand Up @@ -68,6 +75,7 @@ async def test_form(hass):
assert result2["data"] == {
"host": TEST_HOST,
"password": TEST_PASSWORD,
"port": DEFAULT_PORT,
}

assert len(mock_setup.mock_calls) == 1
Expand Down Expand Up @@ -106,6 +114,7 @@ async def test_zeroconf_form(hass):
assert result2["data"] == {
"host": TEST_HOST,
"password": TEST_PASSWORD,
"port": DEFAULT_PORT,
}

assert len(mock_setup.mock_calls) == 1
Expand Down Expand Up @@ -176,6 +185,24 @@ async def test_form_cannot_connect(hass, mock_smile):
assert result2["errors"] == {"base": "cannot_connect"}


async def test_form_cannot_connect_port(hass, mock_smile):
"""Test we handle cannot connect to port error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)

mock_smile.connect.side_effect = Smile.ConnectionFailedError
mock_smile.gateway_id = "0a636a4fc1704ab4a24e4f7e37fb187a"

result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": TEST_HOST, "password": TEST_PASSWORD, "port": TEST_PORT},
)

assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result2["errors"] == {"base": "cannot_connect"}


async def test_form_other_problem(hass, mock_smile):
"""Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init(
Expand Down