Add strict typing to mikrotik (#76974)

add strict typing to mikrotik
This commit is contained in:
Rami Mosleh 2022-08-19 11:39:14 +03:00 committed by GitHub
parent 801f7d1d5f
commit 655e2f92ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 68 deletions

View File

@ -170,6 +170,7 @@ homeassistant.components.mailbox.*
homeassistant.components.media_player.*
homeassistant.components.media_source.*
homeassistant.components.metoffice.*
homeassistant.components.mikrotik.*
homeassistant.components.mjpeg.*
homeassistant.components.modbus.*
homeassistant.components.modem_callerid.*

View File

@ -1,15 +1,18 @@
"""The Mikrotik component."""
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv, device_registry as dr
from .const import ATTR_MANUFACTURER, DOMAIN, PLATFORMS
from .const import ATTR_MANUFACTURER, DOMAIN
from .errors import CannotConnect, LoginError
from .hub import MikrotikDataUpdateCoordinator, get_api
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
PLATFORMS = [Platform.DEVICE_TRACKER]
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up the Mikrotik component."""
@ -26,7 +29,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = coordinator
hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(

View File

@ -1,8 +1,6 @@
"""Constants used in the Mikrotik components."""
from typing import Final
from homeassistant.const import Platform
DOMAIN: Final = "mikrotik"
DEFAULT_NAME: Final = "Mikrotik"
DEFAULT_API_PORT: Final = 8728
@ -40,7 +38,6 @@ MIKROTIK_SERVICES: Final = {
IS_CAPSMAN: "/caps-man/interface/print",
}
PLATFORMS: Final = [Platform.DEVICE_TRACKER]
ATTR_DEVICE_TRACKER: Final = [
"comment",

View File

@ -0,0 +1,66 @@
"""Network client device class."""
from __future__ import annotations
from datetime import datetime
from typing import Any
from homeassistant.util import slugify
import homeassistant.util.dt as dt_util
from .const import ATTR_DEVICE_TRACKER
class Device:
"""Represents a network device."""
def __init__(self, mac: str, params: dict[str, Any]) -> None:
"""Initialize the network device."""
self._mac = mac
self._params = params
self._last_seen: datetime | None = None
self._attrs: dict[str, Any] = {}
self._wireless_params: dict[str, Any] = {}
@property
def name(self) -> str:
"""Return device name."""
return self._params.get("host-name", self.mac)
@property
def ip_address(self) -> str | None:
"""Return device primary ip address."""
return self._params.get("address")
@property
def mac(self) -> str:
"""Return device mac."""
return self._mac
@property
def last_seen(self) -> datetime | None:
"""Return device last seen."""
return self._last_seen
@property
def attrs(self) -> dict[str, Any]:
"""Return device attributes."""
attr_data = self._wireless_params | self._params
for attr in ATTR_DEVICE_TRACKER:
if attr in attr_data:
self._attrs[slugify(attr)] = attr_data[attr]
return self._attrs
def update(
self,
wireless_params: dict[str, Any] | None = None,
params: dict[str, Any] | None = None,
active: bool = False,
) -> None:
"""Update Device params."""
if wireless_params:
self._wireless_params = wireless_params
if params:
self._params = params
if active:
self._last_seen = dt_util.utcnow()

View File

@ -63,7 +63,7 @@ def update_items(
coordinator: MikrotikDataUpdateCoordinator,
async_add_entities: AddEntitiesCallback,
tracked: dict[str, MikrotikDataUpdateCoordinatorTracker],
):
) -> None:
"""Update tracked device state from the hub."""
new_tracked: list[MikrotikDataUpdateCoordinatorTracker] = []
for mac, device in coordinator.api.devices.items():

View File

@ -1,7 +1,7 @@
"""The Mikrotik router class."""
from __future__ import annotations
from datetime import datetime, timedelta
from datetime import timedelta
import logging
import socket
import ssl
@ -14,12 +14,9 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import slugify
import homeassistant.util.dt as dt_util
from .const import (
ARP,
ATTR_DEVICE_TRACKER,
ATTR_FIRMWARE,
ATTR_MODEL,
ATTR_SERIAL_NUMBER,
@ -38,66 +35,12 @@ from .const import (
NAME,
WIRELESS,
)
from .device import Device
from .errors import CannotConnect, LoginError
_LOGGER = logging.getLogger(__name__)
class Device:
"""Represents a network device."""
def __init__(self, mac: str, params: dict[str, Any]) -> None:
"""Initialize the network device."""
self._mac = mac
self._params = params
self._last_seen: datetime | None = None
self._attrs: dict[str, Any] = {}
self._wireless_params: dict[str, Any] = {}
@property
def name(self) -> str:
"""Return device name."""
return self._params.get("host-name", self.mac)
@property
def ip_address(self) -> str | None:
"""Return device primary ip address."""
return self._params.get("address")
@property
def mac(self) -> str:
"""Return device mac."""
return self._mac
@property
def last_seen(self) -> datetime | None:
"""Return device last seen."""
return self._last_seen
@property
def attrs(self) -> dict[str, Any]:
"""Return device attributes."""
attr_data = self._wireless_params | self._params
for attr in ATTR_DEVICE_TRACKER:
if attr in attr_data:
self._attrs[slugify(attr)] = attr_data[attr]
return self._attrs
def update(
self,
wireless_params: dict[str, Any] | None = None,
params: dict[str, Any] | None = None,
active: bool = False,
) -> None:
"""Update Device params."""
if wireless_params:
self._wireless_params = wireless_params
if params:
self._params = params
if active:
self._last_seen = dt_util.utcnow()
class MikrotikData:
"""Handle all communication with the Mikrotik API."""
@ -248,8 +191,8 @@ class MikrotikData:
self, cmd: str, params: dict[str, Any] | None = None
) -> list[dict[str, Any]]:
"""Retrieve data from Mikrotik API."""
_LOGGER.debug("Running command %s", cmd)
try:
_LOGGER.debug("Running command %s", cmd)
if params:
return list(self.api(cmd=cmd, **params))
return list(self.api(cmd=cmd))
@ -273,7 +216,7 @@ class MikrotikData:
return []
class MikrotikDataUpdateCoordinator(DataUpdateCoordinator):
class MikrotikDataUpdateCoordinator(DataUpdateCoordinator[None]):
"""Mikrotik Hub Object."""
def __init__(
@ -293,7 +236,7 @@ class MikrotikDataUpdateCoordinator(DataUpdateCoordinator):
@property
def host(self) -> str:
"""Return the host of this hub."""
return self.config_entry.data[CONF_HOST]
return str(self.config_entry.data[CONF_HOST])
@property
def hostname(self) -> str:

View File

@ -1459,6 +1459,16 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.mikrotik.*]
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.mjpeg.*]
check_untyped_defs = true
disallow_incomplete_defs = true