From 903e6b5aee0052d4c676a4eb1dfaac0cad99b114 Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Fri, 7 Jul 2017 07:05:09 +0100 Subject: [PATCH] Upnp mapping notification (#8303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * UPnP mapping overlap Addressing: https://community.home-assistant.io/t/upnp-new-module/20839 * removed whitespaces --- homeassistant/components/upnp.py | 39 ++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/upnp.py b/homeassistant/components/upnp.py index a058fdae85e..355a6d0a648 100644 --- a/homeassistant/components/upnp.py +++ b/homeassistant/components/upnp.py @@ -9,6 +9,8 @@ from urllib.parse import urlsplit import voluptuous as vol +import homeassistant.loader as loader + from homeassistant.const import (EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers import config_validation as cv from homeassistant.helpers import discovery @@ -23,8 +25,12 @@ DOMAIN = 'upnp' DATA_UPNP = 'UPNP' CONF_ENABLE_PORT_MAPPING = 'port_mapping' +CONF_EXTERNAL_PORT = 'external_port' CONF_UNITS = 'unit' +NOTIFICATION_ID = 'upnp_notification' +NOTIFICATION_TITLE = 'UPnP Setup' + UNITS = { "Bytes": 1, "KBytes": 1024, @@ -35,6 +41,7 @@ UNITS = { CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ vol.Optional(CONF_ENABLE_PORT_MAPPING, default=True): cv.boolean, + vol.Optional(CONF_EXTERNAL_PORT, default=0): cv.positive_int, vol.Optional(CONF_UNITS, default="MBytes"): vol.In(UNITS), }), }, extra=vol.ALLOW_EXTRA) @@ -65,15 +72,33 @@ def setup(hass, config): base_url = urlsplit(hass.config.api.base_url) host = base_url.hostname - external_port = internal_port = base_url.port + internal_port = base_url.port + external_port = int(config[DOMAIN].get(CONF_EXTERNAL_PORT)) - upnp.addportmapping( - external_port, 'TCP', host, internal_port, 'Home Assistant', '') + if external_port == 0: + external_port = internal_port - def deregister_port(event): - """De-register the UPnP port mapping.""" - upnp.deleteportmapping(hass.config.api.port, 'TCP') + persistent_notification = loader.get_component('persistent_notification') - hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, deregister_port) + try: + upnp.addportmapping( + external_port, 'TCP', host, internal_port, 'Home Assistant', '') + def deregister_port(event): + """De-register the UPnP port mapping.""" + upnp.deleteportmapping(external_port, 'TCP') + + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, deregister_port) + + except Exception as ex: + _LOGGER.error("UPnP failed to configure port mapping: %s", str(ex)) + persistent_notification.create( + hass, 'ERROR: tcp port {} is already mapped in your router.' + '
Please disable port_mapping in the upnp ' + 'configuration section.
' + 'You will need to restart hass after fixing.' + ''.format(external_port), + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID) + return False return True