mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Avoid mutating entity descriptions in sunweg (#105982)
This commit is contained in:
parent
27f81b3f63
commit
1d1cd6be57
@ -10,11 +10,10 @@ from homeassistant import config_entries
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.helpers.typing import StateType, UndefinedType
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from .const import CONF_PLANT_ID, DOMAIN, PLATFORMS, DeviceType
|
||||
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
||||
|
||||
SCAN_INTERVAL = datetime.timedelta(minutes=5)
|
||||
|
||||
@ -102,24 +101,30 @@ class SunWEGData:
|
||||
|
||||
def get_data(
|
||||
self,
|
||||
entity_description: SunWEGSensorEntityDescription,
|
||||
*,
|
||||
api_variable_key: str,
|
||||
api_variable_unit: str | None,
|
||||
deep_name: str | None,
|
||||
device_type: DeviceType,
|
||||
inverter_id: int = 0,
|
||||
deep_name: str | None = None,
|
||||
) -> StateType | datetime.datetime:
|
||||
inverter_id: int,
|
||||
name: str | UndefinedType | None,
|
||||
native_unit_of_measurement: str | None,
|
||||
never_resets: bool,
|
||||
previous_value_drop_threshold: float | None,
|
||||
) -> tuple[StateType | datetime.datetime, str | None]:
|
||||
"""Get the data."""
|
||||
_LOGGER.debug(
|
||||
"Data request for: %s",
|
||||
entity_description.name,
|
||||
name,
|
||||
)
|
||||
variable = entity_description.api_variable_key
|
||||
previous_unit = entity_description.native_unit_of_measurement
|
||||
variable = api_variable_key
|
||||
previous_unit = native_unit_of_measurement
|
||||
api_value = self.get_api_value(variable, device_type, inverter_id, deep_name)
|
||||
previous_value = self.previous_values.get(variable)
|
||||
return_value = api_value
|
||||
if entity_description.api_variable_unit is not None:
|
||||
entity_description.native_unit_of_measurement = self.get_api_value(
|
||||
entity_description.api_variable_unit,
|
||||
if api_variable_unit is not None:
|
||||
native_unit_of_measurement = self.get_api_value(
|
||||
api_variable_unit,
|
||||
device_type,
|
||||
inverter_id,
|
||||
deep_name,
|
||||
@ -127,18 +132,18 @@ class SunWEGData:
|
||||
|
||||
# If we have a 'drop threshold' specified, then check it and correct if needed
|
||||
if (
|
||||
entity_description.previous_value_drop_threshold is not None
|
||||
previous_value_drop_threshold is not None
|
||||
and previous_value is not None
|
||||
and api_value is not None
|
||||
and previous_unit == entity_description.native_unit_of_measurement
|
||||
and previous_unit == native_unit_of_measurement
|
||||
):
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"%s - Drop threshold specified (%s), checking for drop... API"
|
||||
" Value: %s, Previous Value: %s"
|
||||
),
|
||||
entity_description.name,
|
||||
entity_description.previous_value_drop_threshold,
|
||||
name,
|
||||
previous_value_drop_threshold,
|
||||
api_value,
|
||||
previous_value,
|
||||
)
|
||||
@ -149,7 +154,7 @@ class SunWEGData:
|
||||
# Note - The energy dashboard takes care of drops within 10%
|
||||
# of the current value, however if the value is low e.g. 0.2
|
||||
# and drops by 0.1 it classes as a reset.
|
||||
if -(entity_description.previous_value_drop_threshold) <= diff < 0:
|
||||
if -(previous_value_drop_threshold) <= diff < 0:
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Diff is negative, but only by a small amount therefore not a"
|
||||
@ -161,9 +166,7 @@ class SunWEGData:
|
||||
)
|
||||
return_value = previous_value
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"%s - No drop detected, using API value", entity_description.name
|
||||
)
|
||||
_LOGGER.debug("%s - No drop detected, using API value", name)
|
||||
|
||||
# Lifetime total values should always be increasing, they will never reset,
|
||||
# however the API sometimes returns 0 values when the clock turns to 00:00
|
||||
@ -178,7 +181,7 @@ class SunWEGData:
|
||||
# - Previous value will not exist meaning 0 will be returned
|
||||
# - This is an edge case that would be better handled by looking
|
||||
# up the previous value of the entity from the recorder
|
||||
if entity_description.never_resets and api_value == 0 and previous_value:
|
||||
if never_resets and api_value == 0 and previous_value:
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"API value is 0, but this value should never reset, returning"
|
||||
@ -190,4 +193,4 @@ class SunWEGData:
|
||||
|
||||
self.previous_values[variable] = return_value
|
||||
|
||||
return return_value
|
||||
return (return_value, native_unit_of_measurement)
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""Read status of SunWEG inverters."""
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
from types import MappingProxyType
|
||||
from typing import Any
|
||||
@ -16,7 +15,6 @@ from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from . import SunWEGData
|
||||
from .const import CONF_PLANT_ID, DEFAULT_PLANT_ID, DOMAIN, DeviceType
|
||||
@ -160,18 +158,20 @@ class SunWEGInverter(SensorEntity):
|
||||
name=name,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(
|
||||
self,
|
||||
) -> StateType | datetime.datetime:
|
||||
"""Return the state of the sensor."""
|
||||
return self.probe.get_data(
|
||||
self.entity_description,
|
||||
device_type=self.device_type,
|
||||
inverter_id=self.inverter_id,
|
||||
deep_name=self.deep_name,
|
||||
)
|
||||
|
||||
def update(self) -> None:
|
||||
"""Get the latest data from the Sun WEG API and updates the state."""
|
||||
self.probe.update()
|
||||
(
|
||||
self._attr_native_value,
|
||||
self._attr_native_unit_of_measurement,
|
||||
) = self.probe.get_data(
|
||||
api_variable_key=self.entity_description.api_variable_key,
|
||||
api_variable_unit=self.entity_description.api_variable_unit,
|
||||
deep_name=self.deep_name,
|
||||
device_type=self.device_type,
|
||||
inverter_id=self.inverter_id,
|
||||
name=self.entity_description.name,
|
||||
native_unit_of_measurement=self.native_unit_of_measurement,
|
||||
never_resets=self.entity_description.never_resets,
|
||||
previous_value_drop_threshold=self.entity_description.previous_value_drop_threshold,
|
||||
)
|
||||
|
@ -95,26 +95,41 @@ async def test_sunwegdata_get_data_drop_threshold() -> None:
|
||||
)
|
||||
entity_description.previous_value_drop_threshold = 0.1
|
||||
data.get_api_value.return_value = 3.0
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 3.0
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (3.0, None)
|
||||
data.get_api_value.return_value = 2.91
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 3.0
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (3.0, None)
|
||||
data.get_api_value.return_value = 2.8
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 2.8
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (2.8, None)
|
||||
|
||||
|
||||
async def test_sunwegdata_get_data_never_reset() -> None:
|
||||
@ -127,23 +142,38 @@ async def test_sunwegdata_get_data_never_reset() -> None:
|
||||
)
|
||||
entity_description.never_resets = True
|
||||
data.get_api_value.return_value = 3.0
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 3.0
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (3.0, None)
|
||||
data.get_api_value.return_value = 0
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 3.0
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (3.0, None)
|
||||
data.get_api_value.return_value = 2.8
|
||||
assert (
|
||||
data.get_data(
|
||||
entity_description=entity_description, device_type=DeviceType.TOTAL
|
||||
)
|
||||
== 2.8
|
||||
)
|
||||
assert data.get_data(
|
||||
api_variable_key=entity_description.api_variable_key,
|
||||
api_variable_unit=entity_description.api_variable_unit,
|
||||
deep_name=None,
|
||||
device_type=DeviceType.TOTAL,
|
||||
inverter_id=0,
|
||||
name=entity_description.name,
|
||||
native_unit_of_measurement=entity_description.native_unit_of_measurement,
|
||||
never_resets=entity_description.never_resets,
|
||||
previous_value_drop_threshold=entity_description.previous_value_drop_threshold,
|
||||
) == (2.8, None)
|
||||
|
Loading…
x
Reference in New Issue
Block a user