Allow for alternative external Growatt servers (#53102)

This commit is contained in:
muppet3000 2021-07-21 09:16:02 +01:00 committed by GitHub
parent 4546e14674
commit 18ec0544b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 12 deletions

View File

@ -3,10 +3,10 @@ import growattServer
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_URL, CONF_USERNAME
from homeassistant.core import callback from homeassistant.core import callback
from .const import CONF_PLANT_ID, DOMAIN from .const import CONF_PLANT_ID, DEFAULT_URL, DOMAIN, SERVER_URLS
class GrowattServerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class GrowattServerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
@ -24,7 +24,11 @@ class GrowattServerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
def _async_show_user_form(self, errors=None): def _async_show_user_form(self, errors=None):
"""Show the form to the user.""" """Show the form to the user."""
data_schema = vol.Schema( data_schema = vol.Schema(
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str} {
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_URL, default=DEFAULT_URL): vol.In(SERVER_URLS),
}
) )
return self.async_show_form( return self.async_show_form(
@ -36,6 +40,7 @@ class GrowattServerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if not user_input: if not user_input:
return self._async_show_user_form() return self._async_show_user_form()
self.api.server_url = user_input[CONF_URL]
login_response = await self.hass.async_add_executor_job( login_response = await self.hass.async_add_executor_job(
self.api.login, user_input[CONF_USERNAME], user_input[CONF_PASSWORD] self.api.login, user_input[CONF_USERNAME], user_input[CONF_PASSWORD]
) )

View File

@ -5,6 +5,14 @@ DEFAULT_PLANT_ID = "0"
DEFAULT_NAME = "Growatt" DEFAULT_NAME = "Growatt"
SERVER_URLS = [
"https://server.growatt.com/",
"https://server-us.growatt.com",
"http://server.smten.com/",
]
DEFAULT_URL = SERVER_URLS[0]
DOMAIN = "growatt_server" DOMAIN = "growatt_server"
PLATFORMS = ["sensor"] PLATFORMS = ["sensor"]

View File

@ -12,6 +12,7 @@ from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import ( from homeassistant.const import (
CONF_NAME, CONF_NAME,
CONF_PASSWORD, CONF_PASSWORD,
CONF_URL,
CONF_USERNAME, CONF_USERNAME,
CURRENCY_EURO, CURRENCY_EURO,
DEVICE_CLASS_BATTERY, DEVICE_CLASS_BATTERY,
@ -33,7 +34,7 @@ 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 from .const import CONF_PLANT_ID, DEFAULT_NAME, DEFAULT_PLANT_ID, DEFAULT_URL, DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -554,6 +555,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_PLANT_ID, default=DEFAULT_PLANT_ID): cv.string, vol.Optional(CONF_PLANT_ID, default=DEFAULT_PLANT_ID): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_URL, default=DEFAULT_URL): cv.string,
} }
) )
@ -579,7 +581,7 @@ def get_device_list(api, config):
# 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(config[CONF_USERNAME], config[CONF_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, Password or URL may be incorrect!")
return return
user_id = login_response["userId"] user_id = login_response["userId"]
if plant_id == DEFAULT_PLANT_ID: if plant_id == DEFAULT_PLANT_ID:
@ -596,9 +598,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
config = config_entry.data config = config_entry.data
username = config[CONF_USERNAME] username = config[CONF_USERNAME]
password = config[CONF_PASSWORD] password = config[CONF_PASSWORD]
url = config[CONF_URL]
name = config[CONF_NAME] name = config[CONF_NAME]
api = growattServer.GrowattApi() api = growattServer.GrowattApi()
api.server_url = url
devices, plant_id = await hass.async_add_executor_job(get_device_list, api, config) devices, plant_id = await hass.async_add_executor_job(get_device_list, api, config)

View File

@ -17,7 +17,8 @@
"data": { "data": {
"name": "[%key:common::config_flow::data::name%]", "name": "[%key:common::config_flow::data::name%]",
"password": "[%key:common::config_flow::data::password%]", "password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::username%]" "username": "[%key:common::config_flow::data::username%]",
"url": "[%key:common::config_flow::data::url%]"
}, },
"title": "Enter your Growatt information" "title": "Enter your Growatt information"
} }

View File

@ -3,12 +3,20 @@ from copy import deepcopy
from unittest.mock import patch from unittest.mock import patch
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.growatt_server.const import CONF_PLANT_ID, DOMAIN from homeassistant.components.growatt_server.const import (
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME CONF_PLANT_ID,
DEFAULT_URL,
DOMAIN,
)
from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
FIXTURE_USER_INPUT = {CONF_USERNAME: "username", CONF_PASSWORD: "password"} FIXTURE_USER_INPUT = {
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_URL: DEFAULT_URL,
}
GROWATT_PLANT_LIST_RESPONSE = { GROWATT_PLANT_LIST_RESPONSE = {
"data": [ "data": [
@ -45,8 +53,8 @@ async def test_show_authenticate_form(hass):
assert result["step_id"] == "user" assert result["step_id"] == "user"
async def test_incorrect_username(hass): async def test_incorrect_login(hass):
"""Test that it shows the appropriate error when an incorrect username is entered.""" """Test that it shows the appropriate error when an incorrect username/password/server is entered."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )