Skip to content

Commit

Permalink
Merge pull request #23448 from home-assistant/rc
Browse files Browse the repository at this point in the history
0.92.1
  • Loading branch information
pvizeli committed Apr 26, 2019
2 parents 8ae2ce2 + 081a029 commit ee10775
Show file tree
Hide file tree
Showing 28 changed files with 172 additions and 104 deletions.
2 changes: 1 addition & 1 deletion homeassistant/bootstrap.py
Expand Up @@ -355,7 +355,7 @@ async def _async_set_up_integrations(
if stage_1_domains:
await asyncio.gather(*[
async_setup_component(hass, domain, config)
for domain in logging_domains
for domain in stage_1_domains
])

# Load all integrations
Expand Down
19 changes: 7 additions & 12 deletions homeassistant/components/broadlink/__init__.py
Expand Up @@ -2,7 +2,6 @@
import asyncio
from base64 import b64decode, b64encode
import logging
import re
import socket

from datetime import timedelta
Expand All @@ -19,26 +18,22 @@
DEFAULT_RETRY = 3


def ipv4_address(value):
"""Validate an ipv4 address."""
regex = re.compile(r'^\d+\.\d+\.\d+\.\d+$')
if not regex.match(value):
raise vol.Invalid('Invalid Ipv4 address, expected a.b.c.d')
return value


def data_packet(value):
"""Decode a data packet given for broadlink."""
return b64decode(cv.string(value))
value = cv.string(value)
extra = len(value) % 4
if extra > 0:
value = value + ('=' * (4 - extra))
return b64decode(value)


SERVICE_SEND_SCHEMA = vol.Schema({
vol.Required(CONF_HOST): ipv4_address,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PACKET): vol.All(cv.ensure_list, [data_packet])
})

SERVICE_LEARN_SCHEMA = vol.Schema({
vol.Required(CONF_HOST): ipv4_address,
vol.Required(CONF_HOST): cv.string,
})


Expand Down
8 changes: 4 additions & 4 deletions homeassistant/components/daikin/__init__.py
Expand Up @@ -63,10 +63,10 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
if not daikin_api:
return False
hass.data.setdefault(DOMAIN, {}).update({entry.entry_id: daikin_api})
await asyncio.wait([
hass.config_entries.async_forward_entry_setup(entry, component)
for component in COMPONENT_TYPES
])
for component in COMPONENT_TYPES:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
entry, component))
return True


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/ecovacs/manifest.json
Expand Up @@ -3,7 +3,7 @@
"name": "Ecovacs",
"documentation": "https://www.home-assistant.io/components/ecovacs",
"requirements": [
"sucks==0.9.3"
"sucks==0.9.4"
],
"dependencies": [],
"codeowners": [
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/components/flux/manifest.json
Expand Up @@ -3,8 +3,7 @@
"name": "Flux",
"documentation": "https://www.home-assistant.io/components/flux",
"requirements": [],
"dependencies": [
"light"
],
"dependencies": [],
"after_dependencies": ["light"],
"codeowners": []
}
2 changes: 1 addition & 1 deletion homeassistant/components/heos/manifest.json
Expand Up @@ -3,7 +3,7 @@
"name": "Heos",
"documentation": "https://www.home-assistant.io/components/heos",
"requirements": [
"pyheos==0.4.0"
"pyheos==0.4.1"
],
"dependencies": [],
"codeowners": [
Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/heos/media_player.py
@@ -1,4 +1,5 @@
"""Denon HEOS Media Player."""
import asyncio
from functools import reduce, wraps
import logging
from operator import ior
Expand Down Expand Up @@ -47,7 +48,7 @@ async def wrapper(*args, **kwargs):
from pyheos import CommandError
try:
await func(*args, **kwargs)
except CommandError as ex:
except (CommandError, asyncio.TimeoutError, ConnectionError) as ex:
_LOGGER.error("Unable to %s: %s", command, ex)
return wrapper
return decorator
Expand Down Expand Up @@ -85,6 +86,13 @@ async def _controller_event(self, event):

async def _heos_event(self, event):
"""Handle connection event."""
from pyheos import CommandError, const
if event == const.EVENT_CONNECTED:
try:
await self._player.refresh()
except (CommandError, asyncio.TimeoutError, ConnectionError) as ex:
_LOGGER.error("Unable to refresh player %s: %s",
self._player, ex)
await self.async_update_ha_state(True)

async def _player_update(self, player_id, event):
Expand Down
47 changes: 25 additions & 22 deletions homeassistant/components/media_player/__init__.py
Expand Up @@ -45,7 +45,8 @@
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY, SUPPORT_PLAY_MEDIA,
SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, SUPPORT_SELECT_SOUND_MODE,
SUPPORT_SELECT_SOURCE, SUPPORT_SHUFFLE_SET, SUPPORT_STOP, SUPPORT_TURN_OFF,
SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET)
SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
SUPPORT_VOLUME_STEP)
from .reproduce_state import async_reproduce_states # noqa

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -164,89 +165,89 @@ async def async_setup(hass, config):

component.async_register_entity_service(
SERVICE_TURN_ON, MEDIA_PLAYER_SCHEMA,
'async_turn_on', SUPPORT_TURN_ON
'async_turn_on', [SUPPORT_TURN_ON]
)
component.async_register_entity_service(
SERVICE_TURN_OFF, MEDIA_PLAYER_SCHEMA,
'async_turn_off', SUPPORT_TURN_OFF
'async_turn_off', [SUPPORT_TURN_OFF]
)
component.async_register_entity_service(
SERVICE_TOGGLE, MEDIA_PLAYER_SCHEMA,
'async_toggle', SUPPORT_TURN_OFF | SUPPORT_TURN_ON
'async_toggle', [SUPPORT_TURN_OFF | SUPPORT_TURN_ON]
)
component.async_register_entity_service(
SERVICE_VOLUME_UP, MEDIA_PLAYER_SCHEMA,
'async_volume_up', SUPPORT_VOLUME_SET
'async_volume_up', [SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP]
)
component.async_register_entity_service(
SERVICE_VOLUME_DOWN, MEDIA_PLAYER_SCHEMA,
'async_volume_down', SUPPORT_VOLUME_SET
'async_volume_down', [SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP]
)
component.async_register_entity_service(
SERVICE_MEDIA_PLAY_PAUSE, MEDIA_PLAYER_SCHEMA,
'async_media_play_pause', SUPPORT_PLAY | SUPPORT_PAUSE
'async_media_play_pause', [SUPPORT_PLAY | SUPPORT_PAUSE]
)
component.async_register_entity_service(
SERVICE_MEDIA_PLAY, MEDIA_PLAYER_SCHEMA,
'async_media_play', SUPPORT_PLAY
'async_media_play', [SUPPORT_PLAY]
)
component.async_register_entity_service(
SERVICE_MEDIA_PAUSE, MEDIA_PLAYER_SCHEMA,
'async_media_pause', SUPPORT_PAUSE
'async_media_pause', [SUPPORT_PAUSE]
)
component.async_register_entity_service(
SERVICE_MEDIA_STOP, MEDIA_PLAYER_SCHEMA,
'async_media_stop', SUPPORT_STOP
'async_media_stop', [SUPPORT_STOP]
)
component.async_register_entity_service(
SERVICE_MEDIA_NEXT_TRACK, MEDIA_PLAYER_SCHEMA,
'async_media_next_track', SUPPORT_NEXT_TRACK
'async_media_next_track', [SUPPORT_NEXT_TRACK]
)
component.async_register_entity_service(
SERVICE_MEDIA_PREVIOUS_TRACK, MEDIA_PLAYER_SCHEMA,
'async_media_previous_track', SUPPORT_PREVIOUS_TRACK
'async_media_previous_track', [SUPPORT_PREVIOUS_TRACK]
)
component.async_register_entity_service(
SERVICE_CLEAR_PLAYLIST, MEDIA_PLAYER_SCHEMA,
'async_clear_playlist', SUPPORT_CLEAR_PLAYLIST
'async_clear_playlist', [SUPPORT_CLEAR_PLAYLIST]
)
component.async_register_entity_service(
SERVICE_VOLUME_SET, MEDIA_PLAYER_SET_VOLUME_SCHEMA,
lambda entity, call: entity.async_set_volume_level(
volume=call.data[ATTR_MEDIA_VOLUME_LEVEL]),
SUPPORT_VOLUME_SET
[SUPPORT_VOLUME_SET]
)
component.async_register_entity_service(
SERVICE_VOLUME_MUTE, MEDIA_PLAYER_MUTE_VOLUME_SCHEMA,
lambda entity, call: entity.async_mute_volume(
mute=call.data[ATTR_MEDIA_VOLUME_MUTED]),
SUPPORT_VOLUME_MUTE
[SUPPORT_VOLUME_MUTE]
)
component.async_register_entity_service(
SERVICE_MEDIA_SEEK, MEDIA_PLAYER_MEDIA_SEEK_SCHEMA,
lambda entity, call: entity.async_media_seek(
position=call.data[ATTR_MEDIA_SEEK_POSITION]),
SUPPORT_SEEK
[SUPPORT_SEEK]
)
component.async_register_entity_service(
SERVICE_SELECT_SOURCE, MEDIA_PLAYER_SELECT_SOURCE_SCHEMA,
'async_select_source', SUPPORT_SELECT_SOURCE
'async_select_source', [SUPPORT_SELECT_SOURCE]
)
component.async_register_entity_service(
SERVICE_SELECT_SOUND_MODE, MEDIA_PLAYER_SELECT_SOUND_MODE_SCHEMA,
'async_select_sound_mode', SUPPORT_SELECT_SOUND_MODE
'async_select_sound_mode', [SUPPORT_SELECT_SOUND_MODE]
)
component.async_register_entity_service(
SERVICE_PLAY_MEDIA, MEDIA_PLAYER_PLAY_MEDIA_SCHEMA,
lambda entity, call: entity.async_play_media(
media_type=call.data[ATTR_MEDIA_CONTENT_TYPE],
media_id=call.data[ATTR_MEDIA_CONTENT_ID],
enqueue=call.data.get(ATTR_MEDIA_ENQUEUE)
), SUPPORT_PLAY_MEDIA
), [SUPPORT_PLAY_MEDIA]
)
component.async_register_entity_service(
SERVICE_SHUFFLE_SET, MEDIA_PLAYER_SET_SHUFFLE_SCHEMA,
'async_set_shuffle', SUPPORT_SHUFFLE_SET
'async_set_shuffle', [SUPPORT_SHUFFLE_SET]
)

return True
Expand Down Expand Up @@ -686,7 +687,8 @@ async def async_volume_up(self):
await self.hass.async_add_job(self.volume_up)
return

if self.volume_level < 1:
if self.volume_level < 1 \
and self.supported_features & SUPPORT_VOLUME_SET:
await self.async_set_volume_level(min(1, self.volume_level + .1))

async def async_volume_down(self):
Expand All @@ -699,7 +701,8 @@ async def async_volume_down(self):
await self.hass.async_add_job(self.volume_down)
return

if self.volume_level > 0:
if self.volume_level > 0 \
and self.supported_features & SUPPORT_VOLUME_SET:
await self.async_set_volume_level(
max(0, self.volume_level - .1))

Expand Down
19 changes: 11 additions & 8 deletions homeassistant/components/netatmo/__init__.py
Expand Up @@ -12,6 +12,8 @@
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle

from .const import DOMAIN, DATA_NETATMO_AUTH

_LOGGER = logging.getLogger(__name__)

DATA_PERSONS = 'netatmo_persons'
Expand All @@ -20,8 +22,6 @@
CONF_SECRET_KEY = 'secret_key'
CONF_WEBHOOKS = 'webhooks'

DOMAIN = 'netatmo'

SERVICE_ADDWEBHOOK = 'addwebhook'
SERVICE_DROPWEBHOOK = 'dropwebhook'

Expand Down Expand Up @@ -83,10 +83,9 @@ def setup(hass, config):
"""Set up the Netatmo devices."""
import pyatmo

global NETATMO_AUTH
hass.data[DATA_PERSONS] = {}
try:
NETATMO_AUTH = pyatmo.ClientAuth(
auth = pyatmo.ClientAuth(
config[DOMAIN][CONF_API_KEY], config[DOMAIN][CONF_SECRET_KEY],
config[DOMAIN][CONF_USERNAME], config[DOMAIN][CONF_PASSWORD],
'read_station read_camera access_camera '
Expand All @@ -96,6 +95,9 @@ def setup(hass, config):
_LOGGER.error("Unable to connect to Netatmo API")
return False

# Store config to be used during entry setup
hass.data[DATA_NETATMO_AUTH] = auth

if config[DOMAIN][CONF_DISCOVERY]:
for component in 'camera', 'sensor', 'binary_sensor', 'climate':
discovery.load_platform(hass, component, DOMAIN, {}, config)
Expand All @@ -107,7 +109,7 @@ def setup(hass, config):
webhook_id)
hass.components.webhook.async_register(
DOMAIN, 'Netatmo', webhook_id, handle_webhook)
NETATMO_AUTH.addwebhook(hass.data[DATA_WEBHOOK_URL])
auth.addwebhook(hass.data[DATA_WEBHOOK_URL])
hass.bus.listen_once(
EVENT_HOMEASSISTANT_STOP, dropwebhook)

Expand All @@ -117,7 +119,7 @@ def _service_addwebhook(service):
if url is None:
url = hass.data[DATA_WEBHOOK_URL]
_LOGGER.info("Adding webhook for URL: %s", url)
NETATMO_AUTH.addwebhook(url)
auth.addwebhook(url)

hass.services.register(
DOMAIN, SERVICE_ADDWEBHOOK, _service_addwebhook,
Expand All @@ -126,7 +128,7 @@ def _service_addwebhook(service):
def _service_dropwebhook(service):
"""Service to drop webhooks during runtime."""
_LOGGER.info("Dropping webhook")
NETATMO_AUTH.dropwebhook()
auth.dropwebhook()

hass.services.register(
DOMAIN, SERVICE_DROPWEBHOOK, _service_dropwebhook,
Expand All @@ -137,7 +139,8 @@ def _service_dropwebhook(service):

def dropwebhook(hass):
"""Drop the webhook subscription."""
NETATMO_AUTH.dropwebhook()
auth = hass.data[DATA_NETATMO_AUTH]
auth.dropwebhook()


async def handle_webhook(hass, webhook_id, request):
Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/netatmo/binary_sensor.py
Expand Up @@ -8,7 +8,8 @@
from homeassistant.const import CONF_TIMEOUT
from homeassistant.helpers import config_validation as cv

from . import CameraData, NETATMO_AUTH
from .const import DATA_NETATMO_AUTH
from . import CameraData

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -59,8 +60,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
module_name = None

import pyatmo

auth = hass.data[DATA_NETATMO_AUTH]

try:
data = CameraData(hass, NETATMO_AUTH, home)
data = CameraData(hass, auth, home)
if not data.get_camera_names():
return None
except pyatmo.NoDevice:
Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/netatmo/camera.py
Expand Up @@ -9,7 +9,8 @@
from homeassistant.const import CONF_VERIFY_SSL
from homeassistant.helpers import config_validation as cv

from . import CameraData, NETATMO_AUTH
from .const import DATA_NETATMO_AUTH
from . import CameraData

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -37,8 +38,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
verify_ssl = config.get(CONF_VERIFY_SSL, True)
quality = config.get(CONF_QUALITY, DEFAULT_QUALITY)
import pyatmo

auth = hass.data[DATA_NETATMO_AUTH]

try:
data = CameraData(hass, NETATMO_AUTH, home)
data = CameraData(hass, auth, home)
for camera_name in data.get_camera_names():
camera_type = data.get_camera_type(camera=camera_name, home=home)
if CONF_CAMERAS in config:
Expand Down

0 comments on commit ee10775

Please sign in to comment.