Upnp properties (#8067)

* make port mapping optional

* dependencies + improvements

* Added bytes and packets sensors from IGD

* flake8 check

* new sensor with upnp counters

* checks

* whitespaces in blank line

* requirements update

* added sensor.upnp to .coveragerc

* downgrade miniupnpc

Latest version of miniupnpc is 2.0, but pypi only has 1.9

Fortunately it is enough

* revert to non async

miniupnpc will do network calls, so this component can’t be moved to
coroutine

* hof hof

forgot to remove import ot asyncio
This commit is contained in:
Diogo Gomes 2017-06-19 05:32:39 +01:00 committed by Paulus Schoutsen
parent 35132f9836
commit 83b791489b
4 changed files with 108 additions and 2 deletions

View File

@ -471,6 +471,7 @@ omit =
homeassistant/components/sensor/transmission.py homeassistant/components/sensor/transmission.py
homeassistant/components/sensor/twitch.py homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py homeassistant/components/sensor/uber.py
homeassistant/components/sensor/upnp.py
homeassistant/components/sensor/ups.py homeassistant/components/sensor/ups.py
homeassistant/components/sensor/usps.py homeassistant/components/sensor/usps.py
homeassistant/components/sensor/vasttrafik.py homeassistant/components/sensor/vasttrafik.py

View File

@ -0,0 +1,75 @@
"""
Support for UPnP Sensors (IGD).
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.upnp/
"""
import logging
from homeassistant.components.upnp import DATA_UPNP, UNITS
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
# sensor_type: [friendly_name, convert_unit, icon]
SENSOR_TYPES = {
'byte_received': ['received bytes', True, 'mdi:server-network'],
'byte_sent': ['sent bytes', True, 'mdi:server-network'],
'packets_in': ['packets received', False, 'mdi:server-network'],
'packets_out': ['packets sent', False, 'mdi:server-network'],
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the IGD sensors."""
upnp = hass.data[DATA_UPNP]
unit = discovery_info['unit']
add_devices([
IGDSensor(upnp, t, unit if SENSOR_TYPES[t][1] else None)
for t in SENSOR_TYPES], True)
class IGDSensor(Entity):
"""Representation of a UPnP IGD sensor."""
def __init__(self, upnp, sensor_type, unit=""):
"""Initialize the IGD sensor."""
self._upnp = upnp
self.type = sensor_type
self.unit = unit
self.unit_factor = UNITS[unit] if unit is not None else 1
self._name = 'IGD {}'.format(SENSOR_TYPES[sensor_type][0])
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def state(self):
"""Return the state of the device."""
if self._state is None:
return None
return format(self._state / self.unit_factor, '.1f')
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return SENSOR_TYPES[self.type][2]
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self.unit
def update(self):
"""Get the latest information from the IGD."""
if self.type == "byte_received":
self._state = self._upnp.totalbytereceived()
elif self.type == "byte_sent":
self._state = self._upnp.totalbytesent()
elif self.type == "packets_in":
self._state = self._upnp.totalpacketreceived()
elif self.type == "packets_out":
self._state = self._upnp.totalpacketsent()

View File

@ -1,5 +1,5 @@
""" """
This module will attempt to open a port in your router for Home Assistant. Will open a port in your router for Home Assistant and provide statistics.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/upnp/ https://home-assistant.io/components/upnp/
@ -10,14 +10,33 @@ from urllib.parse import urlsplit
import voluptuous as vol import voluptuous as vol
from homeassistant.const import (EVENT_HOMEASSISTANT_STOP) from homeassistant.const import (EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery
REQUIREMENTS = ['miniupnpc==1.9']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['api'] DEPENDENCIES = ['api']
DOMAIN = 'upnp' DOMAIN = 'upnp'
DATA_UPNP = 'UPNP'
CONF_ENABLE_PORT_MAPPING = 'port_mapping'
CONF_UNITS = 'unit'
UNITS = {
"Bytes": 1,
"KBytes": 1024,
"MBytes": 1024**2,
"GBytes": 1024**3,
}
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({}), DOMAIN: vol.Schema({
vol.Optional(CONF_ENABLE_PORT_MAPPING, default=True): cv.boolean,
vol.Optional(CONF_UNITS, default="MBytes"): vol.In(UNITS),
}),
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
@ -27,6 +46,7 @@ def setup(hass, config):
import miniupnpc import miniupnpc
upnp = miniupnpc.UPnP() upnp = miniupnpc.UPnP()
hass.data[DATA_UPNP] = upnp
upnp.discoverdelay = 200 upnp.discoverdelay = 200
upnp.discover() upnp.discover()
@ -36,6 +56,13 @@ def setup(hass, config):
_LOGGER.exception("Error when attempting to discover an UPnP IGD") _LOGGER.exception("Error when attempting to discover an UPnP IGD")
return False return False
unit = config[DOMAIN].get(CONF_UNITS)
discovery.load_platform(hass, 'sensor', DOMAIN, {'unit': unit}, config)
port_mapping = config[DOMAIN].get(CONF_ENABLE_PORT_MAPPING)
if not port_mapping:
return True
base_url = urlsplit(hass.config.api.base_url) base_url = urlsplit(hass.config.api.base_url)
host = base_url.hostname host = base_url.hostname
external_port = internal_port = base_url.port external_port = internal_port = base_url.port

View File

@ -378,6 +378,9 @@ mficlient==0.3.0
# homeassistant.components.sensor.miflora # homeassistant.components.sensor.miflora
miflora==0.1.16 miflora==0.1.16
# homeassistant.components.upnp
miniupnpc==1.9
# homeassistant.components.tts # homeassistant.components.tts
mutagen==1.37.0 mutagen==1.37.0