Merge pull request #2281 from home-assistant/0-21-1

Hotfix 0.21.1
This commit is contained in:
Paulus Schoutsen 2016-06-12 00:23:03 -07:00 committed by GitHub
commit 952afeb717
20 changed files with 72 additions and 264 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 232 KiB

View File

@ -96,6 +96,9 @@ class AlexaView(HomeAssistantView):
card = config.get(CONF_CARD) card = config.get(CONF_CARD)
action = config.get(CONF_ACTION) action = config.get(CONF_ACTION)
if action is not None:
action.run(response.variables)
# pylint: disable=unsubscriptable-object # pylint: disable=unsubscriptable-object
if speech is not None: if speech is not None:
response.add_speech(SpeechType[speech['type']], speech['text']) response.add_speech(SpeechType[speech['type']], speech['text'])
@ -104,9 +107,6 @@ class AlexaView(HomeAssistantView):
response.add_card(CardType[card['type']], card['title'], response.add_card(CardType[card['type']], card['title'],
card['content']) card['content'])
if action is not None:
action.run(response.variables)
return self.json(response) return self.json(response)

View File

@ -89,8 +89,6 @@ class Camera(Entity):
def mjpeg_stream(self, response): def mjpeg_stream(self, response):
"""Generate an HTTP MJPEG stream from camera images.""" """Generate an HTTP MJPEG stream from camera images."""
import eventlet import eventlet
response.content_type = ('multipart/x-mixed-replace; '
'boundary=--jpegboundary')
def stream(): def stream():
"""Stream images as mjpeg stream.""" """Stream images as mjpeg stream."""
@ -112,9 +110,11 @@ class Camera(Entity):
except GeneratorExit: except GeneratorExit:
pass pass
response.response = stream() return response(
stream(),
return response content_type=('multipart/x-mixed-replace; '
'boundary=--jpegboundary')
)
@property @property
def state(self): def state(self):
@ -196,4 +196,4 @@ class CameraMjpegStream(CameraView):
def handle(self, camera): def handle(self, camera):
"""Serve camera image.""" """Serve camera image."""
return camera.mjpeg_stream(self.Response()) return camera.mjpeg_stream(self.Response)

View File

@ -70,9 +70,11 @@ class MjpegCamera(Camera):
def mjpeg_stream(self, response): def mjpeg_stream(self, response):
"""Generate an HTTP MJPEG stream from the camera.""" """Generate an HTTP MJPEG stream from the camera."""
stream = self.camera_stream() stream = self.camera_stream()
response.mimetype = stream.headers[CONTENT_TYPE_HEADER] return response(
response.response = stream.iter_content(chunk_size=1024) stream.iter_content(chunk_size=1024),
return response mimetype=stream.headers[CONTENT_TYPE_HEADER],
direct_passthrough=True
)
@property @property
def name(self): def name(self):

View File

@ -1,3 +1,3 @@
"""DO NOT MODIFY. Auto-generated by build_frontend script.""" """DO NOT MODIFY. Auto-generated by build_frontend script."""
CORE = "d0b415dac66c8056d81380b258af5767" CORE = "88b6966e3a74256ecca41ed8ad005c34"
UI = "b0ea2672fff86b1ab86dd86135d4b43a" UI = "c6fc10efa7789ab041a1bb0b6849eb6b"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 612a876199d8ecdc778182ea93fff034a4d15ef4 Subproject commit f0466f42e59f620b82161ecf9e5dfab2bcebcd98

View File

@ -29,7 +29,7 @@
/* eslint-disable quotes, comma-spacing */ /* eslint-disable quotes, comma-spacing */
var PrecacheConfig = [["/","69818e2c5b6f4ca764c46ac78d2fea04"],["/devEvent","69818e2c5b6f4ca764c46ac78d2fea04"],["/devInfo","69818e2c5b6f4ca764c46ac78d2fea04"],["/devService","69818e2c5b6f4ca764c46ac78d2fea04"],["/devState","69818e2c5b6f4ca764c46ac78d2fea04"],["/devTemplate","69818e2c5b6f4ca764c46ac78d2fea04"],["/history","69818e2c5b6f4ca764c46ac78d2fea04"],["/logbook","69818e2c5b6f4ca764c46ac78d2fea04"],["/map","69818e2c5b6f4ca764c46ac78d2fea04"],["/states","69818e2c5b6f4ca764c46ac78d2fea04"],["/static/core-d0b415dac66c8056d81380b258af5767.js","dfafa8e9e34f53e8c36dd8b3f7299b2a"],["/static/frontend-b0ea2672fff86b1ab86dd86135d4b43a.html","69818e2c5b6f4ca764c46ac78d2fea04"],["/static/mdi-9ee3d4466a65bef35c2c8974e91b37c0.html","9a6846935116cd29279c91e0ee0a26d0"],["static/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"],["static/webcomponents-lite.min.js","b0f32ad3c7749c40d486603f31c9d8b1"]]; var PrecacheConfig = [["/","5113b71ee83242d02b525f3331a5d8cc"],["/devEvent","5113b71ee83242d02b525f3331a5d8cc"],["/devInfo","5113b71ee83242d02b525f3331a5d8cc"],["/devService","5113b71ee83242d02b525f3331a5d8cc"],["/devState","5113b71ee83242d02b525f3331a5d8cc"],["/devTemplate","5113b71ee83242d02b525f3331a5d8cc"],["/history","5113b71ee83242d02b525f3331a5d8cc"],["/logbook","5113b71ee83242d02b525f3331a5d8cc"],["/map","5113b71ee83242d02b525f3331a5d8cc"],["/states","5113b71ee83242d02b525f3331a5d8cc"],["/static/core-88b6966e3a74256ecca41ed8ad005c34.js","dec9792a59ab21903b7dda457784db98"],["/static/frontend-c6fc10efa7789ab041a1bb0b6849eb6b.html","5113b71ee83242d02b525f3331a5d8cc"],["/static/mdi-9ee3d4466a65bef35c2c8974e91b37c0.html","9a6846935116cd29279c91e0ee0a26d0"],["static/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"],["static/webcomponents-lite.min.js","b0f32ad3c7749c40d486603f31c9d8b1"]];
/* eslint-enable quotes, comma-spacing */ /* eslint-enable quotes, comma-spacing */
var CacheNamePrefix = 'sw-precache-v1--' + (self.registration ? self.registration.scope : '') + '-'; var CacheNamePrefix = 'sw-precache-v1--' + (self.registration ? self.registration.scope : '') + '-';

View File

@ -66,7 +66,12 @@ class LircInterface(threading.Thread):
"""Main loop of LIRC interface thread.""" """Main loop of LIRC interface thread."""
import lirc import lirc
while not self.stopped.isSet(): while not self.stopped.isSet():
try:
code = lirc.nextcode() # list; empty if no buttons pressed code = lirc.nextcode() # list; empty if no buttons pressed
except lirc.NextCodeError:
_LOGGER.warning('Encountered error reading '
'next code from LIRC')
code = None
# interpret result from python-lirc # interpret result from python-lirc
if code: if code:
code = code[0] code = code[0]

View File

@ -68,6 +68,7 @@ def get_next_departure(sched, start_station_id, end_station_id):
AND time(origin_stop_time.departure_time) > time(:now_str) AND time(origin_stop_time.departure_time) > time(:now_str)
AND start_station.stop_id = :origin_station_id AND start_station.stop_id = :origin_station_id
AND end_station.stop_id = :end_station_id AND end_station.stop_id = :end_station_id
AND origin_stop_time.stop_sequence < destination_stop_time.stop_sequence
ORDER BY origin_stop_time.departure_time LIMIT 1; ORDER BY origin_stop_time.departure_time LIMIT 1;
""".format(day_name=day_name)) """.format(day_name=day_name))
result = sched.engine.execute(sql_query, now_str=now_str, result = sched.engine.execute(sql_query, now_str=now_str,

View File

@ -214,12 +214,6 @@ def setup(hass, config):
config_path=config[DOMAIN].get('config_path', config_path=config[DOMAIN].get('config_path',
default_zwave_config_path),) default_zwave_config_path),)
# Setup autoheal
if autoheal:
_LOGGER.info("ZWave network autoheal is enabled.")
track_time_change(hass, lambda: heal_network(None),
hour=0, minute=0, second=0)
options.set_console_output(use_debug) options.set_console_output(use_debug)
options.lock() options.lock()
@ -291,24 +285,24 @@ def setup(hass, config):
dispatcher.connect( dispatcher.connect(
scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False) scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
def add_node(event): def add_node(service):
"""Switch into inclusion mode.""" """Switch into inclusion mode."""
NETWORK.controller.begin_command_add_device() NETWORK.controller.begin_command_add_device()
def remove_node(event): def remove_node(service):
"""Switch into exclusion mode.""" """Switch into exclusion mode."""
NETWORK.controller.begin_command_remove_device() NETWORK.controller.begin_command_remove_device()
def heal_network(event): def heal_network(service):
"""Heal the network.""" """Heal the network."""
_LOGGER.info("ZWave heal running.") _LOGGER.info("ZWave heal running.")
NETWORK.heal() NETWORK.heal()
def soft_reset(event): def soft_reset(service):
"""Soft reset the controller.""" """Soft reset the controller."""
NETWORK.controller.soft_reset() NETWORK.controller.soft_reset()
def test_network(event): def test_network(service):
"""Test the network by sending commands to all the nodes.""" """Test the network by sending commands to all the nodes."""
NETWORK.test() NETWORK.test()
@ -324,7 +318,7 @@ def setup(hass, config):
# Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
# to be ready. # to be ready.
for i in range(NETWORK_READY_WAIT_SECS): for i in range(NETWORK_READY_WAIT_SECS):
_LOGGER.info( _LOGGER.debug(
"network state: %d %s", NETWORK.state, NETWORK.state_str) "network state: %d %s", NETWORK.state, NETWORK.state_str)
if NETWORK.state >= NETWORK.STATE_AWAKED: if NETWORK.state >= NETWORK.STATE_AWAKED:
_LOGGER.info("zwave ready after %d seconds", i) _LOGGER.info("zwave ready after %d seconds", i)
@ -355,6 +349,11 @@ def setup(hass, config):
hass.services.register(DOMAIN, SERVICE_SOFT_RESET, soft_reset) hass.services.register(DOMAIN, SERVICE_SOFT_RESET, soft_reset)
hass.services.register(DOMAIN, SERVICE_TEST_NETWORK, test_network) hass.services.register(DOMAIN, SERVICE_TEST_NETWORK, test_network)
# Setup autoheal
if autoheal:
_LOGGER.info("ZWave network autoheal is enabled.")
track_time_change(hass, heal_network, hour=0, minute=0, second=0)
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)
return True return True

View File

@ -1,7 +1,7 @@
# coding: utf-8 # coding: utf-8
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
__version__ = "0.21.0" __version__ = "0.21.1"
REQUIRED_PYTHON_VER = (3, 4) REQUIRED_PYTHON_VER = (3, 4)
PLATFORM_FORMAT = '{}.{}' PLATFORM_FORMAT = '{}.{}'

View File

@ -40,7 +40,11 @@ def config_per_platform(config, domain):
platform_config = [platform_config] platform_config = [platform_config]
for item in platform_config: for item in platform_config:
platform = None if item is None else item.get(CONF_PLATFORM) try:
platform = item.get(CONF_PLATFORM)
except AttributeError:
platform = None
yield platform, item yield platform, item

View File

@ -6,6 +6,7 @@ pip>=7.0.0
jinja2>=2.8 jinja2>=2.8
voluptuous==0.8.9 voluptuous==0.8.9
webcolors==1.5 webcolors==1.5
eventlet==0.19.0
# homeassistant.components.isy994 # homeassistant.components.isy994
PyISY==1.0.6 PyISY==1.0.6

View File

@ -18,6 +18,7 @@ REQUIRES = [
'jinja2>=2.8', 'jinja2>=2.8',
'voluptuous==0.8.9', 'voluptuous==0.8.9',
'webcolors==1.5', 'webcolors==1.5',
'eventlet==0.19.0',
] ]
setup( setup(

View File

@ -1,5 +1,6 @@
"""Test component helpers.""" """Test component helpers."""
# pylint: disable=protected-access,too-many-public-methods # pylint: disable=protected-access,too-many-public-methods
from collections import OrderedDict
import unittest import unittest
from homeassistant import helpers from homeassistant import helpers
@ -30,3 +31,19 @@ class TestHelpers(unittest.TestCase):
self.assertEqual(set(['zone', 'zone Hallo', 'zone 100']), self.assertEqual(set(['zone', 'zone Hallo', 'zone 100']),
set(helpers.extract_domain_configs(config, 'zone'))) set(helpers.extract_domain_configs(config, 'zone')))
def test_config_per_platform(self):
"""Test config per platform method."""
config = OrderedDict([
('zone', {'platform': 'hello'}),
('zoner', None),
('zone Hallo', [1, {'platform': 'hello 2'}]),
('zone 100', None),
])
assert [
('hello', config['zone']),
(None, 1),
('hello 2', config['zone Hallo'][1]),
(None, None)
] == list(helpers.config_per_platform(config, 'zone'))