Move vizio coordinator to separate module (#117498)
This commit is contained in:
parent
3604a34823
commit
2c6071820e
5 changed files with 75 additions and 63 deletions
|
@ -2,12 +2,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import timedelta
|
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from pyvizio.const import APPS
|
|
||||||
from pyvizio.util import gen_apps_list_from_url
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.media_player import MediaPlayerDeviceClass
|
from homeassistant.components.media_player import MediaPlayerDeviceClass
|
||||||
|
@ -15,14 +11,11 @@ from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry, ConfigEntry
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
||||||
from homeassistant.helpers.storage import Store
|
from homeassistant.helpers.storage import Store
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
|
||||||
|
|
||||||
from .const import CONF_APPS, CONF_DEVICE_CLASS, DOMAIN, VIZIO_SCHEMA
|
from .const import CONF_APPS, CONF_DEVICE_CLASS, DOMAIN, VIZIO_SCHEMA
|
||||||
|
from .coordinator import VizioAppsDataUpdateCoordinator
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_apps(config: ConfigType) -> ConfigType:
|
def validate_apps(config: ConfigType) -> ConfigType:
|
||||||
|
@ -96,53 +89,3 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||||
hass.data.pop(DOMAIN)
|
hass.data.pop(DOMAIN)
|
||||||
|
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
class VizioAppsDataUpdateCoordinator(DataUpdateCoordinator[list[dict[str, Any]]]): # pylint: disable=hass-enforce-coordinator-module
|
|
||||||
"""Define an object to hold Vizio app config data."""
|
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, store: Store[list[dict[str, Any]]]) -> None:
|
|
||||||
"""Initialize."""
|
|
||||||
super().__init__(
|
|
||||||
hass,
|
|
||||||
_LOGGER,
|
|
||||||
name=DOMAIN,
|
|
||||||
update_interval=timedelta(days=1),
|
|
||||||
)
|
|
||||||
self.fail_count = 0
|
|
||||||
self.fail_threshold = 10
|
|
||||||
self.store = store
|
|
||||||
|
|
||||||
async def async_config_entry_first_refresh(self) -> None:
|
|
||||||
"""Refresh data for the first time when a config entry is setup."""
|
|
||||||
self.data = await self.store.async_load() or APPS
|
|
||||||
await super().async_config_entry_first_refresh()
|
|
||||||
|
|
||||||
async def _async_update_data(self) -> list[dict[str, Any]]:
|
|
||||||
"""Update data via library."""
|
|
||||||
if data := await gen_apps_list_from_url(
|
|
||||||
session=async_get_clientsession(self.hass)
|
|
||||||
):
|
|
||||||
# Reset the fail count and threshold when the data is successfully retrieved
|
|
||||||
self.fail_count = 0
|
|
||||||
self.fail_threshold = 10
|
|
||||||
# Store the new data if it has changed so we have it for the next restart
|
|
||||||
if data != self.data:
|
|
||||||
await self.store.async_save(data)
|
|
||||||
return data
|
|
||||||
# For every failure, increase the fail count until we reach the threshold.
|
|
||||||
# We then log a warning, increase the threshold, and reset the fail count.
|
|
||||||
# This is here to prevent silent failures but to reduce repeat logs.
|
|
||||||
if self.fail_count == self.fail_threshold:
|
|
||||||
_LOGGER.warning(
|
|
||||||
(
|
|
||||||
"Unable to retrieve the apps list from the external server for the "
|
|
||||||
"last %s days"
|
|
||||||
),
|
|
||||||
self.fail_threshold,
|
|
||||||
)
|
|
||||||
self.fail_count = 0
|
|
||||||
self.fail_threshold += 10
|
|
||||||
else:
|
|
||||||
self.fail_count += 1
|
|
||||||
return self.data
|
|
||||||
|
|
69
homeassistant/components/vizio/coordinator.py
Normal file
69
homeassistant/components/vizio/coordinator.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
"""Coordinator for the vizio component."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pyvizio.const import APPS
|
||||||
|
from pyvizio.util import gen_apps_list_from_url
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
from homeassistant.helpers.storage import Store
|
||||||
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VizioAppsDataUpdateCoordinator(DataUpdateCoordinator[list[dict[str, Any]]]):
|
||||||
|
"""Define an object to hold Vizio app config data."""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, store: Store[list[dict[str, Any]]]) -> None:
|
||||||
|
"""Initialize."""
|
||||||
|
super().__init__(
|
||||||
|
hass,
|
||||||
|
_LOGGER,
|
||||||
|
name=DOMAIN,
|
||||||
|
update_interval=timedelta(days=1),
|
||||||
|
)
|
||||||
|
self.fail_count = 0
|
||||||
|
self.fail_threshold = 10
|
||||||
|
self.store = store
|
||||||
|
|
||||||
|
async def async_config_entry_first_refresh(self) -> None:
|
||||||
|
"""Refresh data for the first time when a config entry is setup."""
|
||||||
|
self.data = await self.store.async_load() or APPS
|
||||||
|
await super().async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
async def _async_update_data(self) -> list[dict[str, Any]]:
|
||||||
|
"""Update data via library."""
|
||||||
|
if data := await gen_apps_list_from_url(
|
||||||
|
session=async_get_clientsession(self.hass)
|
||||||
|
):
|
||||||
|
# Reset the fail count and threshold when the data is successfully retrieved
|
||||||
|
self.fail_count = 0
|
||||||
|
self.fail_threshold = 10
|
||||||
|
# Store the new data if it has changed so we have it for the next restart
|
||||||
|
if data != self.data:
|
||||||
|
await self.store.async_save(data)
|
||||||
|
return data
|
||||||
|
# For every failure, increase the fail count until we reach the threshold.
|
||||||
|
# We then log a warning, increase the threshold, and reset the fail count.
|
||||||
|
# This is here to prevent silent failures but to reduce repeat logs.
|
||||||
|
if self.fail_count == self.fail_threshold:
|
||||||
|
_LOGGER.warning(
|
||||||
|
(
|
||||||
|
"Unable to retrieve the apps list from the external server for the "
|
||||||
|
"last %s days"
|
||||||
|
),
|
||||||
|
self.fail_threshold,
|
||||||
|
)
|
||||||
|
self.fail_count = 0
|
||||||
|
self.fail_threshold += 10
|
||||||
|
else:
|
||||||
|
self.fail_count += 1
|
||||||
|
return self.data
|
|
@ -34,7 +34,6 @@ from homeassistant.helpers.dispatcher import (
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import VizioAppsDataUpdateCoordinator
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_ADDITIONAL_CONFIGS,
|
CONF_ADDITIONAL_CONFIGS,
|
||||||
CONF_APPS,
|
CONF_APPS,
|
||||||
|
@ -53,6 +52,7 @@ from .const import (
|
||||||
VIZIO_SOUND_MODE,
|
VIZIO_SOUND_MODE,
|
||||||
VIZIO_VOLUME,
|
VIZIO_VOLUME,
|
||||||
)
|
)
|
||||||
|
from .coordinator import VizioAppsDataUpdateCoordinator
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ def vizio_get_unique_id_fixture():
|
||||||
def vizio_data_coordinator_update_fixture():
|
def vizio_data_coordinator_update_fixture():
|
||||||
"""Mock get data coordinator update."""
|
"""Mock get data coordinator update."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vizio.gen_apps_list_from_url",
|
"homeassistant.components.vizio.coordinator.gen_apps_list_from_url",
|
||||||
return_value=APP_LIST,
|
return_value=APP_LIST,
|
||||||
):
|
):
|
||||||
yield
|
yield
|
||||||
|
@ -64,7 +64,7 @@ def vizio_data_coordinator_update_fixture():
|
||||||
def vizio_data_coordinator_update_failure_fixture():
|
def vizio_data_coordinator_update_failure_fixture():
|
||||||
"""Mock get data coordinator update failure."""
|
"""Mock get data coordinator update failure."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vizio.gen_apps_list_from_url",
|
"homeassistant.components.vizio.coordinator.gen_apps_list_from_url",
|
||||||
return_value=None,
|
return_value=None,
|
||||||
):
|
):
|
||||||
yield
|
yield
|
||||||
|
|
|
@ -745,7 +745,7 @@ async def test_apps_update(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test device setup with apps where no app is running."""
|
"""Test device setup with apps where no app is running."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vizio.gen_apps_list_from_url",
|
"homeassistant.components.vizio.coordinator.gen_apps_list_from_url",
|
||||||
return_value=None,
|
return_value=None,
|
||||||
):
|
):
|
||||||
async with _cm_for_test_setup_tv_with_apps(
|
async with _cm_for_test_setup_tv_with_apps(
|
||||||
|
@ -758,7 +758,7 @@ async def test_apps_update(
|
||||||
assert len(apps) == len(APPS)
|
assert len(apps) == len(APPS)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vizio.gen_apps_list_from_url",
|
"homeassistant.components.vizio.coordinator.gen_apps_list_from_url",
|
||||||
return_value=APP_LIST,
|
return_value=APP_LIST,
|
||||||
):
|
):
|
||||||
async_fire_time_changed(hass, dt_util.now() + timedelta(days=2))
|
async_fire_time_changed(hass, dt_util.now() + timedelta(days=2))
|
||||||
|
|
Loading…
Add table
Reference in a new issue