Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion homeassistant/components/nexia/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from functools import partial
import logging

from nexia.const import BRAND_NEXIA
from nexia.home import NexiaHome
from requests.exceptions import ConnectTimeout, HTTPError

Expand All @@ -13,7 +14,7 @@
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from .const import DOMAIN, NEXIA_DEVICE, PLATFORMS, UPDATE_COORDINATOR
from .const import CONF_BRAND, DOMAIN, NEXIA_DEVICE, PLATFORMS, UPDATE_COORDINATOR
from .util import is_invalid_auth_code

_LOGGER = logging.getLogger(__name__)
Expand All @@ -29,6 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
conf = entry.data
username = conf[CONF_USERNAME]
password = conf[CONF_PASSWORD]
brand = conf.get(CONF_BRAND, BRAND_NEXIA)

state_file = hass.config.path(f"nexia_config_{username}.conf")

Expand All @@ -40,6 +42,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
password=password,
device_name=hass.config.location_name,
state_file=state_file,
brand=brand,
)
)
except ConnectTimeout as ex:
Expand Down
14 changes: 12 additions & 2 deletions homeassistant/components/nexia/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
"""Config flow for Nexia integration."""
import logging

from nexia.const import BRAND_ASAIR, BRAND_NEXIA
from nexia.home import NexiaHome
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol

from homeassistant import config_entries, core, exceptions
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME

from .const import DOMAIN
from .const import BRAND_ASAIR_NAME, BRAND_NEXIA_NAME, CONF_BRAND, DOMAIN
from .util import is_invalid_auth_code

_LOGGER = logging.getLogger(__name__)

DATA_SCHEMA = vol.Schema({CONF_USERNAME: str, CONF_PASSWORD: str})
DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_BRAND, default=BRAND_NEXIA): vol.In(
{BRAND_NEXIA: BRAND_NEXIA_NAME, BRAND_ASAIR: BRAND_ASAIR_NAME}
),
}
)


async def validate_input(hass: core.HomeAssistant, data):
Expand All @@ -27,6 +36,7 @@ async def validate_input(hass: core.HomeAssistant, data):
nexia_home = NexiaHome(
username=data[CONF_USERNAME],
password=data[CONF_PASSWORD],
brand=data[CONF_BRAND],
auto_login=False,
auto_update=False,
device_name=hass.config.location_name,
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/nexia/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
NOTIFICATION_ID = "nexia_notification"
NOTIFICATION_TITLE = "Nexia Setup"

CONF_BRAND = "brand"

NEXIA_DEVICE = "device"
NEXIA_SCAN_INTERVAL = "scan_interval"

Expand All @@ -29,3 +31,6 @@

SIGNAL_ZONE_UPDATE = "NEXIA_CLIMATE_ZONE_UPDATE"
SIGNAL_THERMOSTAT_UPDATE = "NEXIA_CLIMATE_THERMOSTAT_UPDATE"

BRAND_NEXIA_NAME = "Nexia"
BRAND_ASAIR_NAME = "American Standard"
4 changes: 2 additions & 2 deletions homeassistant/components/nexia/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"domain": "nexia",
"name": "Nexia",
"requirements": ["nexia==0.9.6"],
"name": "Nexia/American Standard",
"requirements": ["nexia==0.9.7"],
"codeowners": ["@bdraco"],
"documentation": "https://www.home-assistant.io/integrations/nexia",
"config_flow": true,
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/nexia/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"config": {
"step": {
"user": {
"title": "Connect to mynexia.com",
"data": {
"brand": "Brand",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
}
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/nexia/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"step": {
"user": {
"data": {
"brand": "Brand",
"password": "Password",
"username": "Username"
},
"title": "Connect to mynexia.com"
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ nettigo-air-monitor==0.2.5
neurio==0.3.1

# homeassistant.components.nexia
nexia==0.9.6
nexia==0.9.7

# homeassistant.components.nextcloud
nextcloudmonitor==1.1.0
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ netdisco==2.8.3
nettigo-air-monitor==0.2.5

# homeassistant.components.nexia
nexia==0.9.6
nexia==0.9.7

# homeassistant.components.notify_events
notify-events==1.0.4
Expand Down
40 changes: 32 additions & 8 deletions tests/components/nexia/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""Test the nexia config flow."""
from unittest.mock import MagicMock, patch

from nexia.const import BRAND_ASAIR, BRAND_NEXIA
import pytest
from requests.exceptions import ConnectTimeout, HTTPError

from homeassistant import config_entries, setup
from homeassistant.components.nexia.const import DOMAIN
from homeassistant.components.nexia.const import CONF_BRAND, DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME


async def test_form(hass):
@pytest.mark.parametrize("brand", [BRAND_ASAIR, BRAND_NEXIA])
async def test_form(hass, brand):
"""Test we get the form."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
Expand All @@ -29,13 +32,14 @@ async def test_form(hass):
) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{CONF_BRAND: brand, CONF_USERNAME: "username", CONF_PASSWORD: "password"},
)
await hass.async_block_till_done()

assert result2["type"] == "create_entry"
assert result2["title"] == "myhouse"
assert result2["data"] == {
CONF_BRAND: brand,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
}
Expand All @@ -51,7 +55,11 @@ async def test_form_invalid_auth(hass):
with patch("homeassistant.components.nexia.config_flow.NexiaHome.login"):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{
CONF_BRAND: BRAND_NEXIA,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
},
)

assert result2["type"] == "form"
Expand All @@ -70,7 +78,11 @@ async def test_form_cannot_connect(hass):
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{
CONF_BRAND: BRAND_NEXIA,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
},
)

assert result2["type"] == "form"
Expand All @@ -91,7 +103,11 @@ async def test_form_invalid_auth_http_401(hass):
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{
CONF_BRAND: BRAND_NEXIA,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
},
)

assert result2["type"] == "form"
Expand All @@ -112,7 +128,11 @@ async def test_form_cannot_connect_not_found(hass):
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{
CONF_BRAND: BRAND_NEXIA,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
},
)

assert result2["type"] == "form"
Expand All @@ -131,7 +151,11 @@ async def test_form_broad_exception(hass):
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
{
CONF_BRAND: BRAND_NEXIA,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
},
)

assert result2["type"] == "form"
Expand Down
7 changes: 4 additions & 3 deletions tests/components/nexia/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ async def async_init_integration(
house_fixture = "nexia/mobile_houses_123456.json"
session_fixture = "nexia/session_123456.json"
sign_in_fixture = "nexia/sign_in.json"
nexia = NexiaHome(auto_login=False)

with requests_mock.mock() as m, patch(
"nexia.home.load_or_create_uuid", return_value=uuid.uuid4()
):
m.post(NexiaHome.API_MOBILE_SESSION_URL, text=load_fixture(session_fixture))
m.post(nexia.API_MOBILE_SESSION_URL, text=load_fixture(session_fixture))
m.get(
NexiaHome.API_MOBILE_HOUSES_URL.format(house_id=123456),
nexia.API_MOBILE_HOUSES_URL.format(house_id=123456),
text=load_fixture(house_fixture),
)
m.post(
NexiaHome.API_MOBILE_ACCOUNTS_SIGN_IN_URL,
nexia.API_MOBILE_ACCOUNTS_SIGN_IN_URL,
text=load_fixture(sign_in_fixture),
)
entry = MockConfigEntry(
Expand Down