From 86dad0c0457ca9155d8ec9150e1d46f58201ade8 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Wed, 6 Apr 2016 13:51:26 -0700 Subject: [PATCH 01/10] Add ZeroConf support to http.py --- homeassistant/components/http.py | 36 ++++++++++++++++++++++++++++---- requirements_all.txt | 3 +++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 00b35dda8c9..18bac7c46fd 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -7,6 +7,7 @@ https://home-assistant.io/developers/api/ import gzip import json import logging +import socket import ssl import threading import time @@ -27,7 +28,9 @@ from homeassistant.const import ( HTTP_HEADER_CONTENT_LENGTH, HTTP_HEADER_CONTENT_TYPE, HTTP_HEADER_EXPIRES, HTTP_HEADER_HA_AUTH, HTTP_HEADER_VARY, HTTP_METHOD_NOT_ALLOWED, HTTP_NOT_FOUND, HTTP_OK, HTTP_UNAUTHORIZED, HTTP_UNPROCESSABLE_ENTITY, - SERVER_PORT) + SERVER_PORT, __version__) + +REQUIREMENTS = ["zeroconf==0.17.5"] DOMAIN = "http" @@ -108,6 +111,10 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): # We will lazy init this one if needed self.event_forwarder = None + from zeroconf import Zeroconf + + self.zeroconf = Zeroconf() + if development: _LOGGER.info("running http in development mode") @@ -122,14 +129,35 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): def stop_http(event): """Stop the HTTP server.""" self.shutdown() + self.zeroconf.unregister_all_services() self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http) protocol = 'https' if self.use_ssl else 'http' - _LOGGER.info( - "Starting web interface at %s://%s:%d", - protocol, self.server_address[0], self.server_address[1]) + base_url = "{}://{}:{}".format(protocol, util.get_local_ip(), + self.server_address[1]) + + zeroconf_type = "_home-assistant._tcp.local." + zeroconf_name = "{}.{}".format(self.hass.config.location_name, + zeroconf_type) + + ip_address = socket.inet_aton(util.get_local_ip()) + + has_device_tracker = ("device_tracker" in self.hass.config.components) + + params = {"version": __version__, "base_url": base_url, + "device_tracker_component": has_device_tracker, + "needs_password": (self.api_password != "")} + + from zeroconf import ServiceInfo + + info = ServiceInfo(zeroconf_type, zeroconf_name, ip_address, + self.server_address[1], 0, 0, params) + + self.zeroconf.register_service(info) + + _LOGGER.info("Starting web interface at %s", base_url) # 31-1-2015: Refactored frontend/api components out of this component # To prevent stuff from breaking, load the two extracted components diff --git a/requirements_all.txt b/requirements_all.txt index c0b011e869d..56829f67f97 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -313,3 +313,6 @@ xbee-helper==0.0.6 # homeassistant.components.sensor.yr xmltodict + +# homeassistant.components.http +zeroconf==0.17.5 From 27aabd961cca59828efbfdba0fc49ff65ccf79d8 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Wed, 6 Apr 2016 13:51:43 -0700 Subject: [PATCH 02/10] Remove unnecessary variable --- homeassistant/components/http.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 18bac7c46fd..99f745adcb2 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -142,8 +142,6 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): zeroconf_name = "{}.{}".format(self.hass.config.location_name, zeroconf_type) - ip_address = socket.inet_aton(util.get_local_ip()) - has_device_tracker = ("device_tracker" in self.hass.config.components) params = {"version": __version__, "base_url": base_url, @@ -152,7 +150,8 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): from zeroconf import ServiceInfo - info = ServiceInfo(zeroconf_type, zeroconf_name, ip_address, + info = ServiceInfo(zeroconf_type, zeroconf_name, + socket.inet_aton(util.get_local_ip()), self.server_address[1], 0, 0, params) self.zeroconf.register_service(info) From c33c2c01d29c611fe1c8b58fbe85d00f9dd2e422 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 15:34:04 -0700 Subject: [PATCH 03/10] Break Zeroconf into its own component --- homeassistant/components/http.py | 37 +++----------------- homeassistant/components/zeroconf.py | 50 ++++++++++++++++++++++++++++ requirements_all.txt | 2 +- 3 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 homeassistant/components/zeroconf.py diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 99f745adcb2..03d18170b3b 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -30,8 +30,6 @@ from homeassistant.const import ( HTTP_NOT_FOUND, HTTP_OK, HTTP_UNAUTHORIZED, HTTP_UNPROCESSABLE_ENTITY, SERVER_PORT, __version__) -REQUIREMENTS = ["zeroconf==0.17.5"] - DOMAIN = "http" CONF_API_PASSWORD = "api_password" @@ -106,15 +104,14 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): self.development = development self.paths = [] self.sessions = SessionStore() - self.use_ssl = ssl_certificate is not None + self.protocol = 'https' if ssl_certificate is not None else 'http' + self.base_url = "{}://{}:{}".format(self.protocol, + util.get_local_ip(), + self.server_address[1]) # We will lazy init this one if needed self.event_forwarder = None - from zeroconf import Zeroconf - - self.zeroconf = Zeroconf() - if development: _LOGGER.info("running http in development mode") @@ -129,34 +126,10 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): def stop_http(event): """Stop the HTTP server.""" self.shutdown() - self.zeroconf.unregister_all_services() self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http) - protocol = 'https' if self.use_ssl else 'http' - - base_url = "{}://{}:{}".format(protocol, util.get_local_ip(), - self.server_address[1]) - - zeroconf_type = "_home-assistant._tcp.local." - zeroconf_name = "{}.{}".format(self.hass.config.location_name, - zeroconf_type) - - has_device_tracker = ("device_tracker" in self.hass.config.components) - - params = {"version": __version__, "base_url": base_url, - "device_tracker_component": has_device_tracker, - "needs_password": (self.api_password != "")} - - from zeroconf import ServiceInfo - - info = ServiceInfo(zeroconf_type, zeroconf_name, - socket.inet_aton(util.get_local_ip()), - self.server_address[1], 0, 0, params) - - self.zeroconf.register_service(info) - - _LOGGER.info("Starting web interface at %s", base_url) + _LOGGER.info("Starting web interface at %s", self.base_url) # 31-1-2015: Refactored frontend/api components out of this component # To prevent stuff from breaking, load the two extracted components diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py new file mode 100644 index 00000000000..a9e773fae6d --- /dev/null +++ b/homeassistant/components/zeroconf.py @@ -0,0 +1,50 @@ +""" +This module exposes Home Assistant via Zeroconf, also sometimes known as +Bonjour, Rendezvous, Avahi or Multicast DNS (mDNS). + +For more details about Zeroconf, please refer to the documentation at +https://home-assistant.io/components/zeroconf/ +""" +import logging +import socket + +from homeassistant.const import ( + EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, __version__) + +import homeassistant.util as util + +REQUIREMENTS = ["zeroconf==0.17.5"] + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = "zeroconf" + +ZEROCONF_TYPE = "_home-assistant._tcp.local." + +DEPENDENCIES = ["http", "api"] + +def setup(hass, config): + + from zeroconf import Zeroconf, ServiceInfo + + zeroconf = Zeroconf() + + zeroconf_name = "{}.{}".format(hass.config.location_name, + ZEROCONF_TYPE) + + params = {"version": __version__, "base_url": hass.http.base_url, + "has_password": (hass.http.api_password != "")} + + info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, + socket.inet_aton(util.get_local_ip()), + hass.http.server_address[1], 0, 0, params) + + zeroconf.register_service(info) + + def stop_zeroconf(event): + """Stop Zeroconf.""" + zeroconf.unregister_all_services() + + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) + + return True diff --git a/requirements_all.txt b/requirements_all.txt index 56829f67f97..720c49a47c8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -314,5 +314,5 @@ xbee-helper==0.0.6 # homeassistant.components.sensor.yr xmltodict -# homeassistant.components.http +# homeassistant.components.zeroconf zeroconf==0.17.5 From beac69ad175fd730d8d7054fedd1a6c45c4f34ff Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 16:02:07 -0700 Subject: [PATCH 04/10] Final clean up, flake8, pylint, change a variable name, remove unnecessary imports --- homeassistant/components/http.py | 9 ++++-- homeassistant/components/zeroconf.py | 45 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index 03d18170b3b..bacdf5b15a0 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -7,7 +7,6 @@ https://home-assistant.io/developers/api/ import gzip import json import logging -import socket import ssl import threading import time @@ -28,7 +27,7 @@ from homeassistant.const import ( HTTP_HEADER_CONTENT_LENGTH, HTTP_HEADER_CONTENT_TYPE, HTTP_HEADER_EXPIRES, HTTP_HEADER_HA_AUTH, HTTP_HEADER_VARY, HTTP_METHOD_NOT_ALLOWED, HTTP_NOT_FOUND, HTTP_OK, HTTP_UNAUTHORIZED, HTTP_UNPROCESSABLE_ENTITY, - SERVER_PORT, __version__) + SERVER_PORT) DOMAIN = "http" @@ -105,8 +104,12 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): self.paths = [] self.sessions = SessionStore() self.protocol = 'https' if ssl_certificate is not None else 'http' + if server_address[0] == '0.0.0.0': + self.routable_address = util.get_local_ip() + else: + self.routable_address = server_address[0] self.base_url = "{}://{}:{}".format(self.protocol, - util.get_local_ip(), + self.routable_address, self.server_address[1]) # We will lazy init this one if needed diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py index a9e773fae6d..cd472734f86 100644 --- a/homeassistant/components/zeroconf.py +++ b/homeassistant/components/zeroconf.py @@ -1,6 +1,7 @@ """ -This module exposes Home Assistant via Zeroconf, also sometimes known as -Bonjour, Rendezvous, Avahi or Multicast DNS (mDNS). +This module exposes Home Assistant via Zeroconf. + +Zeroconf is also known as Bonjour, Avahi or Multicast DNS (mDNS). For more details about Zeroconf, please refer to the documentation at https://home-assistant.io/components/zeroconf/ @@ -8,10 +9,7 @@ https://home-assistant.io/components/zeroconf/ import logging import socket -from homeassistant.const import ( - EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, __version__) - -import homeassistant.util as util +from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, __version__) REQUIREMENTS = ["zeroconf==0.17.5"] @@ -21,30 +19,31 @@ DOMAIN = "zeroconf" ZEROCONF_TYPE = "_home-assistant._tcp.local." -DEPENDENCIES = ["http", "api"] +DEPENDENCIES = ["http"] + def setup(hass, config): + """Set up Zeroconf and make Home Assistant discoverable.""" + from zeroconf import Zeroconf, ServiceInfo - from zeroconf import Zeroconf, ServiceInfo + zeroconf = Zeroconf() - zeroconf = Zeroconf() + zeroconf_name = "{}.{}".format(hass.config.location_name, + ZEROCONF_TYPE) - zeroconf_name = "{}.{}".format(hass.config.location_name, - ZEROCONF_TYPE) + params = {"version": __version__, "base_url": hass.http.base_url, + "needs_auth": (hass.http.api_password != "")} - params = {"version": __version__, "base_url": hass.http.base_url, - "has_password": (hass.http.api_password != "")} + info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, + socket.inet_aton(hass.http.routable_address), + hass.http.server_address[1], 0, 0, params) - info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, - socket.inet_aton(util.get_local_ip()), - hass.http.server_address[1], 0, 0, params) + zeroconf.register_service(info) - zeroconf.register_service(info) + def stop_zeroconf(event): + """Stop Zeroconf.""" + zeroconf.unregister_service(info) - def stop_zeroconf(event): - """Stop Zeroconf.""" - zeroconf.unregister_all_services() + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) - hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) - - return True + return True From e70338dfe14e54179757e2b225b417b717d4c4c0 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 16:03:40 -0700 Subject: [PATCH 05/10] Block zeroconf from tests --- .coveragerc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.coveragerc b/.coveragerc index 2f6e7a9adf8..9e54fdccecc 100644 --- a/.coveragerc +++ b/.coveragerc @@ -65,6 +65,8 @@ omit = homeassistant/components/scsgate.py homeassistant/components/*/scsgate.py + homeassistant/components/zeroconf.py + homeassistant/components/binary_sensor/arest.py homeassistant/components/binary_sensor/rest.py homeassistant/components/browser.py From 085d90ed6758a81de05dc96769b0b489befe2c5e Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 16:08:00 -0700 Subject: [PATCH 06/10] Revert all http.py changes --- homeassistant/components/http.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/http.py b/homeassistant/components/http.py index bacdf5b15a0..00b35dda8c9 100644 --- a/homeassistant/components/http.py +++ b/homeassistant/components/http.py @@ -103,14 +103,7 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): self.development = development self.paths = [] self.sessions = SessionStore() - self.protocol = 'https' if ssl_certificate is not None else 'http' - if server_address[0] == '0.0.0.0': - self.routable_address = util.get_local_ip() - else: - self.routable_address = server_address[0] - self.base_url = "{}://{}:{}".format(self.protocol, - self.routable_address, - self.server_address[1]) + self.use_ssl = ssl_certificate is not None # We will lazy init this one if needed self.event_forwarder = None @@ -132,7 +125,11 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): self.hass.bus.listen_once(ha.EVENT_HOMEASSISTANT_STOP, stop_http) - _LOGGER.info("Starting web interface at %s", self.base_url) + protocol = 'https' if self.use_ssl else 'http' + + _LOGGER.info( + "Starting web interface at %s://%s:%d", + protocol, self.server_address[0], self.server_address[1]) # 31-1-2015: Refactored frontend/api components out of this component # To prevent stuff from breaking, load the two extracted components From e1ffdcc5f12be623633e2abab2041fcb574173ea Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 16:09:52 -0700 Subject: [PATCH 07/10] Use hass.config.api instead of hass.http --- homeassistant/components/zeroconf.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py index cd472734f86..4c5c21f08dd 100644 --- a/homeassistant/components/zeroconf.py +++ b/homeassistant/components/zeroconf.py @@ -13,14 +13,14 @@ from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, __version__) REQUIREMENTS = ["zeroconf==0.17.5"] +DEPENDENCIES = ["api"] + _LOGGER = logging.getLogger(__name__) DOMAIN = "zeroconf" ZEROCONF_TYPE = "_home-assistant._tcp.local." -DEPENDENCIES = ["http"] - def setup(hass, config): """Set up Zeroconf and make Home Assistant discoverable.""" @@ -31,12 +31,12 @@ def setup(hass, config): zeroconf_name = "{}.{}".format(hass.config.location_name, ZEROCONF_TYPE) - params = {"version": __version__, "base_url": hass.http.base_url, - "needs_auth": (hass.http.api_password != "")} + params = {"version": __version__, "base_url": hass.config.api.base_url, + "needs_auth": (hass.config.api.api_password != "")} info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, - socket.inet_aton(hass.http.routable_address), - hass.http.server_address[1], 0, 0, params) + socket.inet_aton(hass.config.api.host), + hass.config.api.port, 0, 0, params) zeroconf.register_service(info) From 1de45ebe8bbc30b7203123630ba4a23ef7f419bf Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 17:59:21 -0700 Subject: [PATCH 08/10] Fix api_password conditional and close zeroconf when we shut down --- homeassistant/components/zeroconf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/zeroconf.py b/homeassistant/components/zeroconf.py index 4c5c21f08dd..bda6dcb153b 100644 --- a/homeassistant/components/zeroconf.py +++ b/homeassistant/components/zeroconf.py @@ -32,7 +32,7 @@ def setup(hass, config): ZEROCONF_TYPE) params = {"version": __version__, "base_url": hass.config.api.base_url, - "needs_auth": (hass.config.api.api_password != "")} + "needs_auth": (hass.config.api.api_password is not None)} info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, socket.inet_aton(hass.config.api.host), @@ -43,6 +43,7 @@ def setup(hass, config): def stop_zeroconf(event): """Stop Zeroconf.""" zeroconf.unregister_service(info) + zeroconf.close() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) From eca1631f1bed5f23d9c6ed471015c32319c99e5d Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 18:05:30 -0700 Subject: [PATCH 09/10] Update netdisco dependency to 0.6.3 --- homeassistant/components/discovery.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index f03fdf35929..6f301e549d1 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -15,7 +15,7 @@ from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED) DOMAIN = "discovery" -REQUIREMENTS = ['netdisco==0.6.2'] +REQUIREMENTS = ['netdisco==0.6.3'] SCAN_INTERVAL = 300 # seconds diff --git a/requirements_all.txt b/requirements_all.txt index 7a1e619780c..5fb0646b426 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -132,7 +132,7 @@ messagebird==1.1.1 mficlient==0.3.0 # homeassistant.components.discovery -netdisco==0.6.2 +netdisco==0.6.3 # homeassistant.components.sensor.neurio_energy neurio==0.2.10 From a3959d5e01112e486f4db84fe073df91e6e38ba3 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Sun, 10 Apr 2016 18:10:31 -0700 Subject: [PATCH 10/10] Update netdisco dependency to 0.6.4 (deja vu all over again!) --- homeassistant/components/discovery.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index 6f301e549d1..900d826e61a 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -15,7 +15,7 @@ from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED) DOMAIN = "discovery" -REQUIREMENTS = ['netdisco==0.6.3'] +REQUIREMENTS = ['netdisco==0.6.4'] SCAN_INTERVAL = 300 # seconds diff --git a/requirements_all.txt b/requirements_all.txt index 5fb0646b426..c9035936fc2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -132,7 +132,7 @@ messagebird==1.1.1 mficlient==0.3.0 # homeassistant.components.discovery -netdisco==0.6.3 +netdisco==0.6.4 # homeassistant.components.sensor.neurio_energy neurio==0.2.10