Add Asuswrt Config Flow and Scanner Entities (#46468)
* Add Asuswrt config flow (#43948) * Add AsusWrt Scanner Entity (#44759) * Add Scanner Entity - device tracker entity changed from "DeviceScanner" to "ScannerEntity" - sensors recoded to use "router" class - config entry review to allow multiple entity (for future use) * Force checks * Removed new option and change sensors * Update test_sensor.py * Requested changes * Removed router unique-id * Update last_activity attr only when available * Add Options for AsusWRT Scanner Entity (#44808) * Add Asuswrt config flow (#43948) * Add AsusWrt Scanner Entity (#44759) * Add Scanner Entity - device tracker entity changed from "DeviceScanner" to "ScannerEntity" - sensors recoded to use "router" class - config entry review to allow multiple entity (for future use) * Force checks * Removed new option and change sensors * Update test_sensor.py * Requested changes * Removed router unique-id * Update last_activity attr only when available * Add Options for Scanner Entity * Fix isort * Removed "Track New" option * Add Options for Scanner Entity * Fix isort * Removed "Track New" option * Add test for all the options in the config flow
This commit is contained in:
parent
6f261a09b0
commit
f38b06ed6d
14 changed files with 1406 additions and 315 deletions
|
@ -6,13 +6,15 @@ from typing import Any, Dict, List, Optional
|
|||
|
||||
from aioasuswrt.asuswrt import AsusWrt
|
||||
|
||||
from homeassistant.const import DATA_GIGABYTES, DATA_RATE_MEGABITS_PER_SECOND
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_NAME, DATA_GIGABYTES, DATA_RATE_MEGABITS_PER_SECOND
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
from homeassistant.helpers.update_coordinator import (
|
||||
CoordinatorEntity,
|
||||
DataUpdateCoordinator,
|
||||
)
|
||||
|
||||
from . import DATA_ASUSWRT
|
||||
from .const import DATA_ASUSWRT, DOMAIN, SENSOR_TYPES
|
||||
|
||||
UPLOAD_ICON = "mdi:upload-network"
|
||||
DOWNLOAD_ICON = "mdi:download-network"
|
||||
|
@ -35,6 +37,8 @@ class _SensorTypes(enum.Enum):
|
|||
return DATA_GIGABYTES
|
||||
if self in (_SensorTypes.UPLOAD_SPEED, _SensorTypes.DOWNLOAD_SPEED):
|
||||
return DATA_RATE_MEGABITS_PER_SECOND
|
||||
if self == _SensorTypes.DEVICES:
|
||||
return "devices"
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -72,15 +76,26 @@ class _SensorTypes(enum.Enum):
|
|||
return self in (_SensorTypes.UPLOAD, _SensorTypes.DOWNLOAD)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up the asuswrt sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
class _SensorInfo:
|
||||
"""Class handling sensor information."""
|
||||
|
||||
api: AsusWrt = hass.data[DATA_ASUSWRT]
|
||||
def __init__(self, sensor_type: _SensorTypes):
|
||||
"""Initialize the handler class."""
|
||||
self.type = sensor_type
|
||||
self.enabled = False
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
|
||||
) -> None:
|
||||
"""Set up the asuswrt sensors."""
|
||||
|
||||
router = hass.data[DOMAIN][entry.entry_id][DATA_ASUSWRT]
|
||||
api: AsusWrt = router.api
|
||||
device_name = entry.data.get(CONF_NAME, "AsusWRT")
|
||||
|
||||
# Let's discover the valid sensor types.
|
||||
sensors = [_SensorTypes(x) for x in discovery_info]
|
||||
sensors = [_SensorInfo(_SensorTypes(x)) for x in SENSOR_TYPES]
|
||||
|
||||
data_handler = AsuswrtDataHandler(sensors, api)
|
||||
coordinator = DataUpdateCoordinator(
|
||||
|
@ -93,34 +108,50 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
)
|
||||
|
||||
await coordinator.async_refresh()
|
||||
async_add_entities([AsuswrtSensor(coordinator, x) for x in sensors])
|
||||
async_add_entities(
|
||||
[AsuswrtSensor(coordinator, data_handler, device_name, x.type) for x in sensors]
|
||||
)
|
||||
|
||||
|
||||
class AsuswrtDataHandler:
|
||||
"""Class handling the API updates."""
|
||||
|
||||
def __init__(self, sensors: List[_SensorTypes], api: AsusWrt):
|
||||
def __init__(self, sensors: List[_SensorInfo], api: AsusWrt):
|
||||
"""Initialize the handler class."""
|
||||
self._api = api
|
||||
self._sensors = sensors
|
||||
self._connected = True
|
||||
|
||||
def enable_sensor(self, sensor_type: _SensorTypes):
|
||||
"""Enable a specific sensor type."""
|
||||
for index, sensor in enumerate(self._sensors):
|
||||
if sensor.type == sensor_type:
|
||||
self._sensors[index].enabled = True
|
||||
return
|
||||
|
||||
def disable_sensor(self, sensor_type: _SensorTypes):
|
||||
"""Disable a specific sensor type."""
|
||||
for index, sensor in enumerate(self._sensors):
|
||||
if sensor.type == sensor_type:
|
||||
self._sensors[index].enabled = False
|
||||
return
|
||||
|
||||
async def update_data(self) -> Dict[_SensorTypes, Any]:
|
||||
"""Fetch the relevant data from the router."""
|
||||
ret_dict: Dict[_SensorTypes, Any] = {}
|
||||
try:
|
||||
if _SensorTypes.DEVICES in self._sensors:
|
||||
if _SensorTypes.DEVICES in [x.type for x in self._sensors if x.enabled]:
|
||||
# Let's check the nr of devices.
|
||||
devices = await self._api.async_get_connected_devices()
|
||||
ret_dict[_SensorTypes.DEVICES] = len(devices)
|
||||
|
||||
if any(x.is_speed for x in self._sensors):
|
||||
if any(x.type.is_speed for x in self._sensors if x.enabled):
|
||||
# Let's check the upload and download speed
|
||||
speed = await self._api.async_get_current_transfer_rates()
|
||||
ret_dict[_SensorTypes.DOWNLOAD_SPEED] = round(speed[0] / 125000, 2)
|
||||
ret_dict[_SensorTypes.UPLOAD_SPEED] = round(speed[1] / 125000, 2)
|
||||
|
||||
if any(x.is_size for x in self._sensors):
|
||||
if any(x.type.is_size for x in self._sensors if x.enabled):
|
||||
rates = await self._api.async_get_bytes_total()
|
||||
ret_dict[_SensorTypes.DOWNLOAD] = round(rates[0] / 1000000000, 1)
|
||||
ret_dict[_SensorTypes.UPLOAD] = round(rates[1] / 1000000000, 1)
|
||||
|
@ -142,9 +173,17 @@ class AsuswrtDataHandler:
|
|||
class AsuswrtSensor(CoordinatorEntity):
|
||||
"""The asuswrt specific sensor class."""
|
||||
|
||||
def __init__(self, coordinator: DataUpdateCoordinator, sensor_type: _SensorTypes):
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
data_handler: AsuswrtDataHandler,
|
||||
device_name: str,
|
||||
sensor_type: _SensorTypes,
|
||||
):
|
||||
"""Initialize the sensor class."""
|
||||
super().__init__(coordinator)
|
||||
self._handler = data_handler
|
||||
self._device_name = device_name
|
||||
self._type = sensor_type
|
||||
|
||||
@property
|
||||
|
@ -164,5 +203,34 @@ class AsuswrtSensor(CoordinatorEntity):
|
|||
|
||||
@property
|
||||
def unit_of_measurement(self) -> Optional[str]:
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
"""Return the unit."""
|
||||
return self._type.unit_of_measurement
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return the unique_id of the sensor."""
|
||||
return f"{DOMAIN} {self._type.sensor_name}"
|
||||
|
||||
@property
|
||||
def device_info(self) -> Dict[str, any]:
|
||||
"""Return the device information."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, "AsusWRT")},
|
||||
"name": self._device_name,
|
||||
"model": "Asus Router",
|
||||
"manufacturer": "Asus",
|
||||
}
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self) -> bool:
|
||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||
return False
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""When entity is added to hass."""
|
||||
self._handler.enable_sensor(self._type)
|
||||
await super().async_added_to_hass()
|
||||
|
||||
async def async_will_remove_from_hass(self):
|
||||
"""Call when entity is removed from hass."""
|
||||
self._handler.disable_sensor(self._type)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue