mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 18:27:09 +00:00
Add support for asair brand to nexia (#50504)
This commit is contained in:
parent
bdeeb54d2d
commit
8e38f26978
@ -3,6 +3,7 @@ from datetime import timedelta
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from nexia.const import BRAND_NEXIA
|
||||||
from nexia.home import NexiaHome
|
from nexia.home import NexiaHome
|
||||||
from requests.exceptions import ConnectTimeout, HTTPError
|
from requests.exceptions import ConnectTimeout, HTTPError
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
|
|||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
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
|
from .util import is_invalid_auth_code
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -29,6 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
conf = entry.data
|
conf = entry.data
|
||||||
username = conf[CONF_USERNAME]
|
username = conf[CONF_USERNAME]
|
||||||
password = conf[CONF_PASSWORD]
|
password = conf[CONF_PASSWORD]
|
||||||
|
brand = conf.get(CONF_BRAND, BRAND_NEXIA)
|
||||||
|
|
||||||
state_file = hass.config.path(f"nexia_config_{username}.conf")
|
state_file = hass.config.path(f"nexia_config_{username}.conf")
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
password=password,
|
password=password,
|
||||||
device_name=hass.config.location_name,
|
device_name=hass.config.location_name,
|
||||||
state_file=state_file,
|
state_file=state_file,
|
||||||
|
brand=brand,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except ConnectTimeout as ex:
|
except ConnectTimeout as ex:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Config flow for Nexia integration."""
|
"""Config flow for Nexia integration."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from nexia.const import BRAND_ASAIR, BRAND_NEXIA
|
||||||
from nexia.home import NexiaHome
|
from nexia.home import NexiaHome
|
||||||
from requests.exceptions import ConnectTimeout, HTTPError
|
from requests.exceptions import ConnectTimeout, HTTPError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@ -8,12 +9,20 @@ import voluptuous as vol
|
|||||||
from homeassistant import config_entries, core, exceptions
|
from homeassistant import config_entries, core, exceptions
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
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
|
from .util import is_invalid_auth_code
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_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):
|
async def validate_input(hass: core.HomeAssistant, data):
|
||||||
@ -27,6 +36,7 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
nexia_home = NexiaHome(
|
nexia_home = NexiaHome(
|
||||||
username=data[CONF_USERNAME],
|
username=data[CONF_USERNAME],
|
||||||
password=data[CONF_PASSWORD],
|
password=data[CONF_PASSWORD],
|
||||||
|
brand=data[CONF_BRAND],
|
||||||
auto_login=False,
|
auto_login=False,
|
||||||
auto_update=False,
|
auto_update=False,
|
||||||
device_name=hass.config.location_name,
|
device_name=hass.config.location_name,
|
||||||
|
@ -7,6 +7,8 @@ ATTRIBUTION = "Data provided by mynexia.com"
|
|||||||
NOTIFICATION_ID = "nexia_notification"
|
NOTIFICATION_ID = "nexia_notification"
|
||||||
NOTIFICATION_TITLE = "Nexia Setup"
|
NOTIFICATION_TITLE = "Nexia Setup"
|
||||||
|
|
||||||
|
CONF_BRAND = "brand"
|
||||||
|
|
||||||
NEXIA_DEVICE = "device"
|
NEXIA_DEVICE = "device"
|
||||||
NEXIA_SCAN_INTERVAL = "scan_interval"
|
NEXIA_SCAN_INTERVAL = "scan_interval"
|
||||||
|
|
||||||
@ -29,3 +31,6 @@ MANUFACTURER = "Trane"
|
|||||||
|
|
||||||
SIGNAL_ZONE_UPDATE = "NEXIA_CLIMATE_ZONE_UPDATE"
|
SIGNAL_ZONE_UPDATE = "NEXIA_CLIMATE_ZONE_UPDATE"
|
||||||
SIGNAL_THERMOSTAT_UPDATE = "NEXIA_CLIMATE_THERMOSTAT_UPDATE"
|
SIGNAL_THERMOSTAT_UPDATE = "NEXIA_CLIMATE_THERMOSTAT_UPDATE"
|
||||||
|
|
||||||
|
BRAND_NEXIA_NAME = "Nexia"
|
||||||
|
BRAND_ASAIR_NAME = "American Standard"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"domain": "nexia",
|
"domain": "nexia",
|
||||||
"name": "Nexia",
|
"name": "Nexia/American Standard",
|
||||||
"requirements": ["nexia==0.9.6"],
|
"requirements": ["nexia==0.9.7"],
|
||||||
"codeowners": ["@bdraco"],
|
"codeowners": ["@bdraco"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/nexia",
|
"documentation": "https://www.home-assistant.io/integrations/nexia",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Connect to mynexia.com",
|
|
||||||
"data": {
|
"data": {
|
||||||
|
"brand": "Brand",
|
||||||
"username": "[%key:common::config_flow::data::username%]",
|
"username": "[%key:common::config_flow::data::username%]",
|
||||||
"password": "[%key:common::config_flow::data::password%]"
|
"password": "[%key:common::config_flow::data::password%]"
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
|
"brand": "Brand",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"username": "Username"
|
"username": "Username"
|
||||||
},
|
}
|
||||||
"title": "Connect to mynexia.com"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1000,7 +1000,7 @@ nettigo-air-monitor==0.2.5
|
|||||||
neurio==0.3.1
|
neurio==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.nexia
|
# homeassistant.components.nexia
|
||||||
nexia==0.9.6
|
nexia==0.9.7
|
||||||
|
|
||||||
# homeassistant.components.nextcloud
|
# homeassistant.components.nextcloud
|
||||||
nextcloudmonitor==1.1.0
|
nextcloudmonitor==1.1.0
|
||||||
|
@ -551,7 +551,7 @@ netdisco==2.8.3
|
|||||||
nettigo-air-monitor==0.2.5
|
nettigo-air-monitor==0.2.5
|
||||||
|
|
||||||
# homeassistant.components.nexia
|
# homeassistant.components.nexia
|
||||||
nexia==0.9.6
|
nexia==0.9.7
|
||||||
|
|
||||||
# homeassistant.components.notify_events
|
# homeassistant.components.notify_events
|
||||||
notify-events==1.0.4
|
notify-events==1.0.4
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
"""Test the nexia config flow."""
|
"""Test the nexia config flow."""
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
from nexia.const import BRAND_ASAIR, BRAND_NEXIA
|
||||||
|
import pytest
|
||||||
from requests.exceptions import ConnectTimeout, HTTPError
|
from requests.exceptions import ConnectTimeout, HTTPError
|
||||||
|
|
||||||
from homeassistant import config_entries, setup
|
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
|
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."""
|
"""Test we get the form."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
@ -29,13 +32,14 @@ async def test_form(hass):
|
|||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{CONF_BRAND: brand, CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result2["type"] == "create_entry"
|
assert result2["type"] == "create_entry"
|
||||||
assert result2["title"] == "myhouse"
|
assert result2["title"] == "myhouse"
|
||||||
assert result2["data"] == {
|
assert result2["data"] == {
|
||||||
|
CONF_BRAND: brand,
|
||||||
CONF_USERNAME: "username",
|
CONF_USERNAME: "username",
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
}
|
}
|
||||||
@ -51,7 +55,11 @@ async def test_form_invalid_auth(hass):
|
|||||||
with patch("homeassistant.components.nexia.config_flow.NexiaHome.login"):
|
with patch("homeassistant.components.nexia.config_flow.NexiaHome.login"):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{
|
||||||
|
CONF_BRAND: BRAND_NEXIA,
|
||||||
|
CONF_USERNAME: "username",
|
||||||
|
CONF_PASSWORD: "password",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
@ -70,7 +78,11 @@ async def test_form_cannot_connect(hass):
|
|||||||
):
|
):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{
|
||||||
|
CONF_BRAND: BRAND_NEXIA,
|
||||||
|
CONF_USERNAME: "username",
|
||||||
|
CONF_PASSWORD: "password",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
@ -91,7 +103,11 @@ async def test_form_invalid_auth_http_401(hass):
|
|||||||
):
|
):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{
|
||||||
|
CONF_BRAND: BRAND_NEXIA,
|
||||||
|
CONF_USERNAME: "username",
|
||||||
|
CONF_PASSWORD: "password",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
@ -112,7 +128,11 @@ async def test_form_cannot_connect_not_found(hass):
|
|||||||
):
|
):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{
|
||||||
|
CONF_BRAND: BRAND_NEXIA,
|
||||||
|
CONF_USERNAME: "username",
|
||||||
|
CONF_PASSWORD: "password",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
@ -131,7 +151,11 @@ async def test_form_broad_exception(hass):
|
|||||||
):
|
):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_USERNAME: "username", CONF_PASSWORD: "password"},
|
{
|
||||||
|
CONF_BRAND: BRAND_NEXIA,
|
||||||
|
CONF_USERNAME: "username",
|
||||||
|
CONF_PASSWORD: "password",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
|
@ -21,17 +21,18 @@ async def async_init_integration(
|
|||||||
house_fixture = "nexia/mobile_houses_123456.json"
|
house_fixture = "nexia/mobile_houses_123456.json"
|
||||||
session_fixture = "nexia/session_123456.json"
|
session_fixture = "nexia/session_123456.json"
|
||||||
sign_in_fixture = "nexia/sign_in.json"
|
sign_in_fixture = "nexia/sign_in.json"
|
||||||
|
nexia = NexiaHome(auto_login=False)
|
||||||
|
|
||||||
with requests_mock.mock() as m, patch(
|
with requests_mock.mock() as m, patch(
|
||||||
"nexia.home.load_or_create_uuid", return_value=uuid.uuid4()
|
"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(
|
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),
|
text=load_fixture(house_fixture),
|
||||||
)
|
)
|
||||||
m.post(
|
m.post(
|
||||||
NexiaHome.API_MOBILE_ACCOUNTS_SIGN_IN_URL,
|
nexia.API_MOBILE_ACCOUNTS_SIGN_IN_URL,
|
||||||
text=load_fixture(sign_in_fixture),
|
text=load_fixture(sign_in_fixture),
|
||||||
)
|
)
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user