Support reloading the universal platform (#39248)

This commit is contained in:
J. Nick Koston 2020-08-25 17:25:15 -05:00 committed by GitHub
parent 63ebea1706
commit 90842fcb84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 300 additions and 82 deletions

View file

@ -2,65 +2,26 @@
import logging import logging
from homeassistant import config as conf_util
from homeassistant.const import SERVICE_RELOAD from homeassistant.const import SERVICE_RELOAD
from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.reload import async_reload_integration_platforms
from homeassistant.helpers import config_per_platform, entity_platform
from homeassistant.loader import async_get_integration
from .const import DOMAIN, EVENT_TEMPLATE_RELOADED, PLATFORM_STORAGE_KEY from .const import DOMAIN, EVENT_TEMPLATE_RELOADED, PLATFORMS
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def _async_setup_reload_service(hass): async def async_setup_reload_service(hass):
"""Create the reload service for the template domain."""
if hass.services.has_service(DOMAIN, SERVICE_RELOAD): if hass.services.has_service(DOMAIN, SERVICE_RELOAD):
return return
async def _reload_config(call): async def _reload_config(call):
"""Reload the template platform config.""" """Reload the template platform config."""
try: await async_reload_integration_platforms(hass, DOMAIN, PLATFORMS)
unprocessed_conf = await conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err:
_LOGGER.error(err)
return
for platform in hass.data[PLATFORM_STORAGE_KEY]:
integration = await async_get_integration(hass, platform.domain)
conf = await conf_util.async_process_component_config(
hass, unprocessed_conf, integration
)
if not conf:
continue
await platform.async_reset()
# Extract only the config for template, ignore the rest.
for p_type, p_config in config_per_platform(conf, platform.domain):
if p_type != DOMAIN:
continue
entities = await platform.platform.async_create_entities(hass, p_config)
await platform.async_add_entities(entities)
hass.bus.async_fire(EVENT_TEMPLATE_RELOADED, context=call.context) hass.bus.async_fire(EVENT_TEMPLATE_RELOADED, context=call.context)
hass.helpers.service.async_register_admin_service( hass.helpers.service.async_register_admin_service(
DOMAIN, SERVICE_RELOAD, _reload_config DOMAIN, SERVICE_RELOAD, _reload_config
) )
async def async_setup_platform_reloadable(hass):
"""Template platform with reloadability."""
await _async_setup_reload_service(hass)
platform = entity_platform.current_platform.get()
if platform not in hass.data.setdefault(PLATFORM_STORAGE_KEY, []):
hass.data[PLATFORM_STORAGE_KEY].append(platform)

View file

@ -33,7 +33,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -76,7 +76,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create Template Alarm Control Panels.""" """Create Template Alarm Control Panels."""
alarm_control_panels = [] alarm_control_panels = []
@ -112,8 +112,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Template Alarm Control Panels.""" """Set up the Template Alarm Control Panels."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity):

View file

@ -26,7 +26,7 @@ from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.template import result_as_boolean from homeassistant.helpers.template import result_as_boolean
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -57,7 +57,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the template binary sensors.""" """Create the template binary sensors."""
sensors = [] sensors = []
@ -97,8 +97,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template binary sensors.""" """Set up the template binary sensors."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class BinarySensorTemplate(TemplateEntity, BinarySensorEntity): class BinarySensorTemplate(TemplateEntity, BinarySensorEntity):

View file

@ -7,3 +7,15 @@ DOMAIN = "template"
PLATFORM_STORAGE_KEY = "template_platforms" PLATFORM_STORAGE_KEY = "template_platforms"
EVENT_TEMPLATE_RELOADED = "event_template_reloaded" EVENT_TEMPLATE_RELOADED = "event_template_reloaded"
PLATFORMS = [
"alarm_control_panel",
"binary_sensor",
"cover",
"fan",
"light",
"lock",
"sensor",
"switch",
"vacuum",
]

View file

@ -37,7 +37,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -100,7 +100,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template cover.""" """Create the Template cover."""
covers = [] covers = []
@ -152,8 +152,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Template cover.""" """Set up the Template cover."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class CoverTemplate(TemplateEntity, CoverEntity): class CoverTemplate(TemplateEntity, CoverEntity):

View file

@ -34,7 +34,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -81,7 +81,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template Fans.""" """Create the Template Fans."""
fans = [] fans = []
@ -129,8 +129,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template fans.""" """Set up the template fans."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class TemplateFan(TemplateEntity, FanEntity): class TemplateFan(TemplateEntity, FanEntity):

View file

@ -33,7 +33,7 @@ from homeassistant.helpers.config_validation import PLATFORM_SCHEMA
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -78,7 +78,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template Lights.""" """Create the Template Lights."""
lights = [] lights = []
@ -135,8 +135,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template lights.""" """Set up the template lights."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class LightTemplate(TemplateEntity, LightEntity): class LightTemplate(TemplateEntity, LightEntity):

View file

@ -17,7 +17,7 @@ from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -42,7 +42,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template lock.""" """Create the Template lock."""
device = config.get(CONF_NAME) device = config.get(CONF_NAME)
value_template = config.get(CONF_VALUE_TEMPLATE) value_template = config.get(CONF_VALUE_TEMPLATE)
@ -65,8 +65,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template lock.""" """Set up the template lock."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class TemplateLock(TemplateEntity, LockEntity): class TemplateLock(TemplateEntity, LockEntity):

View file

@ -26,7 +26,7 @@ from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity, async_generate_entity_id from homeassistant.helpers.entity import Entity, async_generate_entity_id
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -57,7 +57,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the template sensors.""" """Create the template sensors."""
sensors = [] sensors = []
@ -97,8 +97,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template sensors.""" """Set up the template sensors."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class SensorTemplate(TemplateEntity, Entity): class SensorTemplate(TemplateEntity, Entity):

View file

@ -26,7 +26,7 @@ from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -55,7 +55,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template switches.""" """Create the Template switches."""
switches = [] switches = []
@ -90,8 +90,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template switches.""" """Set up the template switches."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity): class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity):

View file

@ -43,7 +43,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.script import Script from homeassistant.helpers.script import Script
from . import async_setup_platform_reloadable from . import async_setup_reload_service
from .const import CONF_AVAILABILITY_TEMPLATE from .const import CONF_AVAILABILITY_TEMPLATE
from .template_entity import TemplateEntity from .template_entity import TemplateEntity
@ -93,7 +93,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
) )
async def async_create_entities(hass, config): async def _async_create_entities(hass, config):
"""Create the Template Vacuums.""" """Create the Template Vacuums."""
vacuums = [] vacuums = []
@ -145,8 +145,8 @@ async def async_create_entities(hass, config):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template vacuums.""" """Set up the template vacuums."""
await async_setup_platform_reloadable(hass) await async_setup_reload_service(hass)
async_add_entities(await async_create_entities(hass, config)) async_add_entities(await _async_create_entities(hass, config))
class TemplateVacuum(TemplateEntity, StateVacuumEntity): class TemplateVacuum(TemplateEntity, StateVacuumEntity):

View file

@ -56,6 +56,7 @@ from homeassistant.const import (
SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_PREVIOUS_TRACK,
SERVICE_MEDIA_SEEK, SERVICE_MEDIA_SEEK,
SERVICE_MEDIA_STOP, SERVICE_MEDIA_STOP,
SERVICE_RELOAD,
SERVICE_SHUFFLE_SET, SERVICE_SHUFFLE_SET,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
SERVICE_TURN_ON, SERVICE_TURN_ON,
@ -71,6 +72,7 @@ from homeassistant.const import (
from homeassistant.core import EVENT_HOMEASSISTANT_START, callback from homeassistant.core import EVENT_HOMEASSISTANT_START, callback
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.reload import async_reload_integration_platforms
from homeassistant.helpers.service import async_call_from_config from homeassistant.helpers.service import async_call_from_config
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -102,9 +104,31 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
extra=vol.REMOVE_EXTRA, extra=vol.REMOVE_EXTRA,
) )
EVENT_UNIVERSAL_RELOADED = "event_universal_reloaded"
async def async_setup_reload_service(hass):
"""Create the reload service for the universal domain."""
if hass.services.has_service("universal", SERVICE_RELOAD):
return
async def _reload_config(call):
"""Reload the template universal config."""
await async_reload_integration_platforms(hass, "universal", ["media_player"])
hass.bus.async_fire(EVENT_UNIVERSAL_RELOADED, context=call.context)
hass.helpers.service.async_register_admin_service(
"universal", SERVICE_RELOAD, _reload_config
)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the universal media players.""" """Set up the universal media players."""
await async_setup_reload_service(hass)
player = UniversalMediaPlayer( player = UniversalMediaPlayer(
hass, hass,
config.get(CONF_NAME), config.get(CONF_NAME),
@ -157,7 +181,6 @@ class UniversalMediaPlayer(MediaPlayerEntity):
result = self.hass.helpers.event.async_track_template_result( result = self.hass.helpers.event.async_track_template_result(
self._state_template, _async_on_template_update self._state_template, _async_on_template_update
) )
self.hass.bus.async_listen_once( self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, callback(lambda _: result.async_refresh()) EVENT_HOMEASSISTANT_START, callback(lambda _: result.async_refresh())
) )

View file

@ -0,0 +1,2 @@
reload:
description: Reload all universal entities.

View file

@ -0,0 +1,70 @@
"""Class to reload platforms."""
import logging
from typing import Optional
from homeassistant import config as conf_util
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_per_platform
from homeassistant.helpers.entity_platform import DATA_ENTITY_PLATFORM, EntityPlatform
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.loader import async_get_integration
_LOGGER = logging.getLogger(__name__)
async def async_reload_integration_platforms(
hass: HomeAssistantType, integration_name: str, integration_platforms: str
) -> None:
"""Reload an integration's platforms.
The platform must support being re-setup.
This functionality is only intended to be used for integrations that process
Home Assistant data and make this available to other integrations.
Examples are template, stats, derivative, utility meter.
"""
try:
unprocessed_conf = await conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err:
_LOGGER.error(err)
return
for integration_platform in integration_platforms:
platform = async_get_platform(hass, integration_name, integration_platform)
if not platform:
continue
integration = await async_get_integration(hass, integration_platform)
conf = await conf_util.async_process_component_config(
hass, unprocessed_conf, integration
)
if not conf:
continue
await platform.async_reset()
# Extract only the config for template, ignore the rest.
for p_type, p_config in config_per_platform(conf, integration_platform):
if p_type != integration_name:
continue
await platform.async_setup(p_config) # type: ignore
@callback
def async_get_platform(
hass: HomeAssistantType, integration_name: str, integration_platform_name: str
) -> Optional[EntityPlatform]:
"""Find an existing platform."""
for integration_platform in hass.data[DATA_ENTITY_PLATFORM][integration_name]:
if integration_platform.domain == integration_platform_name:
platform: EntityPlatform = integration_platform
return platform
return None

View file

@ -1,10 +1,13 @@
"""The tests for the Universal Media player platform.""" """The tests for the Universal Media player platform."""
import asyncio import asyncio
from copy import copy from copy import copy
from os import path
import unittest import unittest
from asynctest.mock import patch
from voluptuous.error import MultipleInvalid from voluptuous.error import MultipleInvalid
from homeassistant import config as hass_config
import homeassistant.components.input_number as input_number import homeassistant.components.input_number as input_number
import homeassistant.components.input_select as input_select import homeassistant.components.input_select as input_select
import homeassistant.components.media_player as media_player import homeassistant.components.media_player as media_player
@ -812,3 +815,64 @@ async def test_master_state_with_template(hass):
await hass.async_block_till_done() await hass.async_block_till_done()
hass.states.get("media_player.tv").state == STATE_OFF hass.states.get("media_player.tv").state == STATE_OFF
async def test_reload(hass):
"""Test the state_template option."""
hass.states.async_set("input_boolean.test", STATE_OFF)
hass.states.async_set("media_player.mock1", STATE_OFF)
templ = (
'{% if states.input_boolean.test.state == "off" %}on'
"{% else %}{{ states.media_player.mock1.state }}{% endif %}"
)
await async_setup_component(
hass,
"media_player",
{
"media_player": {
"platform": "universal",
"name": "tv",
"state_template": templ,
}
},
)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 3
await hass.async_start()
await hass.async_block_till_done()
hass.states.get("media_player.tv").state == STATE_ON
hass.states.async_set("input_boolean.test", STATE_ON)
await hass.async_block_till_done()
hass.states.get("media_player.tv").state == STATE_OFF
hass.states.async_set("media_player.master_bedroom_2", STATE_OFF)
hass.states.async_set(
"remote.alexander_master_bedroom",
STATE_ON,
{"activity_list": ["act1", "act2"], "current_activity": "act2"},
)
yaml_path = path.join(
_get_fixtures_base_path(), "fixtures", "universal/configuration.yaml",
)
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path):
await hass.services.async_call(
"universal", universal.SERVICE_RELOAD, {}, blocking=True,
)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 5
assert hass.states.get("media_player.tv") is None
assert hass.states.get("media_player.master_bed_tv").state == "on"
assert hass.states.get("media_player.master_bed_tv").attributes["source"] == "act2"
def _get_fixtures_base_path():
return path.dirname(path.dirname(path.dirname(__file__)))

View file

@ -0,0 +1,14 @@
test_domain:
- platform: test_platform
sensors:
combined_sensor_energy_usage:
friendly_name: Combined Sense Energy Usage
unit_of_measurement: kW
value_template: '{{ ((states(''sensor.energy_usage'') | float) + (states(''sensor.energy_usage_2'')
| float)) / 1000 }}'
watching_tv_in_master_bedroom:
friendly_name: Watching TV in Master Bedroom
value_template: '{% if state_attr("remote.alexander_master_bedroom","current_activity")
== "Watch TV" or state_attr("remote.alexander_master_bedroom","current_activity")
== "Watch Apple TV" %}on{% else %}off{% endif %}'

View file

@ -0,0 +1,9 @@
media_player:
- platform: universal
name: Master Bed TV
children:
- media_player.master_bedroom_2
attributes:
state: remote.alexander_master_bedroom
source_list: remote.alexander_master_bedroom|activity_list
source: remote.alexander_master_bedroom|current_activity

View file

@ -0,0 +1,63 @@
"""Tests for the reload helper."""
import logging
from os import path
from homeassistant import config
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.reload import (
async_get_platform,
async_reload_integration_platforms,
)
from tests.async_mock import Mock, patch
from tests.common import (
MockModule,
MockPlatform,
mock_entity_platform,
mock_integration,
)
_LOGGER = logging.getLogger(__name__)
DOMAIN = "test_domain"
PLATFORM = "test_platform"
async def test_reload_platform(hass):
"""Test the polling of only updated entities."""
component_setup = Mock(return_value=True)
setup_called = []
async def setup_platform(*args):
setup_called.append(args)
mock_integration(hass, MockModule(DOMAIN, setup=component_setup))
mock_integration(hass, MockModule(PLATFORM, dependencies=[DOMAIN]))
mock_platform = MockPlatform(async_setup_platform=setup_platform)
mock_entity_platform(hass, f"{DOMAIN}.{PLATFORM}", mock_platform)
component = EntityComponent(_LOGGER, DOMAIN, hass)
await component.async_setup({DOMAIN: {"platform": PLATFORM, "sensors": None}})
await hass.async_block_till_done()
assert component_setup.called
assert f"{DOMAIN}.{PLATFORM}" in hass.config.components
assert len(setup_called) == 1
platform = async_get_platform(hass, PLATFORM, DOMAIN)
assert platform.platform_name == PLATFORM
assert platform.domain == DOMAIN
yaml_path = path.join(
_get_fixtures_base_path(), "fixtures", "helpers/reload_configuration.yaml",
)
with patch.object(config, "YAML_CONFIG_FILE", yaml_path):
await async_reload_integration_platforms(hass, PLATFORM, [DOMAIN])
assert len(setup_called) == 2
def _get_fixtures_base_path():
return path.dirname(path.dirname(__file__))