mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Enable basic type checking in upnp (#66253)
Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
parent
1793c29fac
commit
8260767e8f
@ -121,6 +121,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
cancel_discovered_callback()
|
||||
|
||||
# Create device.
|
||||
assert discovery_info is not None
|
||||
assert discovery_info.ssdp_location is not None
|
||||
location = discovery_info.ssdp_location
|
||||
try:
|
||||
device = await Device.async_create_device(hass, location)
|
||||
|
@ -43,6 +43,7 @@ async def async_setup_entry(
|
||||
class UpnpStatusBinarySensor(UpnpEntity, BinarySensorEntity):
|
||||
"""Class for UPnP/IGD binary sensors."""
|
||||
|
||||
entity_description: UpnpBinarySensorEntityDescription
|
||||
_attr_device_class = BinarySensorDeviceClass.CONNECTIVITY
|
||||
|
||||
def __init__(
|
||||
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
from collections.abc import Mapping
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@ -31,16 +31,17 @@ from .const import (
|
||||
|
||||
def _friendly_name_from_discovery(discovery_info: ssdp.SsdpServiceInfo) -> str:
|
||||
"""Extract user-friendly name from discovery."""
|
||||
return (
|
||||
return cast(
|
||||
str,
|
||||
discovery_info.upnp.get(ssdp.ATTR_UPNP_FRIENDLY_NAME)
|
||||
or discovery_info.upnp.get(ssdp.ATTR_UPNP_MODEL_NAME)
|
||||
or discovery_info.ssdp_headers.get("_host", "")
|
||||
or discovery_info.ssdp_headers.get("_host", ""),
|
||||
)
|
||||
|
||||
|
||||
def _is_complete_discovery(discovery_info: ssdp.SsdpServiceInfo) -> bool:
|
||||
"""Test if discovery is complete and usable."""
|
||||
return (
|
||||
return bool(
|
||||
ssdp.ATTR_UPNP_UDN in discovery_info.upnp
|
||||
and discovery_info.ssdp_st
|
||||
and discovery_info.ssdp_location
|
||||
@ -114,14 +115,13 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Initialize the UPnP/IGD config flow."""
|
||||
self._discoveries: list[SsdpServiceInfo] | None = None
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: Mapping | None = None
|
||||
) -> Mapping[str, Any]:
|
||||
async def async_step_user(self, user_input: Mapping | None = None) -> FlowResult:
|
||||
"""Handle a flow start."""
|
||||
LOGGER.debug("async_step_user: user_input: %s", user_input)
|
||||
|
||||
if user_input is not None:
|
||||
# Ensure wanted device was discovered.
|
||||
assert self._discoveries
|
||||
matching_discoveries = [
|
||||
discovery
|
||||
for discovery in self._discoveries
|
||||
@ -248,12 +248,13 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def async_step_ssdp_confirm(
|
||||
self, user_input: Mapping | None = None
|
||||
) -> Mapping[str, Any]:
|
||||
) -> FlowResult:
|
||||
"""Confirm integration via SSDP."""
|
||||
LOGGER.debug("async_step_ssdp_confirm: user_input: %s", user_input)
|
||||
if user_input is None:
|
||||
return self.async_show_form(step_id="ssdp_confirm")
|
||||
|
||||
assert self._discoveries
|
||||
discovery = self._discoveries[0]
|
||||
return await self._async_create_entry_from_discovery(discovery)
|
||||
|
||||
@ -268,7 +269,7 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
async def _async_create_entry_from_discovery(
|
||||
self,
|
||||
discovery: SsdpServiceInfo,
|
||||
) -> Mapping[str, Any]:
|
||||
) -> FlowResult:
|
||||
"""Create an entry from discovery."""
|
||||
LOGGER.debug(
|
||||
"_async_create_entry_from_discovery: discovery: %s",
|
||||
@ -291,7 +292,7 @@ class UpnpOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Initialize."""
|
||||
self.config_entry = config_entry
|
||||
|
||||
async def async_step_init(self, user_input: Mapping = None) -> None:
|
||||
async def async_step_init(self, user_input: Mapping = None) -> FlowResult:
|
||||
"""Manage the options."""
|
||||
if user_input is not None:
|
||||
coordinator = self.hass.data[DOMAIN][self.config_entry.entry_id]
|
||||
|
@ -9,7 +9,7 @@ from urllib.parse import urlparse
|
||||
from async_upnp_client import UpnpDevice, UpnpFactory
|
||||
from async_upnp_client.aiohttp import AiohttpSessionRequester
|
||||
from async_upnp_client.exceptions import UpnpError
|
||||
from async_upnp_client.profiles.igd import IgdDevice
|
||||
from async_upnp_client.profiles.igd import IgdDevice, StatusInfo
|
||||
|
||||
from homeassistant.components import ssdp
|
||||
from homeassistant.components.ssdp import SsdpChange, SsdpServiceInfo
|
||||
@ -49,7 +49,7 @@ class Device:
|
||||
"""Initialize UPnP/IGD device."""
|
||||
self.hass = hass
|
||||
self._igd_device = igd_device
|
||||
self.coordinator: DataUpdateCoordinator = None
|
||||
self.coordinator: DataUpdateCoordinator | None = None
|
||||
|
||||
@classmethod
|
||||
async def async_create_device(
|
||||
@ -129,7 +129,7 @@ class Device:
|
||||
return self.usn
|
||||
|
||||
@property
|
||||
def hostname(self) -> str:
|
||||
def hostname(self) -> str | None:
|
||||
"""Get the hostname."""
|
||||
url = self._igd_device.device.device_url
|
||||
parsed = urlparse(url)
|
||||
@ -177,7 +177,9 @@ class Device:
|
||||
self._igd_device.async_get_external_ip_address(),
|
||||
return_exceptions=True,
|
||||
)
|
||||
result = []
|
||||
status_info: StatusInfo | None = None
|
||||
ip_address: str | None = None
|
||||
|
||||
for idx, value in enumerate(values):
|
||||
if isinstance(value, UpnpError):
|
||||
# Not all routers support some of these items although based
|
||||
@ -188,16 +190,18 @@ class Device:
|
||||
self,
|
||||
str(value),
|
||||
)
|
||||
result.append(None)
|
||||
continue
|
||||
|
||||
if isinstance(value, Exception):
|
||||
raise value
|
||||
|
||||
result.append(value)
|
||||
if isinstance(value, StatusInfo):
|
||||
status_info = value
|
||||
elif isinstance(value, str):
|
||||
ip_address = value
|
||||
|
||||
return {
|
||||
WAN_STATUS: result[0][0] if result[0] is not None else None,
|
||||
ROUTER_UPTIME: result[0][2] if result[0] is not None else None,
|
||||
ROUTER_IP: result[1],
|
||||
WAN_STATUS: status_info[0] if status_info is not None else None,
|
||||
ROUTER_UPTIME: status_info[2] if status_info is not None else None,
|
||||
ROUTER_IP: ip_address,
|
||||
}
|
||||
|
@ -143,6 +143,8 @@ async def async_setup_entry(
|
||||
class UpnpSensor(UpnpEntity, SensorEntity):
|
||||
"""Base class for UPnP/IGD sensors."""
|
||||
|
||||
entity_description: UpnpSensorEntityDescription
|
||||
|
||||
|
||||
class RawUpnpSensor(UpnpSensor):
|
||||
"""Representation of a UPnP/IGD sensor."""
|
||||
@ -159,8 +161,6 @@ class RawUpnpSensor(UpnpSensor):
|
||||
class DerivedUpnpSensor(UpnpSensor):
|
||||
"""Representation of a UNIT Sent/Received per second sensor."""
|
||||
|
||||
entity_description: UpnpSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: UpnpDataUpdateCoordinator,
|
||||
|
15
mypy.ini
15
mypy.ini
@ -2725,21 +2725,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.unifi.unifi_entity_base]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.upnp]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.upnp.binary_sensor]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.upnp.config_flow]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.upnp.device]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.upnp.sensor]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.vizio.config_flow]
|
||||
ignore_errors = true
|
||||
|
||||
|
@ -150,11 +150,6 @@ IGNORED_MODULES: Final[list[str]] = [
|
||||
"homeassistant.components.unifi.device_tracker",
|
||||
"homeassistant.components.unifi.diagnostics",
|
||||
"homeassistant.components.unifi.unifi_entity_base",
|
||||
"homeassistant.components.upnp",
|
||||
"homeassistant.components.upnp.binary_sensor",
|
||||
"homeassistant.components.upnp.config_flow",
|
||||
"homeassistant.components.upnp.device",
|
||||
"homeassistant.components.upnp.sensor",
|
||||
"homeassistant.components.vizio.config_flow",
|
||||
"homeassistant.components.vizio.media_player",
|
||||
"homeassistant.components.withings",
|
||||
|
Loading…
x
Reference in New Issue
Block a user