Add Airnow to strict typing (#105566)
parent
278c7ac2a5
commit
e469c6892b
|
@ -48,6 +48,7 @@ homeassistant.components.adguard.*
|
||||||
homeassistant.components.aftership.*
|
homeassistant.components.aftership.*
|
||||||
homeassistant.components.air_quality.*
|
homeassistant.components.air_quality.*
|
||||||
homeassistant.components.airly.*
|
homeassistant.components.airly.*
|
||||||
|
homeassistant.components.airnow.*
|
||||||
homeassistant.components.airvisual.*
|
homeassistant.components.airvisual.*
|
||||||
homeassistant.components.airvisual_pro.*
|
homeassistant.components.airvisual_pro.*
|
||||||
homeassistant.components.airzone.*
|
homeassistant.components.airzone.*
|
||||||
|
|
|
@ -6,8 +6,17 @@ from pyairnow import WebServiceAPI
|
||||||
from pyairnow.errors import AirNowError, EmptyResponseError, InvalidKeyError
|
from pyairnow.errors import AirNowError, EmptyResponseError, InvalidKeyError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries, core, data_entry_flow, exceptions
|
from homeassistant import core
|
||||||
|
from homeassistant.config_entries import (
|
||||||
|
ConfigEntry,
|
||||||
|
ConfigFlow,
|
||||||
|
OptionsFlow,
|
||||||
|
OptionsFlowWithConfigEntry,
|
||||||
|
)
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
|
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
@ -16,7 +25,7 @@ from .const import DOMAIN
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def validate_input(hass: core.HomeAssistant, data):
|
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> bool:
|
||||||
"""Validate the user input allows us to connect.
|
"""Validate the user input allows us to connect.
|
||||||
|
|
||||||
Data has the keys from DATA_SCHEMA with values provided by the user.
|
Data has the keys from DATA_SCHEMA with values provided by the user.
|
||||||
|
@ -46,12 +55,14 @@ async def validate_input(hass: core.HomeAssistant, data):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
class AirNowConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
"""Handle a config flow for AirNow."""
|
"""Handle a config flow for AirNow."""
|
||||||
|
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> FlowResult:
|
||||||
"""Handle the initial step."""
|
"""Handle the initial step."""
|
||||||
errors = {}
|
errors = {}
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
|
@ -108,18 +119,18 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@core.callback
|
@core.callback
|
||||||
def async_get_options_flow(
|
def async_get_options_flow(
|
||||||
config_entry: config_entries.ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
) -> config_entries.OptionsFlow:
|
) -> OptionsFlow:
|
||||||
"""Return the options flow."""
|
"""Return the options flow."""
|
||||||
return OptionsFlowHandler(config_entry)
|
return AirNowOptionsFlowHandler(config_entry)
|
||||||
|
|
||||||
|
|
||||||
class OptionsFlowHandler(config_entries.OptionsFlowWithConfigEntry):
|
class AirNowOptionsFlowHandler(OptionsFlowWithConfigEntry):
|
||||||
"""Handle an options flow for AirNow."""
|
"""Handle an options flow for AirNow."""
|
||||||
|
|
||||||
async def async_step_init(
|
async def async_step_init(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> data_entry_flow.FlowResult:
|
) -> FlowResult:
|
||||||
"""Manage the options."""
|
"""Manage the options."""
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
return self.async_create_entry(data=user_input)
|
return self.async_create_entry(data=user_input)
|
||||||
|
@ -141,13 +152,13 @@ class OptionsFlowHandler(config_entries.OptionsFlowWithConfigEntry):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CannotConnect(exceptions.HomeAssistantError):
|
class CannotConnect(HomeAssistantError):
|
||||||
"""Error to indicate we cannot connect."""
|
"""Error to indicate we cannot connect."""
|
||||||
|
|
||||||
|
|
||||||
class InvalidAuth(exceptions.HomeAssistantError):
|
class InvalidAuth(HomeAssistantError):
|
||||||
"""Error to indicate there is invalid auth."""
|
"""Error to indicate there is invalid auth."""
|
||||||
|
|
||||||
|
|
||||||
class InvalidLocation(exceptions.HomeAssistantError):
|
class InvalidLocation(HomeAssistantError):
|
||||||
"""Error to indicate the location is invalid."""
|
"""Error to indicate the location is invalid."""
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
"""DataUpdateCoordinator for the AirNow integration."""
|
"""DataUpdateCoordinator for the AirNow integration."""
|
||||||
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from aiohttp import ClientSession
|
||||||
from aiohttp.client_exceptions import ClientConnectorError
|
from aiohttp.client_exceptions import ClientConnectorError
|
||||||
from pyairnow import WebServiceAPI
|
from pyairnow import WebServiceAPI
|
||||||
from pyairnow.conv import aqi_to_concentration
|
from pyairnow.conv import aqi_to_concentration
|
||||||
from pyairnow.errors import AirNowError
|
from pyairnow.errors import AirNowError
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
|
@ -31,12 +35,19 @@ from .const import (
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AirNowDataUpdateCoordinator(DataUpdateCoordinator):
|
class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""The AirNow update coordinator."""
|
"""The AirNow update coordinator."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass, session, api_key, latitude, longitude, distance, update_interval
|
self,
|
||||||
):
|
hass: HomeAssistant,
|
||||||
|
session: ClientSession,
|
||||||
|
api_key: str,
|
||||||
|
latitude: float,
|
||||||
|
longitude: float,
|
||||||
|
distance: int,
|
||||||
|
update_interval: timedelta,
|
||||||
|
) -> None:
|
||||||
"""Initialize."""
|
"""Initialize."""
|
||||||
self.latitude = latitude
|
self.latitude = latitude
|
||||||
self.longitude = longitude
|
self.longitude = longitude
|
||||||
|
@ -46,7 +57,7 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
|
||||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||||
|
|
||||||
async def _async_update_data(self):
|
async def _async_update_data(self) -> dict[str, Any]:
|
||||||
"""Update data via library."""
|
"""Update data via library."""
|
||||||
data = {}
|
data = {}
|
||||||
try:
|
try:
|
||||||
|
|
10
mypy.ini
10
mypy.ini
|
@ -240,6 +240,16 @@ disallow_untyped_defs = true
|
||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.airnow.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.airvisual.*]
|
[mypy-homeassistant.components.airvisual.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
|
|
Loading…
Reference in New Issue