Merge pull request #17895 from home-assistant/rc

0.81.1
This commit is contained in:
Paulus Schoutsen 2018-10-28 08:37:44 +01:00 committed by GitHub
commit b6a799499a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 52 deletions

View File

@ -31,7 +31,7 @@ SERVICE_RELOAD_CORE_CONFIG = 'reload_core_config'
SERVICE_CHECK_CONFIG = 'check_config'
SERVICE_UPDATE_ENTITY = 'update_entity'
SCHEMA_UPDATE_ENTITY = vol.Schema({
ATTR_ENTITY_ID: cv.entity_id
ATTR_ENTITY_ID: cv.entity_ids
})
@ -142,8 +142,11 @@ async def async_setup(hass: ha.HomeAssistant, config: dict) -> Awaitable[bool]:
async def async_handle_update_service(call):
"""Service handler for updating an entity."""
await hass.helpers.entity_component.async_update_entity(
call.data[ATTR_ENTITY_ID])
tasks = [hass.helpers.entity_component.async_update_entity(entity)
for entity in call.data[ATTR_ENTITY_ID]]
if tasks:
await asyncio.wait(tasks)
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP, async_handle_core_service)

View File

@ -24,7 +24,7 @@ from homeassistant.core import callback
from homeassistant.helpers.translation import async_get_translations
from homeassistant.loader import bind_hass
REQUIREMENTS = ['home-assistant-frontend==20181026.0']
REQUIREMENTS = ['home-assistant-frontend==20181026.1']
DOMAIN = 'frontend'
DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log',

View File

@ -24,6 +24,7 @@ FORMAT_JSON = 'json'
OLD_WS_TYPE_GET_LOVELACE_UI = 'frontend/lovelace_config'
WS_TYPE_GET_LOVELACE_UI = 'lovelace/config'
WS_TYPE_MIGRATE_CONFIG = 'lovelace/config/migrate'
WS_TYPE_GET_CARD = 'lovelace/config/card/get'
WS_TYPE_UPDATE_CARD = 'lovelace/config/card/update'
WS_TYPE_ADD_CARD = 'lovelace/config/card/add'
@ -33,6 +34,10 @@ SCHEMA_GET_LOVELACE_UI = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
OLD_WS_TYPE_GET_LOVELACE_UI),
})
SCHEMA_MIGRATE_CONFIG = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_MIGRATE_CONFIG,
})
SCHEMA_GET_CARD = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_GET_CARD,
vol.Required('card_id'): str,
@ -132,6 +137,11 @@ def load_yaml(fname: str) -> JSON_TYPE:
def load_config(fname: str) -> JSON_TYPE:
"""Load a YAML file."""
return load_yaml(fname)
def migrate_config(fname: str) -> JSON_TYPE:
"""Load a YAML file and adds id to views and cards if not present."""
config = load_yaml(fname)
# Check if all views and cards have an id or else add one
@ -243,6 +253,10 @@ async def async_setup(hass, config):
OLD_WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config,
SCHEMA_GET_LOVELACE_UI)
hass.components.websocket_api.async_register_command(
WS_TYPE_MIGRATE_CONFIG, websocket_lovelace_migrate_config,
SCHEMA_MIGRATE_CONFIG)
hass.components.websocket_api.async_register_command(
WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config,
SCHEMA_GET_LOVELACE_UI)
@ -286,6 +300,30 @@ async def websocket_lovelace_config(hass, connection, msg):
connection.send_message(message)
@websocket_api.async_response
async def websocket_lovelace_migrate_config(hass, connection, msg):
"""Migrate lovelace UI config."""
error = None
try:
config = await hass.async_add_executor_job(
migrate_config, hass.config.path(LOVELACE_CONFIG_FILE))
message = websocket_api.result_message(
msg['id'], config
)
except FileNotFoundError:
error = ('file_not_found',
'Could not find ui-lovelace.yaml in your config dir.')
except UnsupportedYamlError as err:
error = 'unsupported_error', str(err)
except HomeAssistantError as err:
error = 'load_error', str(err)
if error is not None:
message = websocket_api.error_message(msg['id'], *error)
connection.send_message(message)
@websocket_api.async_response
async def websocket_lovelace_get_card(hass, connection, msg):
"""Send lovelace card config over websocket config."""

View File

@ -109,26 +109,30 @@ async def async_setup(hass, config):
return True
conf = config[DOMAIN]
latitude = conf.get(CONF_LATITUDE)
longitude = conf.get(CONF_LONGITUDE)
identifier = '{0}, {1}'.format(latitude, longitude)
identifier = '{0}, {1}'.format(
conf.get(CONF_LATITUDE, hass.config.latitude),
conf.get(CONF_LONGITUDE, hass.config.longitude))
if identifier in configured_instances(hass):
return True
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={'source': SOURCE_IMPORT},
data={
data = {
CONF_API_KEY: conf[CONF_API_KEY],
CONF_LATITUDE: latitude,
CONF_LONGITUDE: longitude,
CONF_ELEVATION: conf.get(CONF_ELEVATION),
CONF_BINARY_SENSORS: conf[CONF_BINARY_SENSORS],
CONF_SENSORS: conf[CONF_SENSORS],
CONF_SCAN_INTERVAL: conf[CONF_SCAN_INTERVAL],
}))
}
if CONF_LATITUDE in conf:
data[CONF_LATITUDE] = conf[CONF_LATITUDE]
if CONF_LONGITUDE in conf:
data[CONF_LONGITUDE] = conf[CONF_LONGITUDE]
if CONF_ELEVATION in conf:
data[CONF_ELEVATION] = conf[CONF_ELEVATION]
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={'source': SOURCE_IMPORT}, data=data))
return True
@ -143,10 +147,11 @@ async def async_setup_entry(hass, config_entry):
openuv = OpenUV(
Client(
config_entry.data[CONF_API_KEY],
config_entry.data[CONF_LATITUDE],
config_entry.data[CONF_LONGITUDE],
config_entry.data.get(CONF_LATITUDE, hass.config.latitude),
config_entry.data.get(CONF_LONGITUDE, hass.config.longitude),
websession,
altitude=config_entry.data[CONF_ELEVATION]),
altitude=config_entry.data.get(
CONF_ELEVATION, hass.config.elevation)),
config_entry.data.get(CONF_BINARY_SENSORS, {}).get(
CONF_MONITORED_CONDITIONS, list(BINARY_SENSORS)),
config_entry.data.get(CONF_SENSORS, {}).get(
@ -158,7 +163,8 @@ async def async_setup_entry(hass, config_entry):
raise ConfigEntryNotReady
for component in ('binary_sensor', 'sensor'):
hass.async_create_task(hass.config_entries.async_forward_entry_setup(
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
config_entry, component))
async def refresh(event_time):

View File

@ -17,7 +17,8 @@ def configured_instances(hass):
"""Return a set of configured OpenUV instances."""
return set(
'{0}, {1}'.format(
entry.data[CONF_LATITUDE], entry.data[CONF_LONGITUDE])
entry.data.get(CONF_LATITUDE, hass.config.latitude),
entry.data.get(CONF_LONGITUDE, hass.config.longitude))
for entry in hass.config_entries.async_entries(DOMAIN))
@ -36,12 +37,9 @@ class OpenUvFlowHandler(config_entries.ConfigFlow):
"""Show the form to the user."""
data_schema = vol.Schema({
vol.Required(CONF_API_KEY): str,
vol.Optional(CONF_LATITUDE, default=self.hass.config.latitude):
cv.latitude,
vol.Optional(CONF_LONGITUDE, default=self.hass.config.longitude):
cv.longitude,
vol.Optional(CONF_ELEVATION, default=self.hass.config.elevation):
vol.Coerce(float),
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_ELEVATION): vol.Coerce(float),
})
return self.async_show_form(
@ -61,11 +59,9 @@ class OpenUvFlowHandler(config_entries.ConfigFlow):
if not user_input:
return await self._show_form()
latitude = user_input[CONF_LATITUDE]
longitude = user_input[CONF_LONGITUDE]
elevation = user_input[CONF_ELEVATION]
identifier = '{0}, {1}'.format(latitude, longitude)
identifier = '{0}, {1}'.format(
user_input.get(CONF_LATITUDE, self.hass.config.latitude),
user_input.get(CONF_LONGITUDE, self.hass.config.longitude))
if identifier in configured_instances(self.hass):
return await self._show_form({CONF_LATITUDE: 'identifier_exists'})
@ -78,11 +74,6 @@ class OpenUvFlowHandler(config_entries.ConfigFlow):
scan_interval = user_input.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
user_input.update({
CONF_LATITUDE: latitude,
CONF_LONGITUDE: longitude,
CONF_ELEVATION: elevation,
CONF_SCAN_INTERVAL: scan_interval.seconds,
})
user_input[CONF_SCAN_INTERVAL] = scan_interval.seconds
return self.async_create_entry(title=identifier, data=user_input)

View File

@ -527,6 +527,12 @@ homeassistant:
entity_id:
description: The entity_id of the device to turn off.
example: light.living_room
update_entity:
description: Force one or more entities to update its data
fields:
entity_id:
description: One or multiple entity_ids to update. Can be a list.
example: light.living_room
xiaomi_aqara:
play_ringtone:

View File

@ -34,9 +34,9 @@ CONFIG_SCHEMA = vol.Schema({
def setup(hass, config):
"""Set up the Twilio component."""
from twilio.rest import TwilioRestClient
from twilio.rest import Client
conf = config[DOMAIN]
hass.data[DATA_TWILIO] = TwilioRestClient(
hass.data[DATA_TWILIO] = Client(
conf.get(CONF_ACCOUNT_SID), conf.get(CONF_AUTH_TOKEN))
hass.http.register_view(TwilioReceiveDataView())
return True

View File

@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 81
PATCH_VERSION = '0'
PATCH_VERSION = '1'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 5, 3)

View File

@ -466,7 +466,7 @@ hole==0.3.0
holidays==0.9.8
# homeassistant.components.frontend
home-assistant-frontend==20181026.0
home-assistant-frontend==20181026.1
# homeassistant.components.homekit_controller
# homekit==0.10

View File

@ -97,7 +97,7 @@ hdate==0.6.5
holidays==0.9.8
# homeassistant.components.frontend
home-assistant-frontend==20181026.0
home-assistant-frontend==20181026.1
# homeassistant.components.homematicip_cloud
homematicip==0.9.8

View File

@ -8,8 +8,8 @@ from ruamel.yaml import YAML
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
from homeassistant.components.websocket_api.const import TYPE_RESULT
from homeassistant.components.lovelace import (load_yaml,
save_yaml, load_config,
from homeassistant.components.lovelace import (load_yaml, migrate_config,
save_yaml,
UnsupportedYamlError)
TEST_YAML_A = """\
@ -162,7 +162,7 @@ class TestYAML(unittest.TestCase):
with patch('homeassistant.components.lovelace.load_yaml',
return_value=self.yaml.load(TEST_YAML_A)), \
patch('homeassistant.components.lovelace.save_yaml'):
data = load_config(fname)
data = migrate_config(fname)
assert 'id' in data['views'][0]['cards'][0]
assert 'id' in data['views'][1]
@ -171,8 +171,8 @@ class TestYAML(unittest.TestCase):
fname = self._path_for("test7")
with patch('homeassistant.components.lovelace.load_yaml',
return_value=self.yaml.load(TEST_YAML_B)):
data = load_config(fname)
self.assertEqual(data, self.yaml.load(TEST_YAML_B))
data = migrate_config(fname)
assert data == self.yaml.load(TEST_YAML_B)
async def test_deprecated_lovelace_ui(hass, hass_ws_client):

View File

@ -364,7 +364,7 @@ async def test_entity_update(hass):
with patch('homeassistant.helpers.entity_component.async_update_entity',
return_value=mock_coro()) as mock_update:
await hass.services.async_call('homeassistant', 'update_entity', {
'entity_id': 'light.kitchen'
'entity_id': ['light.kitchen']
}, blocking=True)
assert len(mock_update.mock_calls) == 1