mirror of
https://github.com/home-assistant/core.git
synced 2025-06-25 01:21:51 +02:00
Add upload and download sensors and component for asuswrt (#17757)
* Adds upload and download sensors for asuswrt and makes it a component. * Rebase * removes warnings * Fixing review issues * More robust connection phase * Generate dependencies * Not needed try catch * Rename sensors * Revorked tests so they can be turned on again * Using component setup * Test through correct setup * Forgot we dont need to worry about older py
This commit is contained in:
committed by
Martin Hjelmare
parent
d93716bd84
commit
aa4da479b5
68
homeassistant/components/asuswrt.py
Normal file
68
homeassistant/components/asuswrt.py
Normal file
@ -0,0 +1,68 @@
|
||||
"""
|
||||
Support for ASUSWRT devices.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/asuswrt/
|
||||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_PORT, CONF_MODE,
|
||||
CONF_PROTOCOL)
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
|
||||
REQUIREMENTS = ['aioasuswrt==1.1.4']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = "asuswrt"
|
||||
DATA_ASUSWRT = DOMAIN
|
||||
|
||||
CONF_PUB_KEY = 'pub_key'
|
||||
CONF_SSH_KEY = 'ssh_key'
|
||||
CONF_REQUIRE_IP = 'require_ip'
|
||||
DEFAULT_SSH_PORT = 22
|
||||
SECRET_GROUP = 'Password or SSH Key'
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
vol.Optional(CONF_PROTOCOL, default='ssh'): vol.In(['ssh', 'telnet']),
|
||||
vol.Optional(CONF_MODE, default='router'): vol.In(['router', 'ap']),
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_SSH_PORT): cv.port,
|
||||
vol.Optional(CONF_REQUIRE_IP, default=True): cv.boolean,
|
||||
vol.Exclusive(CONF_PASSWORD, SECRET_GROUP): cv.string,
|
||||
vol.Exclusive(CONF_SSH_KEY, SECRET_GROUP): cv.isfile,
|
||||
vol.Exclusive(CONF_PUB_KEY, SECRET_GROUP): cv.isfile
|
||||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up the asuswrt component."""
|
||||
from aioasuswrt.asuswrt import AsusWrt
|
||||
conf = config[DOMAIN]
|
||||
|
||||
api = AsusWrt(conf[CONF_HOST], conf.get(CONF_PORT),
|
||||
conf.get(CONF_PROTOCOL) == 'telnet',
|
||||
conf[CONF_USERNAME],
|
||||
conf.get(CONF_PASSWORD, ''),
|
||||
conf.get('ssh_key', conf.get('pub_key', '')),
|
||||
conf.get(CONF_MODE), conf.get(CONF_REQUIRE_IP))
|
||||
|
||||
await api.connection.async_connect()
|
||||
if not api.is_connected:
|
||||
_LOGGER.error("Unable to setup asuswrt component")
|
||||
return False
|
||||
|
||||
hass.data[DATA_ASUSWRT] = api
|
||||
|
||||
hass.async_create_task(async_load_platform(
|
||||
hass, 'sensor', DOMAIN, {}, config))
|
||||
hass.async_create_task(async_load_platform(
|
||||
hass, 'device_tracker', DOMAIN, {}, config))
|
||||
return True
|
@ -6,43 +6,17 @@ https://home-assistant.io/components/device_tracker.asuswrt/
|
||||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
from homeassistant.components.asuswrt import DATA_ASUSWRT
|
||||
from homeassistant.components.device_tracker import DeviceScanner
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.device_tracker import (
|
||||
DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_PORT, CONF_MODE,
|
||||
CONF_PROTOCOL)
|
||||
|
||||
REQUIREMENTS = ['aioasuswrt==1.1.2']
|
||||
DEPENDENCIES = ['asuswrt']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_PUB_KEY = 'pub_key'
|
||||
CONF_SSH_KEY = 'ssh_key'
|
||||
CONF_REQUIRE_IP = 'require_ip'
|
||||
DEFAULT_SSH_PORT = 22
|
||||
SECRET_GROUP = 'Password or SSH Key'
|
||||
|
||||
PLATFORM_SCHEMA = vol.All(
|
||||
cv.has_at_least_one_key(CONF_PASSWORD, CONF_PUB_KEY, CONF_SSH_KEY),
|
||||
PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
vol.Optional(CONF_PROTOCOL, default='ssh'): vol.In(['ssh', 'telnet']),
|
||||
vol.Optional(CONF_MODE, default='router'): vol.In(['router', 'ap']),
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_SSH_PORT): cv.port,
|
||||
vol.Optional(CONF_REQUIRE_IP, default=True): cv.boolean,
|
||||
vol.Exclusive(CONF_PASSWORD, SECRET_GROUP): cv.string,
|
||||
vol.Exclusive(CONF_SSH_KEY, SECRET_GROUP): cv.isfile,
|
||||
vol.Exclusive(CONF_PUB_KEY, SECRET_GROUP): cv.isfile
|
||||
}))
|
||||
|
||||
|
||||
async def async_get_scanner(hass, config):
|
||||
"""Validate the configuration and return an ASUS-WRT scanner."""
|
||||
scanner = AsusWrtDeviceScanner(config[DOMAIN])
|
||||
scanner = AsusWrtDeviceScanner(hass.data[DATA_ASUSWRT])
|
||||
await scanner.async_connect()
|
||||
return scanner if scanner.success_init else None
|
||||
|
||||
@ -51,19 +25,11 @@ class AsusWrtDeviceScanner(DeviceScanner):
|
||||
"""This class queries a router running ASUSWRT firmware."""
|
||||
|
||||
# Eighth attribute needed for mode (AP mode vs router mode)
|
||||
def __init__(self, config):
|
||||
def __init__(self, api):
|
||||
"""Initialize the scanner."""
|
||||
from aioasuswrt.asuswrt import AsusWrt
|
||||
|
||||
self.last_results = {}
|
||||
self.success_init = False
|
||||
self.connection = AsusWrt(config[CONF_HOST], config[CONF_PORT],
|
||||
config[CONF_PROTOCOL] == 'telnet',
|
||||
config[CONF_USERNAME],
|
||||
config.get(CONF_PASSWORD, ''),
|
||||
config.get('ssh_key',
|
||||
config.get('pub_key', '')),
|
||||
config[CONF_MODE], config[CONF_REQUIRE_IP])
|
||||
self.connection = api
|
||||
|
||||
async def async_connect(self):
|
||||
"""Initialize connection to the router."""
|
||||
|
126
homeassistant/components/sensor/asuswrt.py
Normal file
126
homeassistant/components/sensor/asuswrt.py
Normal file
@ -0,0 +1,126 @@
|
||||
"""
|
||||
Asuswrt status sensors.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.asuswrt/
|
||||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.components.asuswrt import DATA_ASUSWRT
|
||||
|
||||
DEPENDENCIES = ['asuswrt']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the asuswrt sensors."""
|
||||
api = hass.data[DATA_ASUSWRT]
|
||||
add_entities([
|
||||
AsuswrtRXSensor(api),
|
||||
AsuswrtTXSensor(api),
|
||||
AsuswrtTotalRXSensor(api),
|
||||
AsuswrtTotalTXSensor(api)
|
||||
])
|
||||
|
||||
|
||||
class AsuswrtSensor(Entity):
|
||||
"""Representation of a asuswrt sensor."""
|
||||
|
||||
_name = 'generic'
|
||||
|
||||
def __init__(self, api):
|
||||
"""Initialize the sensor."""
|
||||
self._api = api
|
||||
self._state = None
|
||||
self._rates = None
|
||||
self._speed = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
async def async_update(self):
|
||||
"""Fetch status from asuswrt."""
|
||||
self._rates = await self._api.async_get_packets_total()
|
||||
self._speed = await self._api.async_get_current_transfer_rates()
|
||||
|
||||
|
||||
class AsuswrtRXSensor(AsuswrtSensor):
|
||||
"""Representation of a asuswrt download speed sensor."""
|
||||
|
||||
_name = 'Asuswrt Download Speed'
|
||||
_unit = 'Mbit/s'
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self._unit
|
||||
|
||||
async def async_update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
await super().async_update()
|
||||
if self._speed is not None:
|
||||
self._state = round(self._speed[0] / 125000, 2)
|
||||
|
||||
|
||||
class AsuswrtTXSensor(AsuswrtSensor):
|
||||
"""Representation of a asuswrt upload speed sensor."""
|
||||
|
||||
_name = 'Asuswrt Upload Speed'
|
||||
_unit = 'Mbit/s'
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self._unit
|
||||
|
||||
async def async_update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
await super().async_update()
|
||||
if self._speed is not None:
|
||||
self._state = round(self._speed[1] / 125000, 2)
|
||||
|
||||
|
||||
class AsuswrtTotalRXSensor(AsuswrtSensor):
|
||||
"""Representation of a asuswrt total download sensor."""
|
||||
|
||||
_name = 'Asuswrt Download'
|
||||
_unit = 'Gigabyte'
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self._unit
|
||||
|
||||
async def async_update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
await super().async_update()
|
||||
if self._rates is not None:
|
||||
self._state = round(self._rates[0] / 1000000000, 1)
|
||||
|
||||
|
||||
class AsuswrtTotalTXSensor(AsuswrtSensor):
|
||||
"""Representation of a asuswrt total upload sensor."""
|
||||
|
||||
_name = 'Asuswrt Upload'
|
||||
_unit = 'Gigabyte'
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self._unit
|
||||
|
||||
async def async_update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
await super().async_update()
|
||||
if self._rates is not None:
|
||||
self._state = round(self._rates[1] / 1000000000, 1)
|
@ -85,8 +85,8 @@ abodepy==0.14.0
|
||||
# homeassistant.components.media_player.frontier_silicon
|
||||
afsapi==0.0.4
|
||||
|
||||
# homeassistant.components.device_tracker.asuswrt
|
||||
aioasuswrt==1.1.2
|
||||
# homeassistant.components.asuswrt
|
||||
aioasuswrt==1.1.4
|
||||
|
||||
# homeassistant.components.device_tracker.automatic
|
||||
aioautomatic==0.6.5
|
||||
|
50
tests/components/device_tracker/test_asuswrt.py
Normal file
50
tests/components/device_tracker/test_asuswrt.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""The tests for the ASUSWRT device tracker platform."""
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from homeassistant.components.asuswrt import (
|
||||
CONF_PROTOCOL, CONF_MODE, DOMAIN, CONF_PORT, DATA_ASUSWRT)
|
||||
from homeassistant.const import (CONF_PLATFORM, CONF_PASSWORD, CONF_USERNAME,
|
||||
CONF_HOST)
|
||||
|
||||
from tests.common import MockDependency, mock_coro_func
|
||||
|
||||
FAKEFILE = None
|
||||
|
||||
VALID_CONFIG_ROUTER_SSH = {DOMAIN: {
|
||||
CONF_PLATFORM: 'asuswrt',
|
||||
CONF_HOST: 'fake_host',
|
||||
CONF_USERNAME: 'fake_user',
|
||||
CONF_PROTOCOL: 'ssh',
|
||||
CONF_MODE: 'router',
|
||||
CONF_PORT: '22'
|
||||
}}
|
||||
|
||||
|
||||
async def test_password_or_pub_key_required(hass):
|
||||
"""Test creating an AsusWRT scanner without a pass or pubkey."""
|
||||
with MockDependency('aioasuswrt.asuswrt')as mocked_asus:
|
||||
mocked_asus.AsusWrt().connection.async_connect = mock_coro_func()
|
||||
mocked_asus.AsusWrt().is_connected = False
|
||||
result = await async_setup_component(
|
||||
hass, DOMAIN, {DOMAIN: {
|
||||
CONF_HOST: 'fake_host',
|
||||
CONF_USERNAME: 'fake_user'
|
||||
}})
|
||||
assert not result
|
||||
|
||||
|
||||
async def test_get_scanner_with_password_no_pubkey(hass):
|
||||
"""Test creating an AsusWRT scanner with a password and no pubkey."""
|
||||
with MockDependency('aioasuswrt.asuswrt')as mocked_asus:
|
||||
mocked_asus.AsusWrt().connection.async_connect = mock_coro_func()
|
||||
mocked_asus.AsusWrt(
|
||||
).connection.async_get_connected_devices = mock_coro_func(
|
||||
return_value={})
|
||||
result = await async_setup_component(
|
||||
hass, DOMAIN, {DOMAIN: {
|
||||
CONF_HOST: 'fake_host',
|
||||
CONF_USERNAME: 'fake_user',
|
||||
CONF_PASSWORD: '4321'
|
||||
}})
|
||||
assert result
|
||||
assert hass.data[DATA_ASUSWRT] is not None
|
Reference in New Issue
Block a user