UpCloud API and typing update (#50624)

This commit is contained in:
Ville Skyttä 2021-05-15 07:49:41 +03:00 committed by GitHub
parent 7221b1e09d
commit ed10856cc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 71 additions and 27 deletions

View File

@ -46,6 +46,7 @@ homeassistant.components.switch.*
homeassistant.components.synology_dsm.* homeassistant.components.synology_dsm.*
homeassistant.components.systemmonitor.* homeassistant.components.systemmonitor.*
homeassistant.components.tts.* homeassistant.components.tts.*
homeassistant.components.upcloud.*
homeassistant.components.vacuum.* homeassistant.components.vacuum.*
homeassistant.components.water_heater.* homeassistant.components.water_heater.*
homeassistant.components.weather.* homeassistant.components.weather.*

View File

@ -4,7 +4,7 @@ from __future__ import annotations
import dataclasses import dataclasses
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Dict from typing import Any, Dict
import requests.exceptions import requests.exceptions
import upcloud_api import upcloud_api
@ -28,6 +28,7 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_connect,
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import (
CoordinatorEntity, CoordinatorEntity,
DataUpdateCoordinator, DataUpdateCoordinator,
@ -117,7 +118,7 @@ class UpCloudHassData:
scan_interval_migrations: dict[str, int] = dataclasses.field(default_factory=dict) scan_interval_migrations: dict[str, int] = dataclasses.field(default_factory=dict)
async def async_setup(hass: HomeAssistant, config) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up UpCloud component.""" """Set up UpCloud component."""
domain_config = config.get(DOMAIN) domain_config = config.get(DOMAIN)
if not domain_config: if not domain_config:
@ -228,7 +229,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
return True return True
async def async_unload_entry(hass, config_entry): async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Unload the config entry.""" """Unload the config entry."""
unload_ok = await hass.config_entries.async_unload_platforms( unload_ok = await hass.config_entries.async_unload_platforms(
config_entry, CONFIG_ENTRY_DOMAINS config_entry, CONFIG_ENTRY_DOMAINS
@ -242,7 +243,11 @@ async def async_unload_entry(hass, config_entry):
class UpCloudServerEntity(CoordinatorEntity): class UpCloudServerEntity(CoordinatorEntity):
"""Entity class for UpCloud servers.""" """Entity class for UpCloud servers."""
def __init__(self, coordinator, uuid): def __init__(
self,
coordinator: DataUpdateCoordinator[dict[str, upcloud_api.Server]],
uuid: str,
) -> None:
"""Initialize the UpCloud server entity.""" """Initialize the UpCloud server entity."""
super().__init__(coordinator) super().__init__(coordinator)
self.uuid = uuid self.uuid = uuid
@ -257,7 +262,7 @@ class UpCloudServerEntity(CoordinatorEntity):
return self.uuid return self.uuid
@property @property
def name(self): def name(self) -> str:
"""Return the name of the component.""" """Return the name of the component."""
try: try:
return DEFAULT_COMPONENT_NAME.format(self._server.title) return DEFAULT_COMPONENT_NAME.format(self._server.title)
@ -265,12 +270,12 @@ class UpCloudServerEntity(CoordinatorEntity):
return DEFAULT_COMPONENT_NAME.format(self.uuid) return DEFAULT_COMPONENT_NAME.format(self.uuid)
@property @property
def icon(self): def icon(self) -> str:
"""Return the icon of this server.""" """Return the icon of this server."""
return "mdi:server" if self.is_on else "mdi:server-off" return "mdi:server" if self.is_on else "mdi:server-off"
@property @property
def state(self): def state(self) -> str | None:
"""Return state of the server.""" """Return state of the server."""
try: try:
return STATE_MAP.get(self._server.state, self._server.state) return STATE_MAP.get(self._server.state, self._server.state)
@ -278,17 +283,17 @@ class UpCloudServerEntity(CoordinatorEntity):
return None return None
@property @property
def is_on(self): def is_on(self) -> bool:
"""Return true if the server is on.""" """Return true if the server is on."""
return self.state == STATE_ON return self.state == STATE_ON
@property @property
def device_class(self): def device_class(self) -> str:
"""Return the class of this server.""" """Return the class of this server."""
return DEFAULT_COMPONENT_DEVICE_CLASS return DEFAULT_COMPONENT_DEVICE_CLASS
@property @property
def extra_state_attributes(self): def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the UpCloud server.""" """Return the state attributes of the UpCloud server."""
return { return {
x: getattr(self._server, x, None) x: getattr(self._server, x, None)

View File

@ -3,8 +3,11 @@
import voluptuous as vol import voluptuous as vol
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_USERNAME from homeassistant.const import CONF_USERNAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import CONF_SERVERS, DATA_UPCLOUD, UpCloudServerEntity from . import CONF_SERVERS, DATA_UPCLOUD, UpCloudServerEntity
@ -13,7 +16,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the UpCloud server binary sensor.""" """Set up the UpCloud server binary sensor."""
coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]] coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]]
entities = [UpCloudBinarySensor(coordinator, uuid) for uuid in coordinator.data] entities = [UpCloudBinarySensor(coordinator, uuid) for uuid in coordinator.data]

View File

@ -1,6 +1,9 @@
"""Config flow for UpCloud.""" """Config flow for UpCloud."""
from __future__ import annotations
import logging import logging
from typing import Any
import requests.exceptions import requests.exceptions
import upcloud_api import upcloud_api
@ -9,6 +12,7 @@ import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
@ -23,7 +27,9 @@ class UpCloudConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
username: str username: str
password: str password: str
async def async_step_user(self, user_input=None): async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle user initiated flow.""" """Handle user initiated flow."""
if user_input is None: if user_input is None:
return self._async_show_form(step_id="user") return self._async_show_form(step_id="user")
@ -51,7 +57,7 @@ class UpCloudConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_create_entry(title=user_input[CONF_USERNAME], data=user_input) return self.async_create_entry(title=user_input[CONF_USERNAME], data=user_input)
async def async_step_import(self, user_input=None): async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult:
"""Handle import initiated flow.""" """Handle import initiated flow."""
await self.async_set_unique_id(user_input[CONF_USERNAME]) await self.async_set_unique_id(user_input[CONF_USERNAME])
self._abort_if_unique_id_configured() self._abort_if_unique_id_configured()
@ -59,7 +65,12 @@ class UpCloudConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_user(user_input=user_input) return await self.async_step_user(user_input=user_input)
@callback @callback
def _async_show_form(self, step_id, user_input=None, errors=None): def _async_show_form(
self,
step_id: str,
user_input: dict[str, Any] | None = None,
errors: dict[str, str] | None = None,
) -> FlowResult:
"""Show our form.""" """Show our form."""
if user_input is None: if user_input is None:
user_input = {} user_input = {}
@ -80,7 +91,9 @@ class UpCloudConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
@staticmethod @staticmethod
@callback @callback
def async_get_options_flow(config_entry): def async_get_options_flow(
config_entry: config_entries.ConfigEntry,
) -> UpCloudOptionsFlow:
"""Get options flow.""" """Get options flow."""
return UpCloudOptionsFlow(config_entry) return UpCloudOptionsFlow(config_entry)
@ -92,7 +105,9 @@ class UpCloudOptionsFlow(config_entries.OptionsFlow):
"""Initialize options flow.""" """Initialize options flow."""
self.config_entry = config_entry self.config_entry = config_entry
async def async_step_init(self, user_input=None): async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle options flow.""" """Handle options flow."""
if user_input is not None: if user_input is not None:

View File

@ -3,7 +3,7 @@
"name": "UpCloud", "name": "UpCloud",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/upcloud", "documentation": "https://www.home-assistant.io/integrations/upcloud",
"requirements": ["upcloud-api==1.0.1"], "requirements": ["upcloud-api==2.0.0"],
"codeowners": ["@scop"], "codeowners": ["@scop"],
"iot_class": "cloud_polling" "iot_class": "cloud_polling"
} }

View File

@ -1,11 +1,16 @@
"""Support for interacting with UpCloud servers.""" """Support for interacting with UpCloud servers."""
from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_USERNAME, STATE_OFF from homeassistant.const import CONF_USERNAME, STATE_OFF
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import CONF_SERVERS, DATA_UPCLOUD, SIGNAL_UPDATE_UPCLOUD, UpCloudServerEntity from . import CONF_SERVERS, DATA_UPCLOUD, SIGNAL_UPDATE_UPCLOUD, UpCloudServerEntity
@ -14,7 +19,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
) )
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the UpCloud server switch.""" """Set up the UpCloud server switch."""
coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]] coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]]
entities = [UpCloudSwitch(coordinator, uuid) for uuid in coordinator.data] entities = [UpCloudSwitch(coordinator, uuid) for uuid in coordinator.data]
@ -24,13 +33,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class UpCloudSwitch(UpCloudServerEntity, SwitchEntity): class UpCloudSwitch(UpCloudServerEntity, SwitchEntity):
"""Representation of an UpCloud server switch.""" """Representation of an UpCloud server switch."""
def turn_on(self, **kwargs): def turn_on(self, **kwargs: Any) -> None:
"""Start the server.""" """Start the server."""
if self.state == STATE_OFF: if self.state == STATE_OFF:
self._server.start() self._server.start()
dispatcher_send(self.hass, SIGNAL_UPDATE_UPCLOUD) dispatcher_send(self.hass, SIGNAL_UPDATE_UPCLOUD)
def turn_off(self, **kwargs): def turn_off(self, **kwargs: Any) -> None:
"""Stop the server.""" """Stop the server."""
if self.is_on: if self.is_on:
self._server.stop() self._server.stop()

View File

@ -749,7 +749,7 @@ class ToggleEntity(Entity):
"""An abstract class for entities that can be turned on and off.""" """An abstract class for entities that can be turned on and off."""
@property @property
def state(self) -> str: def state(self) -> str | None:
"""Return the state.""" """Return the state."""
return STATE_ON if self.is_on else STATE_OFF return STATE_ON if self.is_on else STATE_OFF

View File

@ -517,6 +517,17 @@ no_implicit_optional = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.upcloud.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.vacuum.*] [mypy-homeassistant.components.vacuum.*]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true
@ -1220,9 +1231,6 @@ ignore_errors = true
[mypy-homeassistant.components.unifi.*] [mypy-homeassistant.components.unifi.*]
ignore_errors = true ignore_errors = true
[mypy-homeassistant.components.upcloud.*]
ignore_errors = true
[mypy-homeassistant.components.updater.*] [mypy-homeassistant.components.updater.*]
ignore_errors = true ignore_errors = true

View File

@ -2286,7 +2286,7 @@ unifiled==0.11
upb_lib==0.4.12 upb_lib==0.4.12
# homeassistant.components.upcloud # homeassistant.components.upcloud
upcloud-api==1.0.1 upcloud-api==2.0.0
# homeassistant.components.huawei_lte # homeassistant.components.huawei_lte
# homeassistant.components.syncthru # homeassistant.components.syncthru

View File

@ -1228,7 +1228,7 @@ twinkly-client==0.0.2
upb_lib==0.4.12 upb_lib==0.4.12
# homeassistant.components.upcloud # homeassistant.components.upcloud
upcloud-api==1.0.1 upcloud-api==2.0.0
# homeassistant.components.huawei_lte # homeassistant.components.huawei_lte
# homeassistant.components.syncthru # homeassistant.components.syncthru

View File

@ -219,7 +219,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.tradfri.*", "homeassistant.components.tradfri.*",
"homeassistant.components.tuya.*", "homeassistant.components.tuya.*",
"homeassistant.components.unifi.*", "homeassistant.components.unifi.*",
"homeassistant.components.upcloud.*",
"homeassistant.components.updater.*", "homeassistant.components.updater.*",
"homeassistant.components.upnp.*", "homeassistant.components.upnp.*",
"homeassistant.components.velbus.*", "homeassistant.components.velbus.*",