Discard Solaredge updates for invalid overview data (#68048)
parent
1f2bfcf12e
commit
04bb156e99
|
@ -77,8 +77,9 @@ class SolarEdgeOverviewDataService(SolarEdgeDataService):
|
|||
|
||||
self.data = {}
|
||||
|
||||
energy_keys = ["lifeTimeData", "lastYearData", "lastMonthData", "lastDayData"]
|
||||
for key, value in overview.items():
|
||||
if key in ["lifeTimeData", "lastYearData", "lastMonthData", "lastDayData"]:
|
||||
if key in energy_keys:
|
||||
data = value["energy"]
|
||||
elif key in ["currentPower"]:
|
||||
data = value["power"]
|
||||
|
@ -86,6 +87,16 @@ class SolarEdgeOverviewDataService(SolarEdgeDataService):
|
|||
data = value
|
||||
self.data[key] = data
|
||||
|
||||
# Sanity check the energy values. SolarEdge API sometimes report "lifetimedata" of zero,
|
||||
# while values for last Year, Month and Day energy are still OK.
|
||||
# See https://github.com/home-assistant/core/issues/59285 .
|
||||
if set(energy_keys).issubset(self.data.keys()):
|
||||
for index, key in enumerate(energy_keys, start=1):
|
||||
# All coming values in list should be larger than the current value.
|
||||
if any(self.data[k] > self.data[key] for k in energy_keys[index:]):
|
||||
self.data = {}
|
||||
raise UpdateFailed("Invalid energy values, skipping update")
|
||||
|
||||
LOGGER.debug("Updated SolarEdge overview: %s", self.data)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
"""Tests for the SolarEdge coordinator services."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.solaredge.const import (
|
||||
CONF_SITE_ID,
|
||||
DEFAULT_NAME,
|
||||
DOMAIN,
|
||||
OVERVIEW_UPDATE_DELAY,
|
||||
)
|
||||
from homeassistant.const import CONF_API_KEY, CONF_NAME, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
SITE_ID = "1a2b3c4d5e6f7g8h"
|
||||
API_KEY = "a1b2c3d4e5f6g7h8"
|
||||
|
||||
|
||||
@patch("homeassistant.components.solaredge.Solaredge")
|
||||
async def test_solaredgeoverviewdataservice_energy_values_validity(
|
||||
mock_solaredge, hass: HomeAssistant
|
||||
):
|
||||
"""Test overview energy data validity."""
|
||||
mock_config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title=DEFAULT_NAME,
|
||||
data={CONF_NAME: DEFAULT_NAME, CONF_SITE_ID: SITE_ID, CONF_API_KEY: API_KEY},
|
||||
)
|
||||
mock_solaredge().get_details.return_value = {"details": {"status": "active"}}
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
# Valid energy values update
|
||||
mock_overview_data = {
|
||||
"overview": {
|
||||
"lifeTimeData": {"energy": 100000},
|
||||
"lastYearData": {"energy": 50000},
|
||||
"lastMonthData": {"energy": 10000},
|
||||
"lastDayData": {"energy": 0.0},
|
||||
"currentPower": {"power": 0.0},
|
||||
}
|
||||
}
|
||||
mock_solaredge().get_overview.return_value = mock_overview_data
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + OVERVIEW_UPDATE_DELAY)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("sensor.solaredge_lifetime_energy")
|
||||
assert state
|
||||
assert state.state == str(mock_overview_data["overview"]["lifeTimeData"]["energy"])
|
||||
|
||||
# Invalid energy values, lifeTimeData energy is lower than last year, month or day.
|
||||
mock_overview_data["overview"]["lifeTimeData"]["energy"] = 0
|
||||
mock_solaredge().get_overview.return_value = mock_overview_data
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + OVERVIEW_UPDATE_DELAY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.solaredge_lifetime_energy")
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
# New valid energy values update
|
||||
mock_overview_data["overview"]["lifeTimeData"]["energy"] = 100001
|
||||
mock_solaredge().get_overview.return_value = mock_overview_data
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + OVERVIEW_UPDATE_DELAY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.solaredge_lifetime_energy")
|
||||
assert state
|
||||
assert state.state == str(mock_overview_data["overview"]["lifeTimeData"]["energy"])
|
||||
|
||||
# Invalid energy values, lastYearData energy is lower than last month or day.
|
||||
mock_overview_data["overview"]["lastYearData"]["energy"] = 0
|
||||
mock_solaredge().get_overview.return_value = mock_overview_data
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + OVERVIEW_UPDATE_DELAY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.solaredge_lifetime_energy")
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
# All zero energy values should also be valid.
|
||||
mock_overview_data["overview"]["lifeTimeData"]["energy"] = 0.0
|
||||
mock_overview_data["overview"]["lastYearData"]["energy"] = 0.0
|
||||
mock_overview_data["overview"]["lastMonthData"]["energy"] = 0.0
|
||||
mock_overview_data["overview"]["lastDayData"]["energy"] = 0.0
|
||||
mock_solaredge().get_overview.return_value = mock_overview_data
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + OVERVIEW_UPDATE_DELAY)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.solaredge_lifetime_energy")
|
||||
assert state
|
||||
assert state.state == str(mock_overview_data["overview"]["lifeTimeData"]["energy"])
|
Loading…
Reference in New Issue