From 015c8811a50ba57cd5c95f48a69d4d90386d902c Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Wed, 29 May 2019 13:33:49 +0200 Subject: [PATCH] Use global imports for ESPHome (#24158) * Use global import for ESPHome * Add aioesphomeapi to test requirements aioesphomeapi is also shipped as a pure-python wheel, so this should not impact test install time --- homeassistant/components/esphome/__init__.py | 37 +++++++------------ .../components/esphome/binary_sensor.py | 15 +++----- homeassistant/components/esphome/camera.py | 16 +++----- homeassistant/components/esphome/climate.py | 22 ++++------- homeassistant/components/esphome/cover.py | 17 +++------ homeassistant/components/esphome/fan.py | 22 ++++------- homeassistant/components/esphome/light.py | 17 +++------ homeassistant/components/esphome/sensor.py | 20 ++++------ homeassistant/components/esphome/switch.py | 17 +++------ requirements_test_all.txt | 3 ++ script/gen_requirements_all.py | 1 + 11 files changed, 69 insertions(+), 118 deletions(-) diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index e5feedd8421..d42bbb725dd 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -2,36 +2,35 @@ import asyncio import logging import math -from typing import Any, Dict, List, Optional, TYPE_CHECKING, Callable, Tuple +from typing import Any, Callable, Dict, List, Optional, Tuple +from aioesphomeapi import ( + COMPONENT_TYPE_TO_INFO, APIClient, APIConnectionError, DeviceInfo, + EntityInfo, EntityState, ServiceCall, UserService, UserServiceArgType) import attr import voluptuous as vol from homeassistant import const from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, \ - EVENT_HOMEASSISTANT_STOP -from homeassistant.core import callback, Event, State -import homeassistant.helpers.device_registry as dr +from homeassistant.const import ( + CONF_HOST, CONF_PASSWORD, CONF_PORT, EVENT_HOMEASSISTANT_STOP) +from homeassistant.core import Event, State, callback from homeassistant.exceptions import TemplateError -import homeassistant.helpers.config_validation as cv from homeassistant.helpers import template -from homeassistant.helpers.dispatcher import async_dispatcher_connect, \ - async_dispatcher_send +import homeassistant.helpers.config_validation as cv +import homeassistant.helpers.device_registry as dr +from homeassistant.helpers.dispatcher import ( + async_dispatcher_connect, async_dispatcher_send) from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change -from homeassistant.helpers.template import Template from homeassistant.helpers.json import JSONEncoder from homeassistant.helpers.storage import Store -from homeassistant.helpers.typing import HomeAssistantType, ConfigType +from homeassistant.helpers.template import Template +from homeassistant.helpers.typing import ConfigType, HomeAssistantType # Import config flow so that it's added to the registry from .config_flow import EsphomeFlowHandler # noqa -if TYPE_CHECKING: - from aioesphomeapi import APIClient, EntityInfo, EntityState, DeviceInfo, \ - ServiceCall, UserService - DOMAIN = 'esphome' _LOGGER = logging.getLogger(__name__) @@ -110,10 +109,6 @@ class RuntimeEntryData: async def async_load_from_store(self) -> Tuple[List['EntityInfo'], List['UserService']]: """Load the retained data from store and return de-serialized data.""" - # pylint: disable= redefined-outer-name - from aioesphomeapi import COMPONENT_TYPE_TO_INFO, DeviceInfo, \ - UserService - restored = await self.store.async_load() if restored is None: return [], [] @@ -164,9 +159,6 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: """Set up the esphome component.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import APIClient, APIConnectionError - hass.data.setdefault(DOMAIN, {}) host = entry.data[CONF_HOST] @@ -306,8 +298,6 @@ async def _setup_auto_reconnect_logic(hass: HomeAssistantType, cli: 'APIClient', entry: ConfigEntry, host: str, on_login): """Set up the re-connect logic for the API client.""" - from aioesphomeapi import APIConnectionError - async def try_connect(tries: int = 0, is_disconnect: bool = True) -> None: """Try connecting to the API client. Will retry if not successful.""" if entry.entry_id not in hass.data[DOMAIN]: @@ -382,7 +372,6 @@ async def _async_setup_device_registry(hass: HomeAssistantType, async def _register_service(hass: HomeAssistantType, entry_data: RuntimeEntryData, service: 'UserService'): - from aioesphomeapi import UserServiceArgType service_name = '{}_{}'.format(entry_data.device_info.name, service.name) schema = {} for arg in service.args: diff --git a/homeassistant/components/esphome/binary_sensor.py b/homeassistant/components/esphome/binary_sensor.py index 6a6f9bfac1c..75a7235c58f 100644 --- a/homeassistant/components/esphome/binary_sensor.py +++ b/homeassistant/components/esphome/binary_sensor.py @@ -1,23 +1,18 @@ """Support for ESPHome binary sensors.""" import logging -from typing import TYPE_CHECKING, Optional +from typing import Optional + +from aioesphomeapi import BinarySensorInfo, BinarySensorState from homeassistant.components.binary_sensor import BinarySensorDevice from . import EsphomeEntity, platform_async_setup_entry -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import BinarySensorInfo, BinarySensorState # noqa - _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, entry, async_add_entities): """Set up ESPHome binary sensors based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import BinarySensorInfo, BinarySensorState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='binary_sensor', @@ -30,11 +25,11 @@ class EsphomeBinarySensor(EsphomeEntity, BinarySensorDevice): """A binary sensor implementation for ESPHome.""" @property - def _static_info(self) -> 'BinarySensorInfo': + def _static_info(self) -> BinarySensorInfo: return super()._static_info @property - def _state(self) -> Optional['BinarySensorState']: + def _state(self) -> Optional[BinarySensorState]: return super()._state @property diff --git a/homeassistant/components/esphome/camera.py b/homeassistant/components/esphome/camera.py index 64e73dc8784..54f774bc426 100644 --- a/homeassistant/components/esphome/camera.py +++ b/homeassistant/components/esphome/camera.py @@ -1,17 +1,16 @@ """Support for ESPHome cameras.""" import asyncio import logging -from typing import Optional, TYPE_CHECKING +from typing import Optional + +from aioesphomeapi import CameraInfo, CameraState from homeassistant.components import camera from homeassistant.components.camera import Camera from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import EsphomeEntity, platform_async_setup_entry -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import CameraInfo, CameraState # noqa +from . import EsphomeEntity, platform_async_setup_entry _LOGGER = logging.getLogger(__name__) @@ -19,9 +18,6 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up esphome cameras based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import CameraInfo, CameraState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='camera', @@ -40,11 +36,11 @@ class EsphomeCamera(Camera, EsphomeEntity): self._image_cond = asyncio.Condition() @property - def _static_info(self) -> 'CameraInfo': + def _static_info(self) -> CameraInfo: return super()._static_info @property - def _state(self) -> Optional['CameraState']: + def _state(self) -> Optional[CameraState]: return super()._state async def _on_update(self) -> None: diff --git a/homeassistant/components/esphome/climate.py b/homeassistant/components/esphome/climate.py index 184eb4b6270..33ea5524787 100644 --- a/homeassistant/components/esphome/climate.py +++ b/homeassistant/components/esphome/climate.py @@ -1,6 +1,8 @@ """Support for ESPHome climate devices.""" import logging -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional + +from aioesphomeapi import ClimateInfo, ClimateMode, ClimateState from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( @@ -12,21 +14,15 @@ from homeassistant.const import ( ATTR_TEMPERATURE, PRECISION_HALVES, PRECISION_TENTHS, PRECISION_WHOLE, STATE_OFF, TEMP_CELSIUS) -from . import EsphomeEntity, platform_async_setup_entry, \ - esphome_state_property, esphome_map_enum - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import ClimateInfo, ClimateState, ClimateMode # noqa +from . import ( + EsphomeEntity, esphome_map_enum, esphome_state_property, + platform_async_setup_entry) _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, entry, async_add_entities): """Set up ESPHome climate devices based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import ClimateInfo, ClimateState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='climate', @@ -37,8 +33,6 @@ async def async_setup_entry(hass, entry, async_add_entities): @esphome_map_enum def _climate_modes(): - # pylint: disable=redefined-outer-name - from aioesphomeapi import ClimateMode # noqa return { ClimateMode.OFF: STATE_OFF, ClimateMode.AUTO: STATE_AUTO, @@ -51,11 +45,11 @@ class EsphomeClimateDevice(EsphomeEntity, ClimateDevice): """A climate implementation for ESPHome.""" @property - def _static_info(self) -> 'ClimateInfo': + def _static_info(self) -> ClimateInfo: return super()._static_info @property - def _state(self) -> Optional['ClimateState']: + def _state(self) -> Optional[ClimateState]: return super()._state @property diff --git a/homeassistant/components/esphome/cover.py b/homeassistant/components/esphome/cover.py index a3ef15fa4c7..b69b62075db 100644 --- a/homeassistant/components/esphome/cover.py +++ b/homeassistant/components/esphome/cover.py @@ -1,6 +1,8 @@ """Support for ESPHome covers.""" import logging -from typing import TYPE_CHECKING, Optional +from typing import Optional + +from aioesphomeapi import CoverInfo, CoverState from homeassistant.components.cover import ( ATTR_POSITION, ATTR_TILT_POSITION, SUPPORT_CLOSE, SUPPORT_CLOSE_TILT, @@ -9,11 +11,7 @@ from homeassistant.components.cover import ( from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import EsphomeEntity, platform_async_setup_entry, esphome_state_property - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import CoverInfo, CoverState # noqa +from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry _LOGGER = logging.getLogger(__name__) @@ -21,9 +19,6 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up ESPHome covers based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import CoverInfo, CoverState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='cover', @@ -36,7 +31,7 @@ class EsphomeCover(EsphomeEntity, CoverDevice): """A cover implementation for ESPHome.""" @property - def _static_info(self) -> 'CoverInfo': + def _static_info(self) -> CoverInfo: return super()._static_info @property @@ -61,7 +56,7 @@ class EsphomeCover(EsphomeEntity, CoverDevice): return self._static_info.assumed_state @property - def _state(self) -> Optional['CoverState']: + def _state(self) -> Optional[CoverState]: return super()._state @esphome_state_property diff --git a/homeassistant/components/esphome/fan.py b/homeassistant/components/esphome/fan.py index 50cf04203f3..255bdaa8cb1 100644 --- a/homeassistant/components/esphome/fan.py +++ b/homeassistant/components/esphome/fan.py @@ -1,6 +1,8 @@ """Support for ESPHome fans.""" import logging -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional + +from aioesphomeapi import FanInfo, FanSpeed, FanState from homeassistant.components.fan import ( SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM, SPEED_OFF, SUPPORT_OSCILLATE, @@ -8,12 +10,9 @@ from homeassistant.components.fan import ( from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import EsphomeEntity, platform_async_setup_entry, \ - esphome_state_property, esphome_map_enum - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import FanInfo, FanState, FanSpeed # noqa +from . import ( + EsphomeEntity, esphome_map_enum, esphome_state_property, + platform_async_setup_entry) _LOGGER = logging.getLogger(__name__) @@ -21,9 +20,6 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up ESPHome fans based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import FanInfo, FanState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='fan', @@ -34,8 +30,6 @@ async def async_setup_entry(hass: HomeAssistantType, @esphome_map_enum def _fan_speeds(): - # pylint: disable=redefined-outer-name - from aioesphomeapi import FanSpeed # noqa return { FanSpeed.LOW: SPEED_LOW, FanSpeed.MEDIUM: SPEED_MEDIUM, @@ -47,11 +41,11 @@ class EsphomeFan(EsphomeEntity, FanEntity): """A fan implementation for ESPHome.""" @property - def _static_info(self) -> 'FanInfo': + def _static_info(self) -> FanInfo: return super()._static_info @property - def _state(self) -> Optional['FanState']: + def _state(self) -> Optional[FanState]: return super()._state async def async_set_speed(self, speed: str) -> None: diff --git a/homeassistant/components/esphome/light.py b/homeassistant/components/esphome/light.py index 6b4abafe62b..f94229d61cc 100644 --- a/homeassistant/components/esphome/light.py +++ b/homeassistant/components/esphome/light.py @@ -1,6 +1,8 @@ """Support for ESPHome lights.""" import logging -from typing import TYPE_CHECKING, List, Optional, Tuple +from typing import List, Optional, Tuple + +from aioesphomeapi import LightInfo, LightState from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_HS_COLOR, @@ -11,11 +13,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType import homeassistant.util.color as color_util -from . import EsphomeEntity, platform_async_setup_entry, esphome_state_property - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import LightInfo, LightState # noqa +from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry _LOGGER = logging.getLogger(__name__) @@ -29,9 +27,6 @@ FLASH_LENGTHS = { async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up ESPHome lights based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import LightInfo, LightState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='light', @@ -44,11 +39,11 @@ class EsphomeLight(EsphomeEntity, Light): """A switch implementation for ESPHome.""" @property - def _static_info(self) -> 'LightInfo': + def _static_info(self) -> LightInfo: return super()._static_info @property - def _state(self) -> Optional['LightState']: + def _state(self) -> Optional[LightState]: return super()._state @esphome_state_property diff --git a/homeassistant/components/esphome/sensor.py b/homeassistant/components/esphome/sensor.py index 8d8fb938c68..a5a530b49f1 100644 --- a/homeassistant/components/esphome/sensor.py +++ b/homeassistant/components/esphome/sensor.py @@ -1,17 +1,15 @@ """Support for esphome sensors.""" import logging import math -from typing import TYPE_CHECKING, Optional +from typing import Optional + +from aioesphomeapi import ( + SensorInfo, SensorState, TextSensorInfo, TextSensorState) from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import EsphomeEntity, platform_async_setup_entry, esphome_state_property - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import ( # noqa - SensorInfo, SensorState, TextSensorInfo, TextSensorState) +from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry _LOGGER = logging.getLogger(__name__) @@ -19,10 +17,6 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up esphome sensors based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import ( # noqa - SensorInfo, SensorState, TextSensorInfo, TextSensorState) - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='sensor', @@ -41,11 +35,11 @@ class EsphomeSensor(EsphomeEntity): """A sensor implementation for esphome.""" @property - def _static_info(self) -> 'SensorInfo': + def _static_info(self) -> SensorInfo: return super()._static_info @property - def _state(self) -> Optional['SensorState']: + def _state(self) -> Optional[SensorState]: return super()._state @property diff --git a/homeassistant/components/esphome/switch.py b/homeassistant/components/esphome/switch.py index 77994d0be58..d209df8cd83 100644 --- a/homeassistant/components/esphome/switch.py +++ b/homeassistant/components/esphome/switch.py @@ -1,16 +1,14 @@ """Support for ESPHome switches.""" import logging -from typing import TYPE_CHECKING, Optional +from typing import Optional + +from aioesphomeapi import SwitchInfo, SwitchState from homeassistant.components.switch import SwitchDevice from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import EsphomeEntity, platform_async_setup_entry, esphome_state_property - -if TYPE_CHECKING: - # pylint: disable=unused-import - from aioesphomeapi import SwitchInfo, SwitchState # noqa +from . import EsphomeEntity, esphome_state_property, platform_async_setup_entry _LOGGER = logging.getLogger(__name__) @@ -18,9 +16,6 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry, async_add_entities) -> None: """Set up ESPHome switches based on a config entry.""" - # pylint: disable=redefined-outer-name - from aioesphomeapi import SwitchInfo, SwitchState # noqa - await platform_async_setup_entry( hass, entry, async_add_entities, component_key='switch', @@ -33,11 +28,11 @@ class EsphomeSwitch(EsphomeEntity, SwitchDevice): """A switch implementation for ESPHome.""" @property - def _static_info(self) -> 'SwitchInfo': + def _static_info(self) -> SwitchInfo: return super()._static_info @property - def _state(self) -> Optional['SwitchState']: + def _state(self) -> Optional[SwitchState]: return super()._state @property diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f551e9ddc34..39f0512cdeb 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -44,6 +44,9 @@ aioautomatic==0.6.5 # homeassistant.components.aws aiobotocore==0.10.2 +# homeassistant.components.esphome +aioesphomeapi==2.0.1 + # homeassistant.components.emulated_hue # homeassistant.components.http aiohttp_cors==0.7.0 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index a5f24be51de..dad20279d5b 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -46,6 +46,7 @@ TEST_REQUIREMENTS = ( 'aioambient', 'aioautomatic', 'aiobotocore', + 'aioesphomeapi', 'aiohttp_cors', 'aiohue', 'aiounifi',