Skip to content

Commit

Permalink
Improve code style
Browse files Browse the repository at this point in the history
  • Loading branch information
wlcrs committed Jul 28, 2022
1 parent b52a74f commit 9070cfb
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 205 deletions.
58 changes: 16 additions & 42 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,32 @@
"""The Huawei Solar integration."""
from __future__ import annotations

import logging
from collections.abc import Awaitable, Callable
from datetime import timedelta
import logging
from typing import TypedDict, TypeVar

import async_timeout
from huawei_solar import (
HuaweiSolarBridge,
HuaweiSolarException,
InvalidCredentials,
register_values as rv,
)

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_PORT,
CONF_USERNAME,
Platform,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from huawei_solar import HuaweiSolarBridge, HuaweiSolarException, InvalidCredentials
from huawei_solar import register_values as rv

from .const import (
CONF_ENABLE_PARAMETER_CONFIGURATION,
CONF_SLAVE_IDS,
DATA_OPTIMIZER_UPDATE_COORDINATORS,
DATA_UPDATE_COORDINATORS,
DOMAIN,
OPTIMIZER_UPDATE_INTERVAL,
SERVICES,
UPDATE_INTERVAL,
OPTIMIZER_UPDATE_INTERVAL,
)
from .services import async_setup_services

Expand Down Expand Up @@ -72,9 +62,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if entry.data.get(CONF_ENABLE_PARAMETER_CONFIGURATION):
if entry.data.get(CONF_USERNAME) and entry.data.get(CONF_PASSWORD):
try:
await primary_bridge.login(
entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD]
)
await primary_bridge.login(entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD])
except InvalidCredentials as err:
raise ConfigEntryAuthFailed() from err

Expand All @@ -83,14 +71,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
connecting_inverter_device_id=None,
)

bridges_with_device_infos: list[
tuple[HuaweiSolarBridge, HuaweiInverterBridgeDeviceInfos]
] = [(primary_bridge, primary_bridge_device_infos)]
bridges_with_device_infos: list[tuple[HuaweiSolarBridge, HuaweiInverterBridgeDeviceInfos]] = [
(primary_bridge, primary_bridge_device_infos)
]

for extra_slave_id in entry.data[CONF_SLAVE_IDS][1:]:
extra_bridge = await HuaweiSolarBridge.create_extra_slave(
primary_bridge, extra_slave_id
)
extra_bridge = await HuaweiSolarBridge.create_extra_slave(primary_bridge, extra_slave_id)

extra_bridge_device_infos = await _compute_device_infos(
extra_bridge,
Expand All @@ -106,18 +92,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
update_coordinators = []
optimizer_update_coordinators = []
for bridge, device_infos in bridges_with_device_infos:
update_coordinators.append(
await _create_update_coordinator(
hass, bridge, device_infos, UPDATE_INTERVAL
)
)
update_coordinators.append(await _create_update_coordinator(hass, bridge, device_infos, UPDATE_INTERVAL))

if bridge.has_optimizers:
optimizers_device_infos = {}
try:
optimizer_system_infos = (
await bridge.get_optimizer_system_information_data()
)
optimizer_system_infos = await bridge.get_optimizer_system_information_data()
for optimizer_id, optimizer in optimizer_system_infos.items():
optimizers_device_infos[optimizer_id] = DeviceInfo(
identifiers={(DOMAIN, optimizer.sn)},
Expand Down Expand Up @@ -170,9 +150,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
update_coordinators = hass.data[DOMAIN][entry.entry_id][
DATA_UPDATE_COORDINATORS
]
update_coordinators = hass.data[DOMAIN][entry.entry_id][DATA_UPDATE_COORDINATORS]
for update_coordinator in update_coordinators:
await update_coordinator.bridge.stop()

Expand Down Expand Up @@ -271,9 +249,7 @@ async def _async_update_data(self):
async with async_timeout.timeout(20):
return await self.bridge.update()
except HuaweiSolarException as err:
raise UpdateFailed(
f"Could not update {self.bridge.serial_number} values: {err}"
) from err
raise UpdateFailed(f"Could not update {self.bridge.serial_number} values: {err}") from err


async def _create_update_coordinator(
Expand Down Expand Up @@ -329,9 +305,7 @@ async def _async_update_data(self):
async with async_timeout.timeout(20):
return await self.bridge.get_latest_optimizer_history_data()
except HuaweiSolarException as err:
raise UpdateFailed(
f"Could not update {self.bridge.serial_number} optimizer values: {err}"
) from err
raise UpdateFailed(f"Could not update {self.bridge.serial_number} optimizer values: {err}") from err


async def _create_optimizer_update_coordinator(
Expand Down
99 changes: 25 additions & 74 deletions config_flow.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
"""Config flow for Huawei Solar integration."""
from __future__ import annotations

import os
import logging
from typing import Any

from huawei_solar import (
ConnectionException,
HuaweiSolarBridge,
HuaweiSolarException,
ReadException,
)
import homeassistant.helpers.config_validation as cv
import serial.tools.list_ports
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.components import usb
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_PORT,
CONF_USERNAME,
CONF_TYPE,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_TYPE, CONF_USERNAME
from homeassistant.data_entry_flow import FlowResult
import homeassistant.helpers.config_validation as cv

from huawei_solar import ConnectionException, HuaweiSolarBridge, HuaweiSolarException, ReadException

from .const import (
CONF_ENABLE_PARAMETER_CONFIGURATION,
Expand Down Expand Up @@ -81,9 +69,7 @@ async def validate_serial_setup(data: dict[str, Any]) -> dict[str, Any]:
# Also validate the other slave-ids
for slave_id in data[CONF_SLAVE_IDS][1:]:
try:
slave_bridge = await HuaweiSolarBridge.create_extra_slave(
bridge, slave_id
)
slave_bridge = await HuaweiSolarBridge.create_extra_slave(bridge, slave_id)

_LOGGER.info(
"Successfully connected to slave inverter %s: %s with SN %s",
Expand Down Expand Up @@ -137,9 +123,7 @@ async def validate_network_setup(data: dict[str, Any]) -> dict[str, Any]:
# Also validate the other slave-ids
for slave_id in data[CONF_SLAVE_IDS][1:]:
try:
slave_bridge = await HuaweiSolarBridge.create_extra_slave(
bridge, slave_id
)
slave_bridge = await HuaweiSolarBridge.create_extra_slave(bridge, slave_id)

_LOGGER.info(
"Successfully connected to slave inverter %s: %s with SN %s",
Expand All @@ -160,9 +144,7 @@ async def validate_network_setup(data: dict[str, Any]) -> dict[str, Any]:
await bridge.stop()


async def validate_network_setup_login(
host: str, port: int, slave_id: int, login_data: dict[str, Any]
) -> bool:
async def validate_network_setup_login(host: str, port: int, slave_id: int, login_data: dict[str, Any]) -> bool:
"""Verify the installer username/password and test if it can perform a write-operation."""
bridge = None
try:
Expand Down Expand Up @@ -206,9 +188,7 @@ def __init__(self) -> None:
# Only used in reauth flows:
self._reauth_entry: config_entries.ConfigEntry | None = None

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_user(self, user_input: dict[str, Any] | None = None) -> FlowResult:
"""Step when user initializes a integration."""
if user_input is not None:
user_selection = user_input[CONF_TYPE]
Expand All @@ -222,9 +202,7 @@ async def async_step_user(
schema = vol.Schema({vol.Required(CONF_TYPE): vol.In(list_of_types)})
return self.async_show_form(step_id="user", data_schema=schema)

async def async_step_setup_serial(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_setup_serial(self, user_input: dict[str, Any] | None = None) -> FlowResult:
"""Handles connection parameters when using ModbusRTU."""
errors = {}

Expand All @@ -235,14 +213,10 @@ async def async_step_setup_serial(
self._slave_ids = user_input[CONF_SLAVE_IDS]
return await self.async_step_setup_serial_manual_path()

user_input[CONF_PORT] = await self.hass.async_add_executor_job(
usb.get_serial_by_id, user_input[CONF_PORT]
)
user_input[CONF_PORT] = await self.hass.async_add_executor_job(usb.get_serial_by_id, user_input[CONF_PORT])

try:
user_input[CONF_SLAVE_IDS] = list(
map(int, user_input[CONF_SLAVE_IDS].split(","))
)
user_input[CONF_SLAVE_IDS] = list(map(int, user_input[CONF_SLAVE_IDS].split(",")))
except ValueError:
errors["base"] = "invalid_slave_ids"
else:
Expand Down Expand Up @@ -305,18 +279,14 @@ async def async_step_setup_serial(
errors=errors,
)

async def async_step_setup_serial_manual_path(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_setup_serial_manual_path(self, user_input: dict[str, Any] | None = None) -> FlowResult:
"""Select path manually."""
errors = {}

if user_input is not None:

try:
user_input[CONF_SLAVE_IDS] = list(
map(int, user_input[CONF_SLAVE_IDS].split(","))
)
user_input[CONF_SLAVE_IDS] = list(map(int, user_input[CONF_SLAVE_IDS].split(",")))
except ValueError:
errors["base"] = "invalid_slave_ids"
else:
Expand Down Expand Up @@ -357,22 +327,16 @@ async def async_step_setup_serial_manual_path(
vol.Required(CONF_SLAVE_IDS, default=self._slave_ids): str,
}
)
return self.async_show_form(
step_id="setup_serial_manual_path", data_schema=schema, errors=errors
)
return self.async_show_form(step_id="setup_serial_manual_path", data_schema=schema, errors=errors)

async def async_step_setup_network(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_setup_network(self, user_input: dict[str, Any] | None = None) -> FlowResult:
"""Handles connection parameters when using ModbusTCP."""

errors = {}

if user_input is not None:
try:
user_input[CONF_SLAVE_IDS] = list(
map(int, user_input[CONF_SLAVE_IDS].split(","))
)
user_input[CONF_SLAVE_IDS] = list(map(int, user_input[CONF_SLAVE_IDS].split(",")))
except ValueError:
errors["base"] = "invalid_slave_ids"
else:
Expand All @@ -396,17 +360,16 @@ async def async_step_setup_network(
self._host = user_input[CONF_HOST]
self._port = user_input[CONF_PORT]
self._slave_ids = user_input[CONF_SLAVE_IDS]
self._enable_parameter_configuration = user_input[
CONF_ENABLE_PARAMETER_CONFIGURATION
]
self._enable_parameter_configuration = user_input[CONF_ENABLE_PARAMETER_CONFIGURATION]

self._inverter_info = info
self.context["title_placeholders"] = {"name": info["model_name"]}

# Check if we need to ask for the login details
if (
self._enable_parameter_configuration
and info["has_write_permission"] == False # this can also be None, in which case login is not supported.
and info["has_write_permission"]
== False # this can also be None, in which case login is not supported.
):
return await self.async_step_network_login()

Expand All @@ -419,9 +382,7 @@ async def async_step_setup_network(
errors=errors,
)

async def async_step_network_login(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_network_login(self, user_input: dict[str, Any] | None = None) -> FlowResult:
"""Handle username/password input."""
assert self._host is not None
assert self._port is not None
Expand Down Expand Up @@ -452,9 +413,7 @@ async def async_step_network_login(
_LOGGER.exception(exception)
errors["base"] = "unknown"

return self.async_show_form(
step_id="network_login", data_schema=STEP_LOGIN_DATA_SCHEMA, errors=errors
)
return self.async_show_form(step_id="network_login", data_schema=STEP_LOGIN_DATA_SCHEMA, errors=errors)

async def _create_entry(self):
"""Create the entry."""
Expand All @@ -475,26 +434,18 @@ async def _create_entry(self):
await self.hass.config_entries.async_reload(self._reauth_entry.entry_id)
return self.async_abort(reason="reauth_successful")

return self.async_create_entry(
title=self._inverter_info["model_name"], data=data
)
return self.async_create_entry(title=self._inverter_info["model_name"], data=data)

async def async_step_reauth(
self, config: dict[str, Any] | None = None
) -> FlowResult:
async def async_step_reauth(self, config: dict[str, Any] | None = None) -> FlowResult:
"""Perform reauth upon an login error."""
assert config is not None

self._host = config.get(CONF_HOST)
self._port = config.get(CONF_PORT)
self._slave_ids = config.get(CONF_SLAVE_IDS)
self._enable_parameter_configuration = config.get(
CONF_ENABLE_PARAMETER_CONFIGURATION, False
)
self._enable_parameter_configuration = config.get(CONF_ENABLE_PARAMETER_CONFIGURATION, False)

self._reauth_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
)
self._reauth_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
return await self.async_step_network_login()


Expand Down
Loading

0 comments on commit 9070cfb

Please sign in to comment.