Skip to content

Commit

Permalink
solax: add Inverter model selector in config_flow to bypass discovery (
Browse files Browse the repository at this point in the history
…home-assistant#66617). Adapt code to upstream solax-3.1.0
  • Loading branch information
brew-your-own committed Apr 7, 2024
1 parent 8f425b9 commit d21923c
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 21 deletions.
22 changes: 19 additions & 3 deletions homeassistant/components/solax/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
"""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]


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
Expand Down
34 changes: 28 additions & 6 deletions homeassistant/components/solax/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,59 @@
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,
)
),
}
)


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


Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/solax/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
DOMAIN = "solax"

MANUFACTURER = "SolaX Power"

CONF_SOLAX_INVERTER = "solax.inverters"
39 changes: 27 additions & 12 deletions tests/components/solax/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -37,18 +36,23 @@ 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,
) as mock_setup_entry,
):
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()

Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit d21923c

Please sign in to comment.