diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py
index 7ccc1f745e9..1e6e66baee0 100644
--- a/homeassistant/components/api.py
+++ b/homeassistant/components/api.py
@@ -18,10 +18,10 @@ from homeassistant.bootstrap import ERROR_LOG_FILENAME
from homeassistant.const import (
URL_API, URL_API_STATES, URL_API_EVENTS, URL_API_SERVICES, URL_API_STREAM,
URL_API_EVENT_FORWARD, URL_API_STATES_ENTITY, URL_API_COMPONENTS,
- URL_API_CONFIG, URL_API_BOOTSTRAP, URL_API_ERROR_LOG,
+ URL_API_CONFIG, URL_API_BOOTSTRAP, URL_API_ERROR_LOG, URL_API_LOG_OUT,
EVENT_TIME_CHANGED, EVENT_HOMEASSISTANT_STOP, MATCH_ALL,
HTTP_OK, HTTP_CREATED, HTTP_BAD_REQUEST, HTTP_NOT_FOUND,
- HTTP_UNPROCESSABLE_ENTITY, CONTENT_TYPE_TEXT_PLAIN)
+ HTTP_UNPROCESSABLE_ENTITY)
DOMAIN = 'api'
@@ -36,10 +36,6 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config):
""" Register the API with the HTTP interface. """
- if 'http' not in hass.config.components:
- _LOGGER.error('Dependency http is not loaded')
- return False
-
# /api - for validation purposes
hass.http.register_path('GET', URL_API, _handle_get_api)
@@ -93,6 +89,8 @@ def setup(hass, config):
hass.http.register_path('GET', URL_API_ERROR_LOG,
_handle_get_api_error_log)
+ hass.http.register_path('POST', URL_API_LOG_OUT, _handle_post_api_log_out)
+
return True
@@ -108,6 +106,7 @@ def _handle_get_api_stream(handler, path_match, data):
wfile = handler.wfile
write_lock = threading.Lock()
block = threading.Event()
+ session_id = None
restrict = data.get('restrict')
if restrict:
@@ -121,6 +120,7 @@ def _handle_get_api_stream(handler, path_match, data):
try:
wfile.write(msg.encode("UTF-8"))
wfile.flush()
+ handler.server.sessions.extend_validation(session_id)
except IOError:
block.set()
@@ -140,6 +140,7 @@ def _handle_get_api_stream(handler, path_match, data):
handler.send_response(HTTP_OK)
handler.send_header('Content-type', 'text/event-stream')
+ session_id = handler.set_session_cookie_header()
handler.end_headers()
hass.bus.listen(MATCH_ALL, forward_events)
@@ -347,9 +348,15 @@ def _handle_get_api_components(handler, path_match, data):
def _handle_get_api_error_log(handler, path_match, data):
""" Returns the logged errors for this session. """
- error_path = handler.server.hass.config.path(ERROR_LOG_FILENAME)
- with open(error_path, 'rb') as error_log:
- handler.write_file_pointer(CONTENT_TYPE_TEXT_PLAIN, error_log)
+ handler.write_file(handler.server.hass.config.path(ERROR_LOG_FILENAME),
+ False)
+
+
+def _handle_post_api_log_out(handler, path_match, data):
+ """ Log user out. """
+ handler.send_response(HTTP_OK)
+ handler.destroy_session()
+ handler.end_headers()
def _services_json(hass):
diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py
index ae5fe28beac..169c97595af 100644
--- a/homeassistant/components/camera/__init__.py
+++ b/homeassistant/components/camera/__init__.py
@@ -80,19 +80,21 @@ def setup(hass, config):
def _proxy_camera_image(handler, path_match, data):
""" Proxies the camera image via the HA server. """
entity_id = path_match.group(ATTR_ENTITY_ID)
+ camera = component.entities.get(entity_id)
- camera = None
- if entity_id in component.entities.keys():
- camera = component.entities[entity_id]
-
- if camera:
- response = camera.camera_image()
- if response is not None:
- handler.wfile.write(response)
- else:
- handler.send_response(HTTP_NOT_FOUND)
- else:
+ if camera is None:
handler.send_response(HTTP_NOT_FOUND)
+ handler.end_headers()
+ return
+
+ response = camera.camera_image()
+
+ if response is None:
+ handler.send_response(HTTP_NOT_FOUND)
+ handler.end_headers()
+ return
+
+ handler.wfile.write(response)
hass.http.register_path(
'GET',
@@ -108,12 +110,9 @@ def setup(hass, config):
stream even with only a still image URL available.
"""
entity_id = path_match.group(ATTR_ENTITY_ID)
+ camera = component.entities.get(entity_id)
- camera = None
- if entity_id in component.entities.keys():
- camera = component.entities[entity_id]
-
- if not camera:
+ if camera is None:
handler.send_response(HTTP_NOT_FOUND)
handler.end_headers()
return
@@ -131,7 +130,6 @@ def setup(hass, config):
# MJPEG_START_HEADER.format()
while True:
-
img_bytes = camera.camera_image()
if img_bytes is None:
continue
@@ -148,12 +146,12 @@ def setup(hass, config):
handler.request.sendall(
bytes('--jpgboundary\r\n', 'utf-8'))
+ time.sleep(0.5)
+
except (requests.RequestException, IOError):
camera.is_streaming = False
camera.update_ha_state()
- camera.is_streaming = False
-
hass.http.register_path(
'GET',
re.compile(
diff --git a/homeassistant/components/camera/demo.py b/homeassistant/components/camera/demo.py
index fc3ec263143..0ad992db86d 100644
--- a/homeassistant/components/camera/demo.py
+++ b/homeassistant/components/camera/demo.py
@@ -4,8 +4,8 @@ homeassistant.components.camera.demo
Demo platform that has a fake camera.
"""
import os
-from random import randint
from homeassistant.components.camera import Camera
+import homeassistant.util.dt as dt_util
def setup_platform(hass, config, add_devices, discovery_info=None):
@@ -24,12 +24,12 @@ class DemoCamera(Camera):
def camera_image(self):
""" Return a faked still image response. """
+ now = dt_util.utcnow()
image_path = os.path.join(os.path.dirname(__file__),
- 'demo_{}.png'.format(randint(1, 5)))
+ 'demo_{}.jpg'.format(now.second % 4))
with open(image_path, 'rb') as file:
- output = file.read()
- return output
+ return file.read()
@property
def name(self):
diff --git a/homeassistant/components/camera/demo_0.jpg b/homeassistant/components/camera/demo_0.jpg
new file mode 100644
index 00000000000..ff87d5179f8
Binary files /dev/null and b/homeassistant/components/camera/demo_0.jpg differ
diff --git a/homeassistant/components/camera/demo_1.jpg b/homeassistant/components/camera/demo_1.jpg
new file mode 100644
index 00000000000..06166fffa85
Binary files /dev/null and b/homeassistant/components/camera/demo_1.jpg differ
diff --git a/homeassistant/components/camera/demo_1.png b/homeassistant/components/camera/demo_1.png
deleted file mode 100644
index fc681fccecd..00000000000
Binary files a/homeassistant/components/camera/demo_1.png and /dev/null differ
diff --git a/homeassistant/components/camera/demo_2.jpg b/homeassistant/components/camera/demo_2.jpg
new file mode 100644
index 00000000000..71356479ab0
Binary files /dev/null and b/homeassistant/components/camera/demo_2.jpg differ
diff --git a/homeassistant/components/camera/demo_2.png b/homeassistant/components/camera/demo_2.png
deleted file mode 100644
index 255cd5c45d4..00000000000
Binary files a/homeassistant/components/camera/demo_2.png and /dev/null differ
diff --git a/homeassistant/components/camera/demo_3.jpg b/homeassistant/components/camera/demo_3.jpg
new file mode 100644
index 00000000000..06166fffa85
Binary files /dev/null and b/homeassistant/components/camera/demo_3.jpg differ
diff --git a/homeassistant/components/camera/demo_3.png b/homeassistant/components/camera/demo_3.png
deleted file mode 100644
index b54c1ffb57c..00000000000
Binary files a/homeassistant/components/camera/demo_3.png and /dev/null differ
diff --git a/homeassistant/components/camera/demo_4.png b/homeassistant/components/camera/demo_4.png
deleted file mode 100644
index 4be36ee42d0..00000000000
Binary files a/homeassistant/components/camera/demo_4.png and /dev/null differ
diff --git a/homeassistant/components/camera/demo_5.png b/homeassistant/components/camera/demo_5.png
deleted file mode 100644
index 874b95ef6a5..00000000000
Binary files a/homeassistant/components/camera/demo_5.png and /dev/null differ
diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py
index 5a8fbed34e9..dac2041fa56 100644
--- a/homeassistant/components/frontend/__init__.py
+++ b/homeassistant/components/frontend/__init__.py
@@ -54,8 +54,7 @@ def setup(hass, config):
def _handle_get_root(handler, path_match, data):
- """ Renders the debug interface. """
-
+ """ Renders the frontend. """
handler.send_response(HTTP_OK)
handler.send_header('Content-type', 'text/html; charset=utf-8')
handler.end_headers()
@@ -66,7 +65,7 @@ def _handle_get_root(handler, path_match, data):
app_url = "frontend-{}.html".format(version.VERSION)
# auto login if no password was set, else check api_password param
- auth = ('no_password_set' if handler.server.no_password_set
+ auth = ('no_password_set' if handler.server.api_password is None
else data.get('api_password', ''))
with open(INDEX_PATH) as template_file:
diff --git a/homeassistant/components/frontend/index.html.template b/homeassistant/components/frontend/index.html.template
index 409ea6752db..87c5f6638a7 100644
--- a/homeassistant/components/frontend/index.html.template
+++ b/homeassistant/components/frontend/index.html.template
@@ -4,16 +4,13 @@
Home Assistant
-
-
-
+
+
+ href='/static/favicon-apple-180x180.png'>
-
+
-
-

-
Initializing
-
+
diff --git a/homeassistant/components/frontend/version.py b/homeassistant/components/frontend/version.py
index ed954909e66..04ccb720f6b 100644
--- a/homeassistant/components/frontend/version.py
+++ b/homeassistant/components/frontend/version.py
@@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
-VERSION = "c90d40a0240cc1feec791ee820d928b3"
+VERSION = "36df87bb6c219a2ee59adf416e3abdfa"
diff --git a/homeassistant/components/frontend/www_static/favicon-384x384.png b/homeassistant/components/frontend/www_static/favicon-384x384.png
new file mode 100644
index 00000000000..51f67770790
Binary files /dev/null and b/homeassistant/components/frontend/www_static/favicon-384x384.png differ
diff --git a/homeassistant/components/frontend/www_static/frontend.html b/homeassistant/components/frontend/www_static/frontend.html
index 73b2ac1b7dd..e600c4c5583 100644
--- a/homeassistant/components/frontend/www_static/frontend.html
+++ b/homeassistant/components/frontend/www_static/frontend.html
@@ -1,6 +1,6 @@
-
To install Home Assistant, run:
pip3 install homeassistant
hass --open-ui
Here are some resources to get started.
To remove this card, edit your config in configuration.yaml
and disable the introduction
component. To install Home Assistant, run:
pip3 install homeassistant
hass --open-ui
Here are some resources to get started.
To remove this card, edit your config in configuration.yaml
and disable the introduction
component.
[[errorMessage]]AboutThe following errors have been logged this session:
[[errorLog]]
AboutThe following errors have been logged this session:
[[errorLog]]
[[_text]]
{{text}}[[_text]]
{{text}}
[[attribute]]
[[getAttributeValue(stateObj, attribute)]]
\ No newline at end of file
+ }