diff --git a/homeassistant/components/solax/__init__.py b/homeassistant/components/solax/__init__.py index b5e15043cec968..b27308eae3abbf 100644 --- a/homeassistant/components/solax/__init__.py +++ b/homeassistant/components/solax/__init__.py @@ -1,13 +1,19 @@ """The solax component.""" -from solax import real_time_api +import logging + +import solax +from solax import RealTimeAPI +from solax.discovery import REGISTRY from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_PORT, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from .const import DOMAIN +from .const import CONF_SOLAX_INVERTER, DOMAIN + +_LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.SENSOR] @@ -15,12 +21,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the sensors from a ConfigEntry.""" + registry_hash = {cls.__name__: cls for cls in REGISTRY} + + invset = set() + for cls_name in entry.data[CONF_SOLAX_INVERTER]: + invset.add(registry_hash[cls_name]) + + _LOGGER.debug("solax inverter set %s", invset) + try: - api = await real_time_api( + inverter = await solax.discover( entry.data[CONF_IP_ADDRESS], entry.data[CONF_PORT], entry.data[CONF_PASSWORD], + inverters=invset, ) + api = RealTimeAPI(inverter) await api.get_data() except Exception as err: raise ConfigEntryNotReady from err diff --git a/homeassistant/components/solax/config_flow.py b/homeassistant/components/solax/config_flow.py index 4055f1c46aeadd..687d967a8150d4 100644 --- a/homeassistant/components/solax/config_flow.py +++ b/homeassistant/components/solax/config_flow.py @@ -5,26 +5,39 @@ import logging from typing import Any -from solax import real_time_api -from solax.discovery import DiscoveryError +from solax import discover +from solax.discovery import REGISTRY, DiscoveryError import voluptuous as vol from homeassistant.config_entries import ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_PORT +from homeassistant.helpers import selector import homeassistant.helpers.config_validation as cv -from .const import DOMAIN +from .const import CONF_SOLAX_INVERTER, DOMAIN _LOGGER = logging.getLogger(__name__) DEFAULT_PORT = 80 DEFAULT_PASSWORD = "" +DEFAULT_INVERTER = "" + +REGISTRY_HASH = {cls.__name__: cls for cls in REGISTRY} STEP_USER_DATA_SCHEMA = vol.Schema( { vol.Required(CONF_IP_ADDRESS): cv.string, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string, + vol.Optional( + CONF_SOLAX_INVERTER, default=DEFAULT_INVERTER + ): selector.SelectSelector( + selector.SelectSelectorConfig( + options=list(REGISTRY_HASH.keys()), + mode=selector.SelectSelectorMode.DROPDOWN, + multiple=True, + ) + ), } ) @@ -32,10 +45,19 @@ async def validate_api(data) -> str: """Validate the credentials.""" - api = await real_time_api( - data[CONF_IP_ADDRESS], data[CONF_PORT], data[CONF_PASSWORD] + _LOGGER.debug("CONF_SOLAX_INVERTER entry: %s", data[CONF_SOLAX_INVERTER]) + + invset = set() + for cls_name in data[CONF_SOLAX_INVERTER]: + invset.add(REGISTRY_HASH[cls_name]) + inverter = await discover( + data[CONF_IP_ADDRESS], + data[CONF_PORT], + data[CONF_PASSWORD], + inverters=invset, ) - response = await api.get_data() + response = await inverter.get_data() + _LOGGER.debug("Solax serial number %s", response.serial_number) return response.serial_number diff --git a/homeassistant/components/solax/const.py b/homeassistant/components/solax/const.py index 26d5962e385888..f25a3139439d8e 100644 --- a/homeassistant/components/solax/const.py +++ b/homeassistant/components/solax/const.py @@ -3,3 +3,5 @@ DOMAIN = "solax" MANUFACTURER = "SolaX Power" + +CONF_SOLAX_INVERTER = "solax.inverters" diff --git a/tests/components/solax/test_config_flow.py b/tests/components/solax/test_config_flow.py index c787962cc8c5d1..1b9b3422aaccd4 100644 --- a/tests/components/solax/test_config_flow.py +++ b/tests/components/solax/test_config_flow.py @@ -2,19 +2,18 @@ from unittest.mock import patch -from solax import RealTimeAPI from solax.inverter import InverterResponse from solax.inverters import X1MiniV34 from homeassistant import config_entries -from homeassistant.components.solax.const import DOMAIN +from homeassistant.components.solax.const import CONF_SOLAX_INVERTER, DOMAIN from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_PORT from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType -def __mock_real_time_api_success(): - return RealTimeAPI(X1MiniV34) +def __mock_discover_success(): + return X1MiniV34 def __mock_get_data(): @@ -37,10 +36,10 @@ async def test_form_success(hass: HomeAssistant) -> None: with ( patch( - "homeassistant.components.solax.config_flow.real_time_api", - return_value=__mock_real_time_api_success(), + "homeassistant.components.solax.config_flow.discover", + return_value=__mock_discover_success(), ), - patch("solax.RealTimeAPI.get_data", return_value=__mock_get_data()), + patch("solax.Inverter.get_data", return_value=__mock_get_data()), patch( "homeassistant.components.solax.async_setup_entry", return_value=True, @@ -48,7 +47,12 @@ async def test_form_success(hass: HomeAssistant) -> None: ): entry_result = await hass.config_entries.flow.async_configure( flow["flow_id"], - {CONF_IP_ADDRESS: "192.168.1.87", CONF_PORT: 80, CONF_PASSWORD: "password"}, + { + CONF_IP_ADDRESS: "192.168.1.87", + CONF_PORT: 80, + CONF_PASSWORD: "password", + CONF_SOLAX_INVERTER: ["X1MiniV34"], + }, ) await hass.async_block_till_done() @@ -58,6 +62,7 @@ async def test_form_success(hass: HomeAssistant) -> None: CONF_IP_ADDRESS: "192.168.1.87", CONF_PORT: 80, CONF_PASSWORD: "password", + CONF_SOLAX_INVERTER: ["X1MiniV34"], } assert len(mock_setup_entry.mock_calls) == 1 @@ -71,12 +76,17 @@ async def test_form_connect_error(hass: HomeAssistant) -> None: assert flow["errors"] == {} with patch( - "homeassistant.components.solax.config_flow.real_time_api", + "homeassistant.components.solax.config_flow.discover", side_effect=ConnectionError, ): entry_result = await hass.config_entries.flow.async_configure( flow["flow_id"], - {CONF_IP_ADDRESS: "192.168.1.87", CONF_PORT: 80, CONF_PASSWORD: "password"}, + { + CONF_IP_ADDRESS: "192.168.1.87", + CONF_PORT: 80, + CONF_PASSWORD: "password", + CONF_SOLAX_INVERTER: [], + }, ) assert entry_result["type"] is FlowResultType.FORM @@ -92,12 +102,17 @@ async def test_form_unknown_error(hass: HomeAssistant) -> None: assert flow["errors"] == {} with patch( - "homeassistant.components.solax.config_flow.real_time_api", + "homeassistant.components.solax.config_flow.discover", side_effect=Exception, ): entry_result = await hass.config_entries.flow.async_configure( flow["flow_id"], - {CONF_IP_ADDRESS: "192.168.1.87", CONF_PORT: 80, CONF_PASSWORD: "password"}, + { + CONF_IP_ADDRESS: "192.168.1.87", + CONF_PORT: 80, + CONF_PASSWORD: "password", + CONF_SOLAX_INVERTER: [], + }, ) assert entry_result["type"] is FlowResultType.FORM