Add Growatt Server Config flow (#41303)
* Growatt Server Config flow * Use reference strings Co-authored-by: SNoof85 <snoof85@gmail.com> * Remove configuration.yaml import logic * Removed import test * Re-added PLATFORM_SCHEMA validation * Import yaml from old yaml configuration * Apply suggestions from code review Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Feedback * Use Executor for IO only * Fix imports * update requirements * Fix flake8 * Run every section of fetching devices in single executor * Config flow feedback * Clean up * Fix plan step * Fix config flow test * Remove duplicate test * Test import step * Test already configured entry * Clean up tests * Add asserts * Mock out entry setup * Add warning if set up via yaml Co-authored-by: SNoof85 <snoof85@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
12342437e2
commit
85f758380a
12 changed files with 390 additions and 12 deletions
|
@ -374,6 +374,7 @@ omit =
|
||||||
homeassistant/components/greenwave/light.py
|
homeassistant/components/greenwave/light.py
|
||||||
homeassistant/components/group/notify.py
|
homeassistant/components/group/notify.py
|
||||||
homeassistant/components/growatt_server/sensor.py
|
homeassistant/components/growatt_server/sensor.py
|
||||||
|
homeassistant/components/growatt_server/__init__.py
|
||||||
homeassistant/components/gstreamer/media_player.py
|
homeassistant/components/gstreamer/media_player.py
|
||||||
homeassistant/components/gtfs/sensor.py
|
homeassistant/components/gtfs/sensor.py
|
||||||
homeassistant/components/guardian/__init__.py
|
homeassistant/components/guardian/__init__.py
|
||||||
|
|
|
@ -1 +1,19 @@
|
||||||
"""The Growatt server PV inverter sensor integration."""
|
"""The Growatt server PV inverter sensor integration."""
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from .const import PLATFORMS
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: config_entries.ConfigEntry
|
||||||
|
) -> bool:
|
||||||
|
"""Load the saved entities."""
|
||||||
|
|
||||||
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass, entry):
|
||||||
|
"""Unload a config entry."""
|
||||||
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
|
78
homeassistant/components/growatt_server/config_flow.py
Normal file
78
homeassistant/components/growatt_server/config_flow.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
"""Config flow for growatt server integration."""
|
||||||
|
import growattServer
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
|
from .const import CONF_PLANT_ID, DOMAIN
|
||||||
|
|
||||||
|
|
||||||
|
class GrowattServerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
|
"""Config flow class."""
|
||||||
|
|
||||||
|
VERSION = 1
|
||||||
|
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialise growatt server flow."""
|
||||||
|
self.api = growattServer.GrowattApi()
|
||||||
|
self.user_id = None
|
||||||
|
self.data = {}
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_show_user_form(self, errors=None):
|
||||||
|
"""Show the form to the user."""
|
||||||
|
data_schema = vol.Schema(
|
||||||
|
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="user", data_schema=data_schema, errors=errors
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_user(self, user_input=None):
|
||||||
|
"""Handle the start of the config flow."""
|
||||||
|
if not user_input:
|
||||||
|
return self._async_show_user_form()
|
||||||
|
|
||||||
|
login_response = await self.hass.async_add_executor_job(
|
||||||
|
self.api.login, user_input[CONF_USERNAME], user_input[CONF_PASSWORD]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not login_response["success"] and login_response["errCode"] == "102":
|
||||||
|
return self._async_show_user_form({"base": "invalid_auth"})
|
||||||
|
self.user_id = login_response["userId"]
|
||||||
|
|
||||||
|
self.data = user_input
|
||||||
|
return await self.async_step_plant()
|
||||||
|
|
||||||
|
async def async_step_plant(self, user_input=None):
|
||||||
|
"""Handle adding a "plant" to Home Assistant."""
|
||||||
|
plant_info = await self.hass.async_add_executor_job(
|
||||||
|
self.api.plant_list, self.user_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if not plant_info["data"]:
|
||||||
|
return self.async_abort(reason="no_plants")
|
||||||
|
|
||||||
|
plants = {plant["plantId"]: plant["plantName"] for plant in plant_info["data"]}
|
||||||
|
|
||||||
|
if user_input is None and len(plant_info["data"]) > 1:
|
||||||
|
data_schema = vol.Schema({vol.Required(CONF_PLANT_ID): vol.In(plants)})
|
||||||
|
|
||||||
|
return self.async_show_form(step_id="plant", data_schema=data_schema)
|
||||||
|
|
||||||
|
if user_input is None and len(plant_info["data"]) == 1:
|
||||||
|
user_input = {CONF_PLANT_ID: plant_info["data"][0]["plantId"]}
|
||||||
|
|
||||||
|
user_input[CONF_NAME] = plants[user_input[CONF_PLANT_ID]]
|
||||||
|
await self.async_set_unique_id(user_input[CONF_PLANT_ID])
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
self.data.update(user_input)
|
||||||
|
return self.async_create_entry(title=self.data[CONF_NAME], data=self.data)
|
||||||
|
|
||||||
|
async def async_step_import(self, import_data):
|
||||||
|
"""Migrate old yaml config to config flow."""
|
||||||
|
return await self.async_step_user(import_data)
|
10
homeassistant/components/growatt_server/const.py
Normal file
10
homeassistant/components/growatt_server/const.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
"""Define constants for the Growatt Server component."""
|
||||||
|
CONF_PLANT_ID = "plant_id"
|
||||||
|
|
||||||
|
DEFAULT_PLANT_ID = "0"
|
||||||
|
|
||||||
|
DEFAULT_NAME = "Growatt"
|
||||||
|
|
||||||
|
DOMAIN = "growatt_server"
|
||||||
|
|
||||||
|
PLATFORMS = ["sensor"]
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"domain": "growatt_server",
|
"domain": "growatt_server",
|
||||||
"name": "Growatt",
|
"name": "Growatt",
|
||||||
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/growatt_server/",
|
"documentation": "https://www.home-assistant.io/integrations/growatt_server/",
|
||||||
"requirements": ["growattServer==1.0.0"],
|
"requirements": ["growattServer==1.0.0"],
|
||||||
"codeowners": ["@indykoning", "@muppet3000"],
|
"codeowners": ["@indykoning", "@muppet3000"],
|
||||||
|
|
|
@ -8,6 +8,7 @@ import growattServer
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||||
|
from homeassistant.config_entries import SOURCE_IMPORT
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
|
@ -32,11 +33,10 @@ from homeassistant.const import (
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.util import Throttle, dt
|
from homeassistant.util import Throttle, dt
|
||||||
|
|
||||||
|
from .const import CONF_PLANT_ID, DEFAULT_NAME, DEFAULT_PLANT_ID, DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONF_PLANT_ID = "plant_id"
|
|
||||||
DEFAULT_PLANT_ID = "0"
|
|
||||||
DEFAULT_NAME = "Growatt"
|
|
||||||
SCAN_INTERVAL = datetime.timedelta(minutes=1)
|
SCAN_INTERVAL = datetime.timedelta(minutes=1)
|
||||||
|
|
||||||
# Sensor type order is: Sensor name, Unit of measurement, api data name, additional options
|
# Sensor type order is: Sensor name, Unit of measurement, api data name, additional options
|
||||||
|
@ -558,17 +558,26 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
"""Set up the Growatt sensor."""
|
"""Set up growatt server from yaml."""
|
||||||
username = config[CONF_USERNAME]
|
if not hass.config_entries.async_entries(DOMAIN):
|
||||||
password = config[CONF_PASSWORD]
|
_LOGGER.warning(
|
||||||
plant_id = config[CONF_PLANT_ID]
|
"Loading Growatt via platform setup is deprecated."
|
||||||
name = config[CONF_NAME]
|
"Please remove it from your configuration"
|
||||||
|
)
|
||||||
|
hass.async_create_task(
|
||||||
|
hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
api = growattServer.GrowattApi()
|
|
||||||
|
def get_device_list(api, config):
|
||||||
|
"""Retrieve the device list for the selected plant."""
|
||||||
|
plant_id = config[CONF_PLANT_ID]
|
||||||
|
|
||||||
# Log in to api and fetch first plant if no plant id is defined.
|
# Log in to api and fetch first plant if no plant id is defined.
|
||||||
login_response = api.login(username, password)
|
login_response = api.login(config[CONF_USERNAME], config[CONF_PASSWORD])
|
||||||
if not login_response["success"] and login_response["errCode"] == "102":
|
if not login_response["success"] and login_response["errCode"] == "102":
|
||||||
_LOGGER.error("Username or Password may be incorrect!")
|
_LOGGER.error("Username or Password may be incorrect!")
|
||||||
return
|
return
|
||||||
|
@ -579,6 +588,20 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
|
|
||||||
# Get a list of devices for specified plant to add sensors for.
|
# Get a list of devices for specified plant to add sensors for.
|
||||||
devices = api.device_list(plant_id)
|
devices = api.device_list(plant_id)
|
||||||
|
return [devices, plant_id]
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Set up the Growatt sensor."""
|
||||||
|
config = config_entry.data
|
||||||
|
username = config[CONF_USERNAME]
|
||||||
|
password = config[CONF_PASSWORD]
|
||||||
|
name = config[CONF_NAME]
|
||||||
|
|
||||||
|
api = growattServer.GrowattApi()
|
||||||
|
|
||||||
|
devices, plant_id = await hass.async_add_executor_job(get_device_list, api, config)
|
||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
probe = GrowattData(api, username, password, plant_id, "total")
|
probe = GrowattData(api, username, password, plant_id, "total")
|
||||||
for sensor in TOTAL_SENSOR_TYPES:
|
for sensor in TOTAL_SENSOR_TYPES:
|
||||||
|
@ -616,7 +639,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
class GrowattInverter(SensorEntity):
|
class GrowattInverter(SensorEntity):
|
||||||
|
|
27
homeassistant/components/growatt_server/strings.json
Normal file
27
homeassistant/components/growatt_server/strings.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"no_plants": "No plants have been found on this account"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"plant": {
|
||||||
|
"data": {
|
||||||
|
"plant_id": "Plant"
|
||||||
|
},
|
||||||
|
"title": "Select your plant"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"name": "[%key:common::config_flow::data::name%]",
|
||||||
|
"password": "[%key:common::config_flow::data::name%]",
|
||||||
|
"username": "[%key:common::config_flow::data::username%]"
|
||||||
|
},
|
||||||
|
"title": "Enter your Growatt information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Growatt Server"
|
||||||
|
}
|
27
homeassistant/components/growatt_server/translations/en.json
Normal file
27
homeassistant/components/growatt_server/translations/en.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"no_plants": "No plants have been found on this account"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"invalid_auth": "Invalid authentication"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"plant": {
|
||||||
|
"data": {
|
||||||
|
"plant_id": "Plant"
|
||||||
|
},
|
||||||
|
"title": "Select your plant"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"name": "Name",
|
||||||
|
"password": "Password",
|
||||||
|
"username": "Username"
|
||||||
|
},
|
||||||
|
"title": "Enter your Growatt information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Growatt Server"
|
||||||
|
}
|
|
@ -92,6 +92,7 @@ FLOWS = [
|
||||||
"google_travel_time",
|
"google_travel_time",
|
||||||
"gpslogger",
|
"gpslogger",
|
||||||
"gree",
|
"gree",
|
||||||
|
"growatt_server",
|
||||||
"guardian",
|
"guardian",
|
||||||
"habitica",
|
"habitica",
|
||||||
"hangouts",
|
"hangouts",
|
||||||
|
|
|
@ -386,6 +386,9 @@ googlemaps==2.5.1
|
||||||
# homeassistant.components.gree
|
# homeassistant.components.gree
|
||||||
greeclimate==0.11.4
|
greeclimate==0.11.4
|
||||||
|
|
||||||
|
# homeassistant.components.growatt_server
|
||||||
|
growattServer==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.profiler
|
# homeassistant.components.profiler
|
||||||
guppy3==3.1.0
|
guppy3==3.1.0
|
||||||
|
|
||||||
|
|
1
tests/components/growatt_server/__init__.py
Normal file
1
tests/components/growatt_server/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for the growatt_server component."""
|
188
tests/components/growatt_server/test_config_flow.py
Normal file
188
tests/components/growatt_server/test_config_flow.py
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
"""Tests for the Growatt server config flow."""
|
||||||
|
from copy import deepcopy
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from homeassistant import config_entries, data_entry_flow
|
||||||
|
from homeassistant.components.growatt_server.const import CONF_PLANT_ID, DOMAIN
|
||||||
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
FIXTURE_USER_INPUT = {CONF_USERNAME: "username", CONF_PASSWORD: "password"}
|
||||||
|
|
||||||
|
GROWATT_PLANT_LIST_RESPONSE = {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"plantMoneyText": "474.9 (€)",
|
||||||
|
"plantName": "Plant name",
|
||||||
|
"plantId": "123456",
|
||||||
|
"isHaveStorage": "false",
|
||||||
|
"todayEnergy": "2.6 kWh",
|
||||||
|
"totalEnergy": "2.37 MWh",
|
||||||
|
"currentPower": "628.8 W",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalData": {
|
||||||
|
"currentPowerSum": "628.8 W",
|
||||||
|
"CO2Sum": "2.37 KT",
|
||||||
|
"isHaveStorage": "false",
|
||||||
|
"eTotalMoneyText": "474.9 (€)",
|
||||||
|
"todayEnergySum": "2.6 kWh",
|
||||||
|
"totalEnergySum": "2.37 MWh",
|
||||||
|
},
|
||||||
|
"success": True,
|
||||||
|
}
|
||||||
|
GROWATT_LOGIN_RESPONSE = {"userId": 123456, "userLevel": 1, "success": True}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_show_authenticate_form(hass):
|
||||||
|
"""Test that the setup form is served."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_incorrect_username(hass):
|
||||||
|
"""Test that it shows the appropriate error when an incorrect username is entered."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login",
|
||||||
|
return_value={"errCode": "102", "success": False},
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], FIXTURE_USER_INPUT
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
assert result["errors"] == {"base": "invalid_auth"}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_no_plants_on_account(hass):
|
||||||
|
"""Test registering an integration and finishing flow with an entered plant_id."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
user_input = FIXTURE_USER_INPUT.copy()
|
||||||
|
plant_list = deepcopy(GROWATT_PLANT_LIST_RESPONSE)
|
||||||
|
plant_list["data"] = []
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login", return_value=GROWATT_LOGIN_RESPONSE
|
||||||
|
), patch("growattServer.GrowattApi.plant_list", return_value=plant_list):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == "abort"
|
||||||
|
assert result["reason"] == "no_plants"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_multiple_plant_ids(hass):
|
||||||
|
"""Test registering an integration and finishing flow with an entered plant_id."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
user_input = FIXTURE_USER_INPUT.copy()
|
||||||
|
plant_list = deepcopy(GROWATT_PLANT_LIST_RESPONSE)
|
||||||
|
plant_list["data"].append(plant_list["data"][0])
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login", return_value=GROWATT_LOGIN_RESPONSE
|
||||||
|
), patch("growattServer.GrowattApi.plant_list", return_value=plant_list), patch(
|
||||||
|
"homeassistant.components.growatt_server.async_setup_entry", return_value=True
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input
|
||||||
|
)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "plant"
|
||||||
|
|
||||||
|
user_input = {CONF_PLANT_ID: "123456"}
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result["data"][CONF_USERNAME] == FIXTURE_USER_INPUT[CONF_USERNAME]
|
||||||
|
assert result["data"][CONF_PASSWORD] == FIXTURE_USER_INPUT[CONF_PASSWORD]
|
||||||
|
assert result["data"][CONF_PLANT_ID] == "123456"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_one_plant_on_account(hass):
|
||||||
|
"""Test registering an integration and finishing flow with an entered plant_id."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
user_input = FIXTURE_USER_INPUT.copy()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login", return_value=GROWATT_LOGIN_RESPONSE
|
||||||
|
), patch(
|
||||||
|
"growattServer.GrowattApi.plant_list",
|
||||||
|
return_value=GROWATT_PLANT_LIST_RESPONSE,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.growatt_server.async_setup_entry", return_value=True
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result["data"][CONF_USERNAME] == FIXTURE_USER_INPUT[CONF_USERNAME]
|
||||||
|
assert result["data"][CONF_PASSWORD] == FIXTURE_USER_INPUT[CONF_PASSWORD]
|
||||||
|
assert result["data"][CONF_PLANT_ID] == "123456"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_import_one_plant(hass):
|
||||||
|
"""Test import step with a single plant."""
|
||||||
|
import_data = FIXTURE_USER_INPUT.copy()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login", return_value=GROWATT_LOGIN_RESPONSE
|
||||||
|
), patch(
|
||||||
|
"growattServer.GrowattApi.plant_list",
|
||||||
|
return_value=GROWATT_PLANT_LIST_RESPONSE,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.growatt_server.async_setup_entry", return_value=True
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
|
data=import_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result["data"][CONF_USERNAME] == FIXTURE_USER_INPUT[CONF_USERNAME]
|
||||||
|
assert result["data"][CONF_PASSWORD] == FIXTURE_USER_INPUT[CONF_PASSWORD]
|
||||||
|
assert result["data"][CONF_PLANT_ID] == "123456"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_existing_plant_configured(hass):
|
||||||
|
"""Test entering an existing plant_id."""
|
||||||
|
entry = MockConfigEntry(domain=DOMAIN, unique_id="123456")
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
user_input = FIXTURE_USER_INPUT.copy()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"growattServer.GrowattApi.login", return_value=GROWATT_LOGIN_RESPONSE
|
||||||
|
), patch(
|
||||||
|
"growattServer.GrowattApi.plant_list",
|
||||||
|
return_value=GROWATT_PLANT_LIST_RESPONSE,
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == "abort"
|
||||||
|
assert result["reason"] == "already_configured"
|
Loading…
Add table
Add a link
Reference in a new issue