mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 07:25:52 -05:00
Add new integration to control Electra Smart HVAC devices (#70361)
* Added new integration to support Electra Smart (HVAC) * fixes + option to set scan interval * renamed the module to electrasmart and added unittests * added non tested files to .coveragerc * changed the usage from UpdateCoordinator to each entity updates it self * small fixes * increased pypi package version, increased polling timeout to 60 seconds, improved error handling * PARALLEL_UPDATE=1 to prevent multi access to the API * code improvements * aligned with the new HA APIs * fixes * fixes * more * fixes * more * more * handled re-atuh flow * fixed test * removed hvac action * added shabat mode * tests: 100% coverage * ran hassfest * Update homeassistant/components/electrasmart/manifest.json Co-authored-by: Shay Levy <levyshay1@gmail.com> * Update homeassistant/components/electrasmart/manifest.json Co-authored-by: Shay Levy <levyshay1@gmail.com> * Update homeassistant/components/electrasmart/manifest.json Co-authored-by: Shay Levy <levyshay1@gmail.com> * Update homeassistant/components/electrasmart/climate.py Co-authored-by: Shay Levy <levyshay1@gmail.com> * address Shay's comments * address Shay's comments * address more comments --------- Co-authored-by: Shay Levy <levyshay1@gmail.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Tests for the Electra Air Conditioner integration."""
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": 99,
|
||||
"status": 0,
|
||||
"desc": "None",
|
||||
"data": { "res": 0, "res_desc": "None" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": 99,
|
||||
"status": 1,
|
||||
"desc": "None",
|
||||
"data": { "res": 100, "res_desc": "None" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": 99,
|
||||
"status": 0,
|
||||
"desc": "None",
|
||||
"data": { "res": 100, "res_desc": "None" }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": 99,
|
||||
"status": 0,
|
||||
"desc": "None",
|
||||
"data": {
|
||||
"token": "ec7a0db6c1f148ca8c0f48aabb5f8150",
|
||||
"sid": "bd6f11f947244e5d9612eba89e91112b",
|
||||
"res": 0,
|
||||
"res_desc": "None"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
"""Test the Electra Smart config flow."""
|
||||
from json import loads
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.electrasmart.config_flow import ElectraApiError
|
||||
from homeassistant.components.electrasmart.const import (
|
||||
CONF_OTP,
|
||||
CONF_PHONE_NUMBER,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import load_fixture
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant):
|
||||
"""Test user config."""
|
||||
|
||||
mock_generate_token = loads(load_fixture("generate_token_response.json", DOMAIN))
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
return_value=mock_generate_token,
|
||||
):
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data=None,
|
||||
)
|
||||
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567"},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == CONF_OTP
|
||||
|
||||
|
||||
async def test_one_time_password(hass: HomeAssistant):
|
||||
"""Test one time password."""
|
||||
|
||||
mock_generate_token = loads(load_fixture("generate_token_response.json", DOMAIN))
|
||||
mock_otp_response = loads(load_fixture("otp_response.json", DOMAIN))
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
return_value=mock_generate_token,
|
||||
), patch(
|
||||
"electrasmart.api.ElectraAPI.validate_one_time_password",
|
||||
return_value=mock_otp_response,
|
||||
), patch(
|
||||
"electrasmart.api.ElectraAPI.fetch_devices", return_value=[]
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567", CONF_OTP: "1234"},
|
||||
)
|
||||
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_OTP: "1234"}
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
|
||||
|
||||
async def test_one_time_password_api_error(hass: HomeAssistant):
|
||||
"""Test one time password."""
|
||||
mock_generate_token = loads(load_fixture("generate_token_response.json", DOMAIN))
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
return_value=mock_generate_token,
|
||||
), patch(
|
||||
"electrasmart.api.ElectraAPI.validate_one_time_password",
|
||||
side_effect=ElectraApiError,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_OTP: "1234"}
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
|
||||
|
||||
async def test_cannot_connect(hass: HomeAssistant):
|
||||
"""Test cannot connect."""
|
||||
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
side_effect=ElectraApiError,
|
||||
):
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
async def test_invalid_phone_number(hass: HomeAssistant):
|
||||
"""Test invalid phone number."""
|
||||
|
||||
mock_invalid_phone_number_response = loads(
|
||||
load_fixture("invalid_phone_number_response.json", DOMAIN)
|
||||
)
|
||||
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
return_value=mock_invalid_phone_number_response,
|
||||
):
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567"},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
assert result["errors"] == {"phone_number": "invalid_phone_number"}
|
||||
|
||||
|
||||
async def test_invalid_auth(hass: HomeAssistant):
|
||||
"""Test invalid auth."""
|
||||
|
||||
mock_generate_token_response = loads(
|
||||
load_fixture("generate_token_response.json", DOMAIN)
|
||||
)
|
||||
mock_invalid_otp_response = loads(load_fixture("invalid_otp_response.json", DOMAIN))
|
||||
|
||||
with patch(
|
||||
"electrasmart.api.ElectraAPI.generate_new_token",
|
||||
return_value=mock_generate_token_response,
|
||||
), patch(
|
||||
"electrasmart.api.ElectraAPI.validate_one_time_password",
|
||||
return_value=mock_invalid_otp_response,
|
||||
):
|
||||
# test with required
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data={CONF_PHONE_NUMBER: "0521234567", CONF_OTP: "1234"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_OTP: "1234"}
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == CONF_OTP
|
||||
assert result["errors"] == {CONF_OTP: "invalid_auth"}
|
||||
Reference in New Issue
Block a user