mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Bump sunweg to 2.0.1 (#105613)
* chore(sunweg): minor requested changes * test(sunweg): use of fixtures * feat(sunweg): provide bad auth result on expired authentication * chore(sunweg): bump version * chore(sunweg): removed reauth * chore(sunweg): removed features out of scope * chore(sunweg): fixtures moved to conftest.py * chore(sunweg): devicetype moved to const * chore(sunweg): conftest comment Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
7e1dc2286f
commit
d4a7361bc6
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
|
|
||||||
from .const import CONF_PLANT_ID, DOMAIN, PLATFORMS
|
from .const import CONF_PLANT_ID, DOMAIN, PLATFORMS, DeviceType
|
||||||
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
||||||
|
|
||||||
SCAN_INTERVAL = datetime.timedelta(minutes=5)
|
SCAN_INTERVAL = datetime.timedelta(minutes=5)
|
||||||
@ -74,12 +74,12 @@ class SunWEGData:
|
|||||||
def get_api_value(
|
def get_api_value(
|
||||||
self,
|
self,
|
||||||
variable: str,
|
variable: str,
|
||||||
device_type: str,
|
device_type: DeviceType,
|
||||||
inverter_id: int = 0,
|
inverter_id: int = 0,
|
||||||
deep_name: str | None = None,
|
deep_name: str | None = None,
|
||||||
):
|
):
|
||||||
"""Retrieve from a Plant the desired variable value."""
|
"""Retrieve from a Plant the desired variable value."""
|
||||||
if device_type == "total":
|
if device_type == DeviceType.TOTAL:
|
||||||
return self.data.__dict__.get(variable)
|
return self.data.__dict__.get(variable)
|
||||||
|
|
||||||
inverter_list = [i for i in self.data.inverters if i.id == inverter_id]
|
inverter_list = [i for i in self.data.inverters if i.id == inverter_id]
|
||||||
@ -87,13 +87,13 @@ class SunWEGData:
|
|||||||
return None
|
return None
|
||||||
inverter = inverter_list[0]
|
inverter = inverter_list[0]
|
||||||
|
|
||||||
if device_type == "inverter":
|
if device_type == DeviceType.INVERTER:
|
||||||
return inverter.__dict__.get(variable)
|
return inverter.__dict__.get(variable)
|
||||||
if device_type == "phase":
|
if device_type == DeviceType.PHASE:
|
||||||
for phase in inverter.phases:
|
for phase in inverter.phases:
|
||||||
if phase.name == deep_name:
|
if phase.name == deep_name:
|
||||||
return phase.__dict__.get(variable)
|
return phase.__dict__.get(variable)
|
||||||
elif device_type == "string":
|
elif device_type == DeviceType.STRING:
|
||||||
for mppt in inverter.mppts:
|
for mppt in inverter.mppts:
|
||||||
for string in mppt.strings:
|
for string in mppt.strings:
|
||||||
if string.name == deep_name:
|
if string.name == deep_name:
|
||||||
@ -103,7 +103,7 @@ class SunWEGData:
|
|||||||
def get_data(
|
def get_data(
|
||||||
self,
|
self,
|
||||||
entity_description: SunWEGSensorEntityDescription,
|
entity_description: SunWEGSensorEntityDescription,
|
||||||
device_type: str,
|
device_type: DeviceType,
|
||||||
inverter_id: int = 0,
|
inverter_id: int = 0,
|
||||||
deep_name: str | None = None,
|
deep_name: str | None = None,
|
||||||
) -> StateType | datetime.datetime:
|
) -> StateType | datetime.datetime:
|
||||||
@ -113,13 +113,13 @@ class SunWEGData:
|
|||||||
entity_description.name,
|
entity_description.name,
|
||||||
)
|
)
|
||||||
variable = entity_description.api_variable_key
|
variable = entity_description.api_variable_key
|
||||||
previous_metric = entity_description.native_unit_of_measurement
|
previous_unit = entity_description.native_unit_of_measurement
|
||||||
api_value = self.get_api_value(variable, device_type, inverter_id, deep_name)
|
api_value = self.get_api_value(variable, device_type, inverter_id, deep_name)
|
||||||
previous_value = self.previous_values.get(variable)
|
previous_value = self.previous_values.get(variable)
|
||||||
return_value = api_value
|
return_value = api_value
|
||||||
if entity_description.api_variable_metric is not None:
|
if entity_description.api_variable_unit is not None:
|
||||||
entity_description.native_unit_of_measurement = self.get_api_value(
|
entity_description.native_unit_of_measurement = self.get_api_value(
|
||||||
entity_description.api_variable_metric,
|
entity_description.api_variable_unit,
|
||||||
device_type,
|
device_type,
|
||||||
inverter_id,
|
inverter_id,
|
||||||
deep_name,
|
deep_name,
|
||||||
@ -130,7 +130,7 @@ class SunWEGData:
|
|||||||
entity_description.previous_value_drop_threshold is not None
|
entity_description.previous_value_drop_threshold is not None
|
||||||
and previous_value is not None
|
and previous_value is not None
|
||||||
and api_value is not None
|
and api_value is not None
|
||||||
and previous_metric == entity_description.native_unit_of_measurement
|
and previous_unit == entity_description.native_unit_of_measurement
|
||||||
):
|
):
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
(
|
(
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
"""Define constants for the Sun WEG component."""
|
"""Define constants for the Sun WEG component."""
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceType(Enum):
|
||||||
|
"""Device Type Enum."""
|
||||||
|
|
||||||
|
TOTAL = 1
|
||||||
|
INVERTER = 2
|
||||||
|
PHASE = 3
|
||||||
|
STRING = 4
|
||||||
|
|
||||||
|
|
||||||
CONF_PLANT_ID = "plant_id"
|
CONF_PLANT_ID = "plant_id"
|
||||||
|
|
||||||
DEFAULT_PLANT_ID = 0
|
DEFAULT_PLANT_ID = 0
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/sunweg/",
|
"documentation": "https://www.home-assistant.io/integrations/sunweg/",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["sunweg"],
|
"loggers": ["sunweg"],
|
||||||
"requirements": ["sunweg==2.0.0"]
|
"requirements": ["sunweg==2.0.1"]
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
from . import SunWEGData
|
from . import SunWEGData
|
||||||
from .const import CONF_PLANT_ID, DEFAULT_PLANT_ID, DOMAIN
|
from .const import CONF_PLANT_ID, DEFAULT_PLANT_ID, DOMAIN, DeviceType
|
||||||
from .sensor_types.inverter import INVERTER_SENSOR_TYPES
|
from .sensor_types.inverter import INVERTER_SENSOR_TYPES
|
||||||
from .sensor_types.phase import PHASE_SENSOR_TYPES
|
from .sensor_types.phase import PHASE_SENSOR_TYPES
|
||||||
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
||||||
@ -67,7 +67,7 @@ async def async_setup_entry(
|
|||||||
name=f"{name} Total",
|
name=f"{name} Total",
|
||||||
unique_id=f"{plant_id}-{description.key}",
|
unique_id=f"{plant_id}-{description.key}",
|
||||||
description=description,
|
description=description,
|
||||||
device_type="total",
|
device_type=DeviceType.TOTAL,
|
||||||
)
|
)
|
||||||
for description in TOTAL_SENSOR_TYPES
|
for description in TOTAL_SENSOR_TYPES
|
||||||
]
|
]
|
||||||
@ -80,7 +80,7 @@ async def async_setup_entry(
|
|||||||
name=f"{device.name}",
|
name=f"{device.name}",
|
||||||
unique_id=f"{device.sn}-{description.key}",
|
unique_id=f"{device.sn}-{description.key}",
|
||||||
description=description,
|
description=description,
|
||||||
device_type="inverter",
|
device_type=DeviceType.INVERTER,
|
||||||
inverter_id=device.id,
|
inverter_id=device.id,
|
||||||
)
|
)
|
||||||
for device in devices
|
for device in devices
|
||||||
@ -96,7 +96,7 @@ async def async_setup_entry(
|
|||||||
unique_id=f"{device.sn}-{phase.name}-{description.key}",
|
unique_id=f"{device.sn}-{phase.name}-{description.key}",
|
||||||
description=description,
|
description=description,
|
||||||
inverter_id=device.id,
|
inverter_id=device.id,
|
||||||
device_type="phase",
|
device_type=DeviceType.PHASE,
|
||||||
deep_name=phase.name,
|
deep_name=phase.name,
|
||||||
)
|
)
|
||||||
for device in devices
|
for device in devices
|
||||||
@ -113,7 +113,7 @@ async def async_setup_entry(
|
|||||||
unique_id=f"{device.sn}-{string.name}-{description.key}",
|
unique_id=f"{device.sn}-{string.name}-{description.key}",
|
||||||
description=description,
|
description=description,
|
||||||
inverter_id=device.id,
|
inverter_id=device.id,
|
||||||
device_type="string",
|
device_type=DeviceType.STRING,
|
||||||
deep_name=string.name,
|
deep_name=string.name,
|
||||||
)
|
)
|
||||||
for device in devices
|
for device in devices
|
||||||
@ -137,7 +137,7 @@ class SunWEGInverter(SensorEntity):
|
|||||||
name: str,
|
name: str,
|
||||||
unique_id: str,
|
unique_id: str,
|
||||||
description: SunWEGSensorEntityDescription,
|
description: SunWEGSensorEntityDescription,
|
||||||
device_type: str,
|
device_type: DeviceType,
|
||||||
inverter_id: int = 0,
|
inverter_id: int = 0,
|
||||||
deep_name: str | None = None,
|
deep_name: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -16,7 +16,7 @@ INVERTER_SENSOR_TYPES: tuple[SunWEGSensorEntityDescription, ...] = (
|
|||||||
key="inverter_energy_today",
|
key="inverter_energy_today",
|
||||||
name="Energy today",
|
name="Energy today",
|
||||||
api_variable_key="_today_energy",
|
api_variable_key="_today_energy",
|
||||||
api_variable_metric="_today_energy_metric",
|
api_variable_unit="_today_energy_metric",
|
||||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
device_class=SensorDeviceClass.ENERGY,
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
@ -26,7 +26,7 @@ INVERTER_SENSOR_TYPES: tuple[SunWEGSensorEntityDescription, ...] = (
|
|||||||
key="inverter_energy_total",
|
key="inverter_energy_total",
|
||||||
name="Lifetime energy output",
|
name="Lifetime energy output",
|
||||||
api_variable_key="_total_energy",
|
api_variable_key="_total_energy",
|
||||||
api_variable_metric="_total_energy_metric",
|
api_variable_unit="_total_energy_metric",
|
||||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
device_class=SensorDeviceClass.ENERGY,
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
suggested_display_precision=1,
|
suggested_display_precision=1,
|
||||||
@ -45,7 +45,7 @@ INVERTER_SENSOR_TYPES: tuple[SunWEGSensorEntityDescription, ...] = (
|
|||||||
key="inverter_current_wattage",
|
key="inverter_current_wattage",
|
||||||
name="Output power",
|
name="Output power",
|
||||||
api_variable_key="_power",
|
api_variable_key="_power",
|
||||||
api_variable_metric="_power_metric",
|
api_variable_unit="_power_metric",
|
||||||
native_unit_of_measurement=UnitOfPower.WATT,
|
native_unit_of_measurement=UnitOfPower.WATT,
|
||||||
device_class=SensorDeviceClass.POWER,
|
device_class=SensorDeviceClass.POWER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
@ -17,7 +17,7 @@ class SunWEGRequiredKeysMixin:
|
|||||||
class SunWEGSensorEntityDescription(SensorEntityDescription, SunWEGRequiredKeysMixin):
|
class SunWEGSensorEntityDescription(SensorEntityDescription, SunWEGRequiredKeysMixin):
|
||||||
"""Describes SunWEG sensor entity."""
|
"""Describes SunWEG sensor entity."""
|
||||||
|
|
||||||
api_variable_metric: str | None = None
|
api_variable_unit: str | None = None
|
||||||
previous_value_drop_threshold: float | None = None
|
previous_value_drop_threshold: float | None = None
|
||||||
never_resets: bool = False
|
never_resets: bool = False
|
||||||
icon: str | None = None
|
icon: str | None = None
|
||||||
|
@ -19,7 +19,7 @@ TOTAL_SENSOR_TYPES: tuple[SunWEGSensorEntityDescription, ...] = (
|
|||||||
key="total_energy_today",
|
key="total_energy_today",
|
||||||
name="Energy Today",
|
name="Energy Today",
|
||||||
api_variable_key="_today_energy",
|
api_variable_key="_today_energy",
|
||||||
api_variable_metric="_today_energy_metric",
|
api_variable_unit="_today_energy_metric",
|
||||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
device_class=SensorDeviceClass.ENERGY,
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
|
@ -2553,7 +2553,7 @@ subarulink==0.7.9
|
|||||||
sunwatcher==0.2.1
|
sunwatcher==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.sunweg
|
# homeassistant.components.sunweg
|
||||||
sunweg==2.0.0
|
sunweg==2.0.1
|
||||||
|
|
||||||
# homeassistant.components.surepetcare
|
# homeassistant.components.surepetcare
|
||||||
surepy==0.8.0
|
surepy==0.8.0
|
||||||
|
@ -1917,7 +1917,7 @@ subarulink==0.7.9
|
|||||||
sunwatcher==0.2.1
|
sunwatcher==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.sunweg
|
# homeassistant.components.sunweg
|
||||||
sunweg==2.0.0
|
sunweg==2.0.1
|
||||||
|
|
||||||
# homeassistant.components.surepetcare
|
# homeassistant.components.surepetcare
|
||||||
surepy==0.8.0
|
surepy==0.8.0
|
||||||
|
@ -1,57 +1,15 @@
|
|||||||
"""Common functions needed to setup tests for Sun WEG."""
|
"""Common functions needed to setup tests for Sun WEG."""
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from sunweg.device import MPPT, Inverter, Phase, String
|
|
||||||
from sunweg.plant import Plant
|
|
||||||
|
|
||||||
from homeassistant.components.sunweg.const import CONF_PLANT_ID, DOMAIN
|
from homeassistant.components.sunweg.const import CONF_PLANT_ID, DOMAIN
|
||||||
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
FIXTURE_USER_INPUT = {
|
SUNWEG_USER_INPUT = {
|
||||||
CONF_USERNAME: "username",
|
CONF_USERNAME: "username",
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
}
|
}
|
||||||
|
|
||||||
SUNWEG_PLANT_RESPONSE = Plant(
|
|
||||||
123456,
|
|
||||||
"Plant #123",
|
|
||||||
29.5,
|
|
||||||
0.5,
|
|
||||||
0,
|
|
||||||
12.786912,
|
|
||||||
24.0,
|
|
||||||
"kWh",
|
|
||||||
332.2,
|
|
||||||
0.012296,
|
|
||||||
datetime(2023, 2, 16, 14, 22, 37),
|
|
||||||
)
|
|
||||||
|
|
||||||
SUNWEG_INVERTER_RESPONSE = Inverter(
|
|
||||||
21255,
|
|
||||||
"INVERSOR01",
|
|
||||||
"J63T233018RE074",
|
|
||||||
23.2,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
"MWh",
|
|
||||||
0,
|
|
||||||
"kWh",
|
|
||||||
0.0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
"kW",
|
|
||||||
)
|
|
||||||
|
|
||||||
SUNWEG_PHASE_RESPONSE = Phase("PhaseA", 120.0, 3.2, 0, 0)
|
|
||||||
|
|
||||||
SUNWEG_MPPT_RESPONSE = MPPT("MPPT1")
|
|
||||||
|
|
||||||
SUNWEG_STRING_RESPONSE = String("STR1", 450.3, 23.4, 0)
|
|
||||||
|
|
||||||
SUNWEG_LOGIN_RESPONSE = True
|
|
||||||
|
|
||||||
SUNWEG_MOCK_ENTRY = MockConfigEntry(
|
SUNWEG_MOCK_ENTRY = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
data={
|
data={
|
||||||
|
70
tests/components/sunweg/conftest.py
Normal file
70
tests/components/sunweg/conftest.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
"""Conftest for SunWEG tests."""
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from sunweg.device import MPPT, Inverter, Phase, String
|
||||||
|
from sunweg.plant import Plant
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def string_fixture() -> String:
|
||||||
|
"""Define String fixture."""
|
||||||
|
return String("STR1", 450.3, 23.4, 0)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mppt_fixture(string_fixture) -> MPPT:
|
||||||
|
"""Define MPPT fixture."""
|
||||||
|
mppt = MPPT("mppt")
|
||||||
|
mppt.strings.append(string_fixture)
|
||||||
|
return mppt
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def phase_fixture() -> Phase:
|
||||||
|
"""Define Phase fixture."""
|
||||||
|
return Phase("PhaseA", 120.0, 3.2, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def inverter_fixture(phase_fixture, mppt_fixture) -> Inverter:
|
||||||
|
"""Define inverter fixture."""
|
||||||
|
inverter = Inverter(
|
||||||
|
21255,
|
||||||
|
"INVERSOR01",
|
||||||
|
"J63T233018RE074",
|
||||||
|
23.2,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
"MWh",
|
||||||
|
0,
|
||||||
|
"kWh",
|
||||||
|
0.0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
"kW",
|
||||||
|
)
|
||||||
|
inverter.phases.append(phase_fixture)
|
||||||
|
inverter.mppts.append(mppt_fixture)
|
||||||
|
return inverter
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def plant_fixture(inverter_fixture) -> Plant:
|
||||||
|
"""Define Plant fixture."""
|
||||||
|
plant = Plant(
|
||||||
|
123456,
|
||||||
|
"Plant #123",
|
||||||
|
29.5,
|
||||||
|
0.5,
|
||||||
|
0,
|
||||||
|
12.786912,
|
||||||
|
24.0,
|
||||||
|
"kWh",
|
||||||
|
332.2,
|
||||||
|
0.012296,
|
||||||
|
datetime(2023, 2, 16, 14, 22, 37),
|
||||||
|
)
|
||||||
|
plant.inverters.append(inverter_fixture)
|
||||||
|
return plant
|
@ -1,5 +1,4 @@
|
|||||||
"""Tests for the Sun WEG server config flow."""
|
"""Tests for the Sun WEG server config flow."""
|
||||||
from copy import deepcopy
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from sunweg.api import APIHelper
|
from sunweg.api import APIHelper
|
||||||
@ -9,7 +8,7 @@ from homeassistant.components.sunweg.const import CONF_PLANT_ID, DOMAIN
|
|||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import FIXTURE_USER_INPUT, SUNWEG_LOGIN_RESPONSE, SUNWEG_PLANT_RESPONSE
|
from .common import SUNWEG_USER_INPUT
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ async def test_incorrect_login(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
with patch.object(APIHelper, "authenticate", return_value=False):
|
with patch.object(APIHelper, "authenticate", return_value=False):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], FIXTURE_USER_INPUT
|
result["flow_id"], SUNWEG_USER_INPUT
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
@ -41,34 +40,33 @@ async def test_incorrect_login(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_no_plants_on_account(hass: HomeAssistant) -> None:
|
async def test_no_plants_on_account(hass: HomeAssistant) -> None:
|
||||||
"""Test registering an integration and finishing flow with an entered plant_id."""
|
"""Test registering an integration with no plants available."""
|
||||||
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}
|
||||||
)
|
)
|
||||||
user_input = FIXTURE_USER_INPUT.copy()
|
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(APIHelper, "authenticate", return_value=True), patch.object(
|
||||||
APIHelper, "authenticate", return_value=SUNWEG_LOGIN_RESPONSE
|
APIHelper, "listPlants", return_value=[]
|
||||||
), patch.object(APIHelper, "listPlants", return_value=[]):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input
|
result["flow_id"], SUNWEG_USER_INPUT
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == "abort"
|
assert result["type"] == "abort"
|
||||||
assert result["reason"] == "no_plants"
|
assert result["reason"] == "no_plants"
|
||||||
|
|
||||||
|
|
||||||
async def test_multiple_plant_ids(hass: HomeAssistant) -> None:
|
async def test_multiple_plant_ids(hass: HomeAssistant, plant_fixture) -> None:
|
||||||
"""Test registering an integration and finishing flow with an entered plant_id."""
|
"""Test registering an integration and finishing flow with an selected plant_id."""
|
||||||
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}
|
||||||
)
|
)
|
||||||
user_input = FIXTURE_USER_INPUT.copy()
|
user_input = SUNWEG_USER_INPUT.copy()
|
||||||
plant_list = [deepcopy(SUNWEG_PLANT_RESPONSE), deepcopy(SUNWEG_PLANT_RESPONSE)]
|
plant_list = [plant_fixture, plant_fixture]
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(APIHelper, "authenticate", return_value=True), patch.object(
|
||||||
APIHelper, "authenticate", return_value=SUNWEG_LOGIN_RESPONSE
|
APIHelper, "listPlants", return_value=plant_list
|
||||||
), patch.object(APIHelper, "listPlants", return_value=plant_list):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input
|
result["flow_id"], user_input
|
||||||
)
|
)
|
||||||
@ -82,50 +80,46 @@ async def test_multiple_plant_ids(hass: HomeAssistant) -> None:
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||||
assert result["data"][CONF_USERNAME] == FIXTURE_USER_INPUT[CONF_USERNAME]
|
assert result["data"][CONF_USERNAME] == SUNWEG_USER_INPUT[CONF_USERNAME]
|
||||||
assert result["data"][CONF_PASSWORD] == FIXTURE_USER_INPUT[CONF_PASSWORD]
|
assert result["data"][CONF_PASSWORD] == SUNWEG_USER_INPUT[CONF_PASSWORD]
|
||||||
assert result["data"][CONF_PLANT_ID] == 123456
|
assert result["data"][CONF_PLANT_ID] == 123456
|
||||||
|
|
||||||
|
|
||||||
async def test_one_plant_on_account(hass: HomeAssistant) -> None:
|
async def test_one_plant_on_account(hass: HomeAssistant, plant_fixture) -> None:
|
||||||
"""Test registering an integration and finishing flow with an entered plant_id."""
|
"""Test registering an integration and finishing flow with current plant_id."""
|
||||||
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}
|
||||||
)
|
)
|
||||||
user_input = FIXTURE_USER_INPUT.copy()
|
user_input = SUNWEG_USER_INPUT.copy()
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(APIHelper, "authenticate", return_value=True), patch.object(
|
||||||
APIHelper, "authenticate", return_value=SUNWEG_LOGIN_RESPONSE
|
|
||||||
), patch.object(
|
|
||||||
APIHelper,
|
APIHelper,
|
||||||
"listPlants",
|
"listPlants",
|
||||||
return_value=[deepcopy(SUNWEG_PLANT_RESPONSE)],
|
return_value=[plant_fixture],
|
||||||
):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input
|
result["flow_id"], user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||||
assert result["data"][CONF_USERNAME] == FIXTURE_USER_INPUT[CONF_USERNAME]
|
assert result["data"][CONF_USERNAME] == SUNWEG_USER_INPUT[CONF_USERNAME]
|
||||||
assert result["data"][CONF_PASSWORD] == FIXTURE_USER_INPUT[CONF_PASSWORD]
|
assert result["data"][CONF_PASSWORD] == SUNWEG_USER_INPUT[CONF_PASSWORD]
|
||||||
assert result["data"][CONF_PLANT_ID] == 123456
|
assert result["data"][CONF_PLANT_ID] == 123456
|
||||||
|
|
||||||
|
|
||||||
async def test_existing_plant_configured(hass: HomeAssistant) -> None:
|
async def test_existing_plant_configured(hass: HomeAssistant, plant_fixture) -> None:
|
||||||
"""Test entering an existing plant_id."""
|
"""Test entering an existing plant_id."""
|
||||||
entry = MockConfigEntry(domain=DOMAIN, unique_id=123456)
|
entry = MockConfigEntry(domain=DOMAIN, unique_id=123456)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
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}
|
||||||
)
|
)
|
||||||
user_input = FIXTURE_USER_INPUT.copy()
|
user_input = SUNWEG_USER_INPUT.copy()
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(APIHelper, "authenticate", return_value=True), patch.object(
|
||||||
APIHelper, "authenticate", return_value=SUNWEG_LOGIN_RESPONSE
|
|
||||||
), patch.object(
|
|
||||||
APIHelper,
|
APIHelper,
|
||||||
"listPlants",
|
"listPlants",
|
||||||
return_value=[deepcopy(SUNWEG_PLANT_RESPONSE)],
|
return_value=[plant_fixture],
|
||||||
):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input
|
result["flow_id"], user_input
|
||||||
|
@ -1,51 +1,31 @@
|
|||||||
"""Tests for the Sun WEG init."""
|
"""Tests for the Sun WEG init."""
|
||||||
|
|
||||||
from copy import deepcopy
|
|
||||||
import json
|
import json
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from sunweg.api import APIHelper
|
from sunweg.api import APIHelper, SunWegApiError
|
||||||
from sunweg.device import MPPT, Inverter
|
|
||||||
from sunweg.plant import Plant
|
|
||||||
|
|
||||||
from homeassistant.components.sunweg import SunWEGData
|
from homeassistant.components.sunweg import SunWEGData
|
||||||
from homeassistant.components.sunweg.const import DOMAIN
|
from homeassistant.components.sunweg.const import DOMAIN, DeviceType
|
||||||
from homeassistant.components.sunweg.sensor_types.sensor_entity_description import (
|
from homeassistant.components.sunweg.sensor_types.sensor_entity_description import (
|
||||||
SunWEGSensorEntityDescription,
|
SunWEGSensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .common import (
|
from .common import SUNWEG_MOCK_ENTRY
|
||||||
SUNWEG_INVERTER_RESPONSE,
|
|
||||||
SUNWEG_LOGIN_RESPONSE,
|
|
||||||
SUNWEG_MOCK_ENTRY,
|
|
||||||
SUNWEG_MPPT_RESPONSE,
|
|
||||||
SUNWEG_PHASE_RESPONSE,
|
|
||||||
SUNWEG_PLANT_RESPONSE,
|
|
||||||
SUNWEG_STRING_RESPONSE,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_methods(hass: HomeAssistant) -> None:
|
async def test_methods(hass: HomeAssistant, plant_fixture, inverter_fixture) -> None:
|
||||||
"""Test methods."""
|
"""Test methods."""
|
||||||
mock_entry = SUNWEG_MOCK_ENTRY
|
mock_entry = SUNWEG_MOCK_ENTRY
|
||||||
mock_entry.add_to_hass(hass)
|
mock_entry.add_to_hass(hass)
|
||||||
mppt: MPPT = deepcopy(SUNWEG_MPPT_RESPONSE)
|
|
||||||
mppt.strings.append(SUNWEG_STRING_RESPONSE)
|
|
||||||
inverter: Inverter = deepcopy(SUNWEG_INVERTER_RESPONSE)
|
|
||||||
inverter.phases.append(SUNWEG_PHASE_RESPONSE)
|
|
||||||
inverter.mppts.append(mppt)
|
|
||||||
plant: Plant = deepcopy(SUNWEG_PLANT_RESPONSE)
|
|
||||||
plant.inverters.append(inverter)
|
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(APIHelper, "authenticate", return_value=True), patch.object(
|
||||||
APIHelper, "authenticate", return_value=SUNWEG_LOGIN_RESPONSE
|
APIHelper, "listPlants", return_value=[plant_fixture]
|
||||||
), patch.object(APIHelper, "listPlants", return_value=[plant]), patch.object(
|
), patch.object(APIHelper, "plant", return_value=plant_fixture), patch.object(
|
||||||
APIHelper, "plant", return_value=plant
|
APIHelper, "inverter", return_value=inverter_fixture
|
||||||
), patch.object(APIHelper, "inverter", return_value=inverter), patch.object(
|
), patch.object(APIHelper, "complete_inverter"):
|
||||||
APIHelper, "complete_inverter"
|
|
||||||
):
|
|
||||||
assert await async_setup_component(hass, DOMAIN, mock_entry.data)
|
assert await async_setup_component(hass, DOMAIN, mock_entry.data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert await hass.config_entries.async_unload(mock_entry.entry_id)
|
assert await hass.config_entries.async_unload(mock_entry.entry_id)
|
||||||
@ -60,6 +40,17 @@ async def test_setup_wrongpass(hass: HomeAssistant) -> None:
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_error_500(hass: HomeAssistant) -> None:
|
||||||
|
"""Test setup with wrong pass."""
|
||||||
|
mock_entry = SUNWEG_MOCK_ENTRY
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
with patch.object(
|
||||||
|
APIHelper, "authenticate", side_effect=SunWegApiError("Error 500")
|
||||||
|
):
|
||||||
|
assert await async_setup_component(hass, DOMAIN, mock_entry.data)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
async def test_sunwegdata_update_exception() -> None:
|
async def test_sunwegdata_update_exception() -> None:
|
||||||
"""Test SunWEGData exception on update."""
|
"""Test SunWEGData exception on update."""
|
||||||
api = MagicMock()
|
api = MagicMock()
|
||||||
@ -69,33 +60,29 @@ async def test_sunwegdata_update_exception() -> None:
|
|||||||
assert data.data is None
|
assert data.data is None
|
||||||
|
|
||||||
|
|
||||||
async def test_sunwegdata_update_success() -> None:
|
async def test_sunwegdata_update_success(plant_fixture) -> None:
|
||||||
"""Test SunWEGData success on update."""
|
"""Test SunWEGData success on update."""
|
||||||
inverter: Inverter = deepcopy(SUNWEG_INVERTER_RESPONSE)
|
|
||||||
plant: Plant = deepcopy(SUNWEG_PLANT_RESPONSE)
|
|
||||||
plant.inverters.append(inverter)
|
|
||||||
api = MagicMock()
|
api = MagicMock()
|
||||||
api.plant = MagicMock(return_value=plant)
|
api.plant = MagicMock(return_value=plant_fixture)
|
||||||
api.complete_inverter = MagicMock()
|
api.complete_inverter = MagicMock()
|
||||||
data = SunWEGData(api, 0)
|
data = SunWEGData(api, 0)
|
||||||
data.update()
|
data.update()
|
||||||
assert data.data.id == plant.id
|
assert data.data.id == plant_fixture.id
|
||||||
assert data.data.name == plant.name
|
assert data.data.name == plant_fixture.name
|
||||||
assert data.data.kwh_per_kwp == plant.kwh_per_kwp
|
assert data.data.kwh_per_kwp == plant_fixture.kwh_per_kwp
|
||||||
assert data.data.last_update == plant.last_update
|
assert data.data.last_update == plant_fixture.last_update
|
||||||
assert data.data.performance_rate == plant.performance_rate
|
assert data.data.performance_rate == plant_fixture.performance_rate
|
||||||
assert data.data.saving == plant.saving
|
assert data.data.saving == plant_fixture.saving
|
||||||
assert len(data.data.inverters) == 1
|
assert len(data.data.inverters) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_sunwegdata_get_api_value_none() -> None:
|
async def test_sunwegdata_get_api_value_none(plant_fixture) -> None:
|
||||||
"""Test SunWEGData none return on get_api_value."""
|
"""Test SunWEGData none return on get_api_value."""
|
||||||
api = MagicMock()
|
api = MagicMock()
|
||||||
data = SunWEGData(api, 123456)
|
data = SunWEGData(api, 123456)
|
||||||
data.data = deepcopy(SUNWEG_PLANT_RESPONSE)
|
data.data = plant_fixture
|
||||||
assert data.get_api_value("variable", "inverter", 0, "deep_name") is None
|
assert data.get_api_value("variable", DeviceType.INVERTER, 0, "deep_name") is None
|
||||||
data.data.inverters.append(deepcopy(SUNWEG_INVERTER_RESPONSE))
|
assert data.get_api_value("variable", DeviceType.STRING, 21255, "deep_name") is None
|
||||||
assert data.get_api_value("variable", "invalid type", 21255, "deep_name") is None
|
|
||||||
|
|
||||||
|
|
||||||
async def test_sunwegdata_get_data_drop_threshold() -> None:
|
async def test_sunwegdata_get_data_drop_threshold() -> None:
|
||||||
@ -109,15 +96,24 @@ async def test_sunwegdata_get_data_drop_threshold() -> None:
|
|||||||
entity_description.previous_value_drop_threshold = 0.1
|
entity_description.previous_value_drop_threshold = 0.1
|
||||||
data.get_api_value.return_value = 3.0
|
data.get_api_value.return_value = 3.0
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 3.0
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 3.0
|
||||||
)
|
)
|
||||||
data.get_api_value.return_value = 2.91
|
data.get_api_value.return_value = 2.91
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 3.0
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 3.0
|
||||||
)
|
)
|
||||||
data.get_api_value.return_value = 2.8
|
data.get_api_value.return_value = 2.8
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 2.8
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 2.8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -132,13 +128,22 @@ async def test_sunwegdata_get_data_never_reset() -> None:
|
|||||||
entity_description.never_resets = True
|
entity_description.never_resets = True
|
||||||
data.get_api_value.return_value = 3.0
|
data.get_api_value.return_value = 3.0
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 3.0
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 3.0
|
||||||
)
|
)
|
||||||
data.get_api_value.return_value = 0
|
data.get_api_value.return_value = 0
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 3.0
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 3.0
|
||||||
)
|
)
|
||||||
data.get_api_value.return_value = 2.8
|
data.get_api_value.return_value = 2.8
|
||||||
assert (
|
assert (
|
||||||
data.get_data(entity_description=entity_description, device_type="total") == 2.8
|
data.get_data(
|
||||||
|
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||||
|
)
|
||||||
|
== 2.8
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user