Async syntax 3/8 (#17017)

* Async syntax 3, device_tracker & fan & hassio & image_processing & input

* Pylint fixes
This commit is contained in:
cdce8p 2018-10-01 08:59:45 +02:00 committed by Paulus Schoutsen
parent 134eeecd65
commit b24f9f5dfa
23 changed files with 194 additions and 286 deletions

View file

@ -139,8 +139,7 @@ def see(hass: HomeAssistantType, mac: str = None, dev_id: str = None,
hass.services.call(DOMAIN, SERVICE_SEE, data)
@asyncio.coroutine
def async_setup(hass: HomeAssistantType, config: ConfigType):
async def async_setup(hass: HomeAssistantType, config: ConfigType):
"""Set up the device tracker."""
yaml_path = hass.config.path(YAML_DEVICES)
@ -153,14 +152,13 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
if track_new is None:
track_new = defaults.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW)
devices = yield from async_load_config(yaml_path, hass, consider_home)
devices = await async_load_config(yaml_path, hass, consider_home)
tracker = DeviceTracker(
hass, consider_home, track_new, defaults, devices)
@asyncio.coroutine
def async_setup_platform(p_type, p_config, disc_info=None):
async def async_setup_platform(p_type, p_config, disc_info=None):
"""Set up a device tracker platform."""
platform = yield from async_prepare_setup_platform(
platform = await async_prepare_setup_platform(
hass, config, DOMAIN, p_type)
if platform is None:
return
@ -170,16 +168,16 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
scanner = None
setup = None
if hasattr(platform, 'async_get_scanner'):
scanner = yield from platform.async_get_scanner(
scanner = await platform.async_get_scanner(
hass, {DOMAIN: p_config})
elif hasattr(platform, 'get_scanner'):
scanner = yield from hass.async_add_job(
scanner = await hass.async_add_job(
platform.get_scanner, hass, {DOMAIN: p_config})
elif hasattr(platform, 'async_setup_scanner'):
setup = yield from platform.async_setup_scanner(
setup = await platform.async_setup_scanner(
hass, p_config, tracker.async_see, disc_info)
elif hasattr(platform, 'setup_scanner'):
setup = yield from hass.async_add_job(
setup = await hass.async_add_job(
platform.setup_scanner, hass, p_config, tracker.see,
disc_info)
else:
@ -200,14 +198,13 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
setup_tasks = [async_setup_platform(p_type, p_config) for p_type, p_config
in config_per_platform(config, DOMAIN)]
if setup_tasks:
yield from asyncio.wait(setup_tasks, loop=hass.loop)
await asyncio.wait(setup_tasks, loop=hass.loop)
tracker.async_setup_group()
@asyncio.coroutine
def async_platform_discovered(platform, info):
async def async_platform_discovered(platform, info):
"""Load a platform."""
yield from async_setup_platform(platform, {}, disc_info=info)
await async_setup_platform(platform, {}, disc_info=info)
discovery.async_listen_platform(hass, DOMAIN, async_platform_discovered)
@ -215,20 +212,19 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
async_track_utc_time_change(
hass, tracker.async_update_stale, second=range(0, 60, 5))
@asyncio.coroutine
def async_see_service(call):
async def async_see_service(call):
"""Service to see a device."""
# Temp workaround for iOS, introduced in 0.65
data = dict(call.data)
data.pop('hostname', None)
data.pop('battery_status', None)
yield from tracker.async_see(**data)
await tracker.async_see(**data)
hass.services.async_register(
DOMAIN, SERVICE_SEE, async_see_service, SERVICE_SEE_PAYLOAD_SCHEMA)
# restore
yield from tracker.async_setup_tracked_device()
await tracker.async_setup_tracked_device()
return True
@ -269,8 +265,7 @@ class DeviceTracker:
picture, icon, consider_home)
)
@asyncio.coroutine
def async_see(
async def async_see(
self, mac: str = None, dev_id: str = None, host_name: str = None,
location_name: str = None, gps: GPSType = None,
gps_accuracy: int = None, battery: int = None,
@ -293,11 +288,11 @@ class DeviceTracker:
device = self.devices.get(dev_id)
if device:
yield from device.async_seen(
await device.async_seen(
host_name, location_name, gps, gps_accuracy, battery,
attributes, source_type, consider_home)
if device.track:
yield from device.async_update_ha_state()
await device.async_update_ha_state()
return
# If no device can be found, create it
@ -311,12 +306,12 @@ class DeviceTracker:
if mac is not None:
self.mac_to_dev[mac] = device
yield from device.async_seen(
await device.async_seen(
host_name, location_name, gps, gps_accuracy, battery, attributes,
source_type)
if device.track:
yield from device.async_update_ha_state()
await device.async_update_ha_state()
# During init, we ignore the group
if self.group and self.track_new:
@ -378,17 +373,15 @@ class DeviceTracker:
device.stale(now):
self.hass.async_add_job(device.async_update_ha_state(True))
@asyncio.coroutine
def async_setup_tracked_device(self):
async def async_setup_tracked_device(self):
"""Set up all not exists tracked devices.
This method is a coroutine.
"""
@asyncio.coroutine
def async_init_single_device(dev):
async def async_init_single_device(dev):
"""Init a single device_tracker entity."""
yield from dev.async_added_to_hass()
yield from dev.async_update_ha_state()
await dev.async_added_to_hass()
await dev.async_update_ha_state()
tasks = []
for device in self.devices.values():
@ -397,7 +390,7 @@ class DeviceTracker:
async_init_single_device(device)))
if tasks:
yield from asyncio.wait(tasks, loop=self.hass.loop)
await asyncio.wait(tasks, loop=self.hass.loop)
class Device(Entity):
@ -495,12 +488,12 @@ class Device(Entity):
"""If device should be hidden."""
return self.away_hide and self.state != STATE_HOME
@asyncio.coroutine
def async_seen(self, host_name: str = None, location_name: str = None,
gps: GPSType = None, gps_accuracy=0, battery: int = None,
attributes: dict = None,
source_type: str = SOURCE_TYPE_GPS,
consider_home: timedelta = None):
async def async_seen(
self, host_name: str = None, location_name: str = None,
gps: GPSType = None, gps_accuracy=0, battery: int = None,
attributes: dict = None,
source_type: str = SOURCE_TYPE_GPS,
consider_home: timedelta = None):
"""Mark the device as seen."""
self.source_type = source_type
self.last_seen = dt_util.utcnow()
@ -526,7 +519,7 @@ class Device(Entity):
"Could not parse gps value for %s: %s", self.dev_id, gps)
# pylint: disable=not-an-iterable
yield from self.async_update()
await self.async_update()
def stale(self, now: dt_util.dt.datetime = None):
"""Return if device state is stale.
@ -536,8 +529,7 @@ class Device(Entity):
return self.last_seen and \
(now or dt_util.utcnow()) - self.last_seen > self.consider_home
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Update state of entity.
This method is a coroutine.
@ -563,10 +555,9 @@ class Device(Entity):
self._state = STATE_HOME
self.last_update_home = True
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Add an entity."""
state = yield from async_get_last_state(self.hass, self.entity_id)
state = await async_get_last_state(self.hass, self.entity_id)
if not state:
return
self._state = state.state
@ -629,9 +620,8 @@ def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta):
async_load_config(path, hass, consider_home), hass.loop).result()
@asyncio.coroutine
def async_load_config(path: str, hass: HomeAssistantType,
consider_home: timedelta):
async def async_load_config(path: str, hass: HomeAssistantType,
consider_home: timedelta):
"""Load devices from YAML configuration file.
This method is a coroutine.
@ -651,7 +641,7 @@ def async_load_config(path: str, hass: HomeAssistantType,
try:
result = []
try:
devices = yield from hass.async_add_job(
devices = await hass.async_add_job(
load_yaml_config_file, path)
except HomeAssistantError as err:
_LOGGER.error("Unable to load %s: %s", path, str(err))

View file

@ -4,7 +4,6 @@ Support for the Geofency platform.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.geofency/
"""
import asyncio
from functools import partial
import logging
@ -58,10 +57,9 @@ class GeofencyView(HomeAssistantView):
self.see = see
self.mobile_beacons = [slugify(beacon) for beacon in mobile_beacons]
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Handle Geofency requests."""
data = yield from request.post()
data = await request.post()
hass = request.app['hass']
data = self._validate_data(data)
@ -69,7 +67,7 @@ class GeofencyView(HomeAssistantView):
return ("Invalid data", HTTP_UNPROCESSABLE_ENTITY)
if self._is_mobile_beacon(data):
return (yield from self._set_location(hass, data, None))
return await self._set_location(hass, data, None)
if data['entry'] == LOCATION_ENTRY:
location_name = data['name']
else:
@ -78,7 +76,7 @@ class GeofencyView(HomeAssistantView):
data[ATTR_LATITUDE] = data[ATTR_CURRENT_LATITUDE]
data[ATTR_LONGITUDE] = data[ATTR_CURRENT_LONGITUDE]
return (yield from self._set_location(hass, data, location_name))
return await self._set_location(hass, data, location_name)
@staticmethod
def _validate_data(data):
@ -121,12 +119,11 @@ class GeofencyView(HomeAssistantView):
return "{}_{}".format(BEACON_DEV_PREFIX, data['name'])
return data['device']
@asyncio.coroutine
def _set_location(self, hass, data, location_name):
async def _set_location(self, hass, data, location_name):
"""Fire HA event to set location."""
device = self._device_name(data)
yield from hass.async_add_job(
await hass.async_add_job(
partial(self.see, dev_id=device,
gps=(data[ATTR_LATITUDE], data[ATTR_LONGITUDE]),
location_name=location_name,

View file

@ -4,7 +4,6 @@ Support for the Locative platform.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.locative/
"""
import asyncio
from functools import partial
import logging
@ -38,21 +37,18 @@ class LocativeView(HomeAssistantView):
"""Initialize Locative URL endpoints."""
self.see = see
@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Locative message received as GET."""
res = yield from self._handle(request.app['hass'], request.query)
res = await self._handle(request.app['hass'], request.query)
return res
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Locative message received."""
data = yield from request.post()
res = yield from self._handle(request.app['hass'], data)
data = await request.post()
res = await self._handle(request.app['hass'], data)
return res
@asyncio.coroutine
def _handle(self, hass, data):
async def _handle(self, hass, data):
"""Handle locative request."""
if 'latitude' not in data or 'longitude' not in data:
return ('Latitude and longitude not specified.',
@ -79,7 +75,7 @@ class LocativeView(HomeAssistantView):
gps_location = (data[ATTR_LATITUDE], data[ATTR_LONGITUDE])
if direction == 'enter':
yield from hass.async_add_job(
await hass.async_add_job(
partial(self.see, dev_id=device, location_name=location_name,
gps=gps_location))
return 'Setting location to {}'.format(location_name)
@ -90,7 +86,7 @@ class LocativeView(HomeAssistantView):
if current_state is None or current_state.state == location_name:
location_name = STATE_NOT_HOME
yield from hass.async_add_job(
await hass.async_add_job(
partial(self.see, dev_id=device,
location_name=location_name, gps=gps_location))
return 'Setting location to not home'

View file

@ -5,7 +5,6 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.meraki/
"""
import asyncio
import logging
import json
@ -33,8 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an endpoint for the Meraki tracker."""
hass.http.register_view(
MerakiView(config, async_see))
@ -54,16 +52,14 @@ class MerakiView(HomeAssistantView):
self.validator = config[CONF_VALIDATOR]
self.secret = config[CONF_SECRET]
@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Meraki message received as GET."""
return self.validator
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Meraki CMX message received."""
try:
data = yield from request.json()
data = await request.json()
except ValueError:
return self.json_message('Invalid JSON', HTTP_BAD_REQUEST)
_LOGGER.debug("Meraki Data from Post: %s", json.dumps(data))

View file

@ -4,7 +4,6 @@ Support for tracking MQTT enabled devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.mqtt/
"""
import asyncio
import logging
import voluptuous as vol
@ -25,8 +24,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend({
})
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up the MQTT tracker."""
devices = config[CONF_DEVICES]
qos = config[CONF_QOS]
@ -38,7 +36,7 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
hass.async_add_job(
async_see(dev_id=dev_id, location_name=payload))
yield from mqtt.async_subscribe(
await mqtt.async_subscribe(
hass, topic, async_message_received, qos)
return True

View file

@ -4,7 +4,6 @@ Support for GPS tracking MQTT enabled devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.mqtt_json/
"""
import asyncio
import json
import logging
@ -35,8 +34,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend({
})
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up the MQTT JSON tracker."""
devices = config[CONF_DEVICES]
qos = config[CONF_QOS]
@ -59,7 +57,7 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
kwargs = _parse_see_args(dev_id, data)
hass.async_add_job(async_see(**kwargs))
yield from mqtt.async_subscribe(
await mqtt.async_subscribe(
hass, topic, async_message_received, qos)
return True

View file

@ -4,7 +4,6 @@ Device tracker platform that adds support for OwnTracks over MQTT.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks/
"""
import asyncio
import base64
import json
import logging
@ -73,13 +72,11 @@ def get_cipher():
return (KEYLEN, decrypt)
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker."""
context = context_from_config(async_see, config)
@asyncio.coroutine
def async_handle_mqtt_message(topic, payload, qos):
async def async_handle_mqtt_message(topic, payload, qos):
"""Handle incoming OwnTracks message."""
try:
message = json.loads(payload)
@ -90,9 +87,9 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
message['topic'] = topic
yield from async_handle_message(hass, context, message)
await async_handle_message(hass, context, message)
yield from mqtt.async_subscribe(
await mqtt.async_subscribe(
hass, context.mqtt_topic, async_handle_mqtt_message, 1)
return True
@ -266,8 +263,7 @@ class OwnTracksContext:
return True
@asyncio.coroutine
def async_see_beacons(self, hass, dev_id, kwargs_param):
async def async_see_beacons(self, hass, dev_id, kwargs_param):
"""Set active beacons to the current location."""
kwargs = kwargs_param.copy()
@ -290,12 +286,11 @@ class OwnTracksContext:
for beacon in self.mobile_beacons_active[dev_id]:
kwargs['dev_id'] = "{}_{}".format(BEACON_DEV_ID, beacon)
kwargs['host_name'] = beacon
yield from self.async_see(**kwargs)
await self.async_see(**kwargs)
@HANDLERS.register('location')
@asyncio.coroutine
def async_handle_location_message(hass, context, message):
async def async_handle_location_message(hass, context, message):
"""Handle a location message."""
if not context.async_valid_accuracy(message):
return
@ -312,12 +307,11 @@ def async_handle_location_message(hass, context, message):
context.regions_entered[-1])
return
yield from context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see(**kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
@asyncio.coroutine
def _async_transition_message_enter(hass, context, message, location):
async def _async_transition_message_enter(hass, context, message, location):
"""Execute enter event."""
zone = hass.states.get("zone.{}".format(slugify(location)))
dev_id, kwargs = _parse_see_args(message, context.mqtt_topic)
@ -331,7 +325,7 @@ def _async_transition_message_enter(hass, context, message, location):
if location not in beacons:
beacons.add(location)
_LOGGER.info("Added beacon %s", location)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
else:
# Normal region
regions = context.regions_entered[dev_id]
@ -339,12 +333,11 @@ def _async_transition_message_enter(hass, context, message, location):
regions.append(location)
_LOGGER.info("Enter region %s", location)
_set_gps_from_zone(kwargs, location, zone)
yield from context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see(**kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
@asyncio.coroutine
def _async_transition_message_leave(hass, context, message, location):
async def _async_transition_message_leave(hass, context, message, location):
"""Execute leave event."""
dev_id, kwargs = _parse_see_args(message, context.mqtt_topic)
regions = context.regions_entered[dev_id]
@ -356,7 +349,7 @@ def _async_transition_message_leave(hass, context, message, location):
if location in beacons:
beacons.remove(location)
_LOGGER.info("Remove beacon %s", location)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
else:
new_region = regions[-1] if regions else None
if new_region:
@ -365,21 +358,20 @@ def _async_transition_message_leave(hass, context, message, location):
"zone.{}".format(slugify(new_region)))
_set_gps_from_zone(kwargs, new_region, zone)
_LOGGER.info("Exit to %s", new_region)
yield from context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see(**kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
return
_LOGGER.info("Exit to GPS")
# Check for GPS accuracy
if context.async_valid_accuracy(message):
yield from context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs)
await context.async_see(**kwargs)
await context.async_see_beacons(hass, dev_id, kwargs)
@HANDLERS.register('transition')
@asyncio.coroutine
def async_handle_transition_message(hass, context, message):
async def async_handle_transition_message(hass, context, message):
"""Handle a transition message."""
if message.get('desc') is None:
_LOGGER.error(
@ -399,10 +391,10 @@ def async_handle_transition_message(hass, context, message):
location = STATE_HOME
if message['event'] == 'enter':
yield from _async_transition_message_enter(
await _async_transition_message_enter(
hass, context, message, location)
elif message['event'] == 'leave':
yield from _async_transition_message_leave(
await _async_transition_message_leave(
hass, context, message, location)
else:
_LOGGER.error(
@ -410,8 +402,7 @@ def async_handle_transition_message(hass, context, message):
message['event'])
@asyncio.coroutine
def async_handle_waypoint(hass, name_base, waypoint):
async def async_handle_waypoint(hass, name_base, waypoint):
"""Handle a waypoint."""
name = waypoint['desc']
pretty_name = '{} - {}'.format(name_base, name)
@ -429,13 +420,12 @@ def async_handle_waypoint(hass, name_base, waypoint):
zone = zone_comp.Zone(hass, pretty_name, lat, lon, rad,
zone_comp.ICON_IMPORT, False)
zone.entity_id = entity_id
yield from zone.async_update_ha_state()
await zone.async_update_ha_state()
@HANDLERS.register('waypoint')
@HANDLERS.register('waypoints')
@asyncio.coroutine
def async_handle_waypoints_message(hass, context, message):
async def async_handle_waypoints_message(hass, context, message):
"""Handle a waypoints message."""
if not context.import_waypoints:
return
@ -456,12 +446,11 @@ def async_handle_waypoints_message(hass, context, message):
name_base = ' '.join(_parse_topic(message['topic'], context.mqtt_topic))
for wayp in wayps:
yield from async_handle_waypoint(hass, name_base, wayp)
await async_handle_waypoint(hass, name_base, wayp)
@HANDLERS.register('encrypted')
@asyncio.coroutine
def async_handle_encrypted_message(hass, context, message):
async def async_handle_encrypted_message(hass, context, message):
"""Handle an encrypted message."""
plaintext_payload = _decrypt_payload(context.secret, message['topic'],
message['data'])
@ -472,7 +461,7 @@ def async_handle_encrypted_message(hass, context, message):
decrypted = json.loads(plaintext_payload)
decrypted['topic'] = message['topic']
yield from async_handle_message(hass, context, decrypted)
await async_handle_message(hass, context, decrypted)
@HANDLERS.register('lwt')
@ -481,24 +470,21 @@ def async_handle_encrypted_message(hass, context, message):
@HANDLERS.register('cmd')
@HANDLERS.register('steps')
@HANDLERS.register('card')
@asyncio.coroutine
def async_handle_not_impl_msg(hass, context, message):
async def async_handle_not_impl_msg(hass, context, message):
"""Handle valid but not implemented message types."""
_LOGGER.debug('Not handling %s message: %s', message.get("_type"), message)
@asyncio.coroutine
def async_handle_unsupported_msg(hass, context, message):
async def async_handle_unsupported_msg(hass, context, message):
"""Handle an unsupported or invalid message type."""
_LOGGER.warning('Received unsupported message type: %s.',
message.get('_type'))
@asyncio.coroutine
def async_handle_message(hass, context, message):
async def async_handle_message(hass, context, message):
"""Handle an OwnTracks message."""
msgtype = message.get('_type')
handler = HANDLERS.get(msgtype, async_handle_unsupported_msg)
yield from handler(hass, context, message)
await handler(hass, context, message)

View file

@ -4,7 +4,6 @@ Device tracker platform that adds support for OwnTracks over HTTP.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks_http/
"""
import asyncio
import re
from aiohttp.web_exceptions import HTTPInternalServerError
@ -19,8 +18,7 @@ from .owntracks import ( # NOQA
DEPENDENCIES = ['http']
@asyncio.coroutine
def async_setup_scanner(hass, config, async_see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker."""
context = context_from_config(async_see, config)
@ -39,19 +37,18 @@ class OwnTracksView(HomeAssistantView):
"""Initialize OwnTracks URL endpoints."""
self.context = context
@asyncio.coroutine
def post(self, request, user, device):
async def post(self, request, user, device):
"""Handle an OwnTracks message."""
hass = request.app['hass']
subscription = self.context.mqtt_topic
topic = re.sub('/#$', '', subscription)
message = yield from request.json()
message = await request.json()
message['topic'] = '{}/{}/{}'.format(topic, user, device)
try:
yield from async_handle_message(hass, self.context, message)
await async_handle_message(hass, self.context, message)
return self.json([])
except ValueError:

View file

@ -31,11 +31,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_get_scanner(hass, config):
async def async_get_scanner(hass, config):
"""Return the UPC device scanner."""
scanner = UPCDeviceScanner(hass, config[DOMAIN])
success_init = yield from scanner.async_initialize_token()
success_init = await scanner.async_initialize_token()
return scanner if success_init else None
@ -61,18 +60,17 @@ class UPCDeviceScanner(DeviceScanner):
self.websession = async_get_clientsession(hass)
@asyncio.coroutine
def async_scan_devices(self):
async def async_scan_devices(self):
"""Scan for new devices and return a list with found device IDs."""
import defusedxml.ElementTree as ET
if self.token is None:
token_initialized = yield from self.async_initialize_token()
token_initialized = await self.async_initialize_token()
if not token_initialized:
_LOGGER.error("Not connected to %s", self.host)
return []
raw = yield from self._async_ws_function(CMD_DEVICES)
raw = await self._async_ws_function(CMD_DEVICES)
try:
xml_root = ET.fromstring(raw)
@ -82,22 +80,20 @@ class UPCDeviceScanner(DeviceScanner):
self.token = None
return []
@asyncio.coroutine
def async_get_device_name(self, device):
async def async_get_device_name(self, device):
"""Get the device name (the name of the wireless device not used)."""
return None
@asyncio.coroutine
def async_initialize_token(self):
async def async_initialize_token(self):
"""Get first token."""
try:
# get first token
with async_timeout.timeout(10, loop=self.hass.loop):
response = yield from self.websession.get(
response = await self.websession.get(
"http://{}/common_page/login.html".format(self.host),
headers=self.headers)
yield from response.text()
await response.text()
self.token = response.cookies['sessionToken'].value
@ -107,14 +103,13 @@ class UPCDeviceScanner(DeviceScanner):
_LOGGER.error("Can not load login page from %s", self.host)
return False
@asyncio.coroutine
def _async_ws_function(self, function):
async def _async_ws_function(self, function):
"""Execute a command on UPC firmware webservice."""
try:
with async_timeout.timeout(10, loop=self.hass.loop):
# The 'token' parameter has to be first, and 'fun' second
# or the UPC firmware will return an error
response = yield from self.websession.post(
response = await self.websession.post(
"http://{}/xml/getter.xml".format(self.host),
data="token={}&fun={}".format(self.token, function),
headers=self.headers, allow_redirects=False)
@ -127,7 +122,7 @@ class UPCDeviceScanner(DeviceScanner):
# Load data, store token for next request
self.token = response.cookies['sessionToken'].value
return (yield from response.text())
return await response.text()
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Error on %s", function)

View file

@ -3,7 +3,6 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/fan.dyson/
"""
import asyncio
import logging
import voluptuous as vol
@ -77,8 +76,7 @@ class DysonPureCoolLinkDevice(FanEntity):
self.hass = hass
self._device = device
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Call when entity is added to hass."""
self.hass.async_add_job(
self._device.add_message_listener, self.on_message)

View file

@ -4,7 +4,6 @@ Support for INSTEON fans via PowerLinc Modem.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/fan.insteon/
"""
import asyncio
import logging
from homeassistant.components.fan import (SPEED_OFF,
@ -28,9 +27,8 @@ FAN_SPEEDS = [STATE_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
_LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the INSTEON device class for the hass platform."""
insteon_modem = hass.data['insteon'].get('modem')
@ -64,20 +62,17 @@ class InsteonFan(InsteonEntity, FanEntity):
"""Flag supported features."""
return SUPPORT_SET_SPEED
@asyncio.coroutine
def async_turn_on(self, speed: str = None, **kwargs) -> None:
async def async_turn_on(self, speed: str = None, **kwargs) -> None:
"""Turn on the entity."""
if speed is None:
speed = SPEED_MEDIUM
yield from self.async_set_speed(speed)
await self.async_set_speed(speed)
@asyncio.coroutine
def async_turn_off(self, **kwargs) -> None:
async def async_turn_off(self, **kwargs) -> None:
"""Turn off the entity."""
yield from self.async_set_speed(SPEED_OFF)
await self.async_set_speed(SPEED_OFF)
@asyncio.coroutine
def async_set_speed(self, speed: str) -> None:
async def async_set_speed(self, speed: str) -> None:
"""Set the speed of the fan."""
fan_speed = SPEED_TO_HEX[speed]
if fan_speed == 0x00:

View file

@ -4,7 +4,6 @@ Support for Wink fans.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/fan.wink/
"""
import asyncio
import logging
from homeassistant.components.fan import (
@ -33,8 +32,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class WinkFanDevice(WinkDevice, FanEntity):
"""Representation of a Wink fan."""
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['fan'].append(self)

View file

@ -4,7 +4,6 @@ Exposes regular REST commands as services.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/hassio/
"""
import asyncio
from datetime import timedelta
import logging
import os
@ -134,11 +133,10 @@ def is_hassio(hass):
@bind_hass
@asyncio.coroutine
def async_check_config(hass):
async def async_check_config(hass):
"""Check configuration over Hass.io API."""
hassio = hass.data[DOMAIN]
result = yield from hassio.check_homeassistant_config()
result = await hassio.check_homeassistant_config()
if not result:
return "Hass.io config check API error"
@ -147,8 +145,7 @@ def async_check_config(hass):
return None
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up the Hass.io component."""
try:
host = os.environ['HASSIO']
@ -165,27 +162,27 @@ def async_setup(hass, config):
websession = hass.helpers.aiohttp_client.async_get_clientsession()
hass.data[DOMAIN] = hassio = HassIO(hass.loop, websession, host)
if not (yield from hassio.is_connected()):
if not await hassio.is_connected():
_LOGGER.error("Not connected with Hass.io")
return False
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
data = yield from store.async_load()
data = await store.async_load()
if data is None:
data = {}
refresh_token = None
if 'hassio_user' in data:
user = yield from hass.auth.async_get_user(data['hassio_user'])
user = await hass.auth.async_get_user(data['hassio_user'])
if user and user.refresh_tokens:
refresh_token = list(user.refresh_tokens.values())[0]
if refresh_token is None:
user = yield from hass.auth.async_create_system_user('Hass.io')
refresh_token = yield from hass.auth.async_create_refresh_token(user)
user = await hass.auth.async_create_system_user('Hass.io')
refresh_token = await hass.auth.async_create_refresh_token(user)
data['hassio_user'] = user.id
yield from store.async_save(data)
await store.async_save(data)
# This overrides the normal API call that would be forwarded
development_repo = config.get(DOMAIN, {}).get(CONF_FRONTEND_REPO)
@ -197,7 +194,7 @@ def async_setup(hass, config):
hass.http.register_view(HassIOView(host, websession))
if 'frontend' in hass.config.components:
yield from hass.components.panel_custom.async_register_panel(
await hass.components.panel_custom.async_register_panel(
frontend_url_path='hassio',
webcomponent_name='hassio-main',
sidebar_title='Hass.io',
@ -212,13 +209,12 @@ def async_setup(hass, config):
else:
token = None
yield from hassio.update_hass_api(config.get('http', {}), token)
await hassio.update_hass_api(config.get('http', {}), token)
if 'homeassistant' in config:
yield from hassio.update_hass_timezone(config['homeassistant'])
await hassio.update_hass_timezone(config['homeassistant'])
@asyncio.coroutine
def async_service_handler(service):
async def async_service_handler(service):
"""Handle service calls for Hass.io."""
api_command = MAP_SERVICE_API[service.service][0]
data = service.data.copy()
@ -233,7 +229,7 @@ def async_setup(hass, config):
payload = data
# Call API
ret = yield from hassio.send_command(
ret = await hassio.send_command(
api_command.format(addon=addon, snapshot=snapshot),
payload=payload, timeout=MAP_SERVICE_API[service.service][2]
)
@ -245,10 +241,9 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, service, async_service_handler, schema=settings[1])
@asyncio.coroutine
def update_homeassistant_version(now):
async def update_homeassistant_version(now):
"""Update last available Home Assistant version."""
data = yield from hassio.get_homeassistant_info()
data = await hassio.get_homeassistant_info()
if data:
hass.data[DATA_HOMEASSISTANT_VERSION] = data['last_version']
@ -256,16 +251,15 @@ def async_setup(hass, config):
update_homeassistant_version, utcnow() + HASSIO_UPDATE_INTERVAL)
# Fetch last version
yield from update_homeassistant_version(None)
await update_homeassistant_version(None)
@asyncio.coroutine
def async_handle_core_service(call):
async def async_handle_core_service(call):
"""Service handler for handling core services."""
if call.service == SERVICE_HOMEASSISTANT_STOP:
yield from hassio.stop_homeassistant()
await hassio.stop_homeassistant()
return
error = yield from async_check_config(hass)
error = await async_check_config(hass)
if error:
_LOGGER.error(error)
hass.components.persistent_notification.async_create(
@ -274,7 +268,7 @@ def async_setup(hass, config):
return
if call.service == SERVICE_HOMEASSISTANT_RESTART:
yield from hassio.restart_homeassistant()
await hassio.restart_homeassistant()
# Mock core services
for service in (SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART,

View file

@ -120,15 +120,15 @@ class HassIO:
'timezone': core_config.get(CONF_TIME_ZONE)
})
@asyncio.coroutine
def send_command(self, command, method="post", payload=None, timeout=10):
async def send_command(self, command, method="post", payload=None,
timeout=10):
"""Send API command to Hass.io.
This method is a coroutine.
"""
try:
with async_timeout.timeout(timeout, loop=self.loop):
request = yield from self.websession.request(
request = await self.websession.request(
method, "http://{}{}".format(self._ip, command),
json=payload, headers={
X_HASSIO: os.environ.get('HASSIO_TOKEN', "")
@ -139,7 +139,7 @@ class HassIO:
"%s return code %d.", command, request.status)
return None
answer = yield from request.json()
answer = await request.json()
return answer
except asyncio.TimeoutError:

View file

@ -54,15 +54,14 @@ class HassIOView(HomeAssistantView):
self._host = host
self._websession = websession
@asyncio.coroutine
def _handle(self, request, path):
async def _handle(self, request, path):
"""Route data to Hass.io."""
if _need_auth(path) and not request[KEY_AUTHENTICATED]:
return web.Response(status=401)
client = yield from self._command_proxy(path, request)
client = await self._command_proxy(path, request)
data = yield from client.read()
data = await client.read()
if path.endswith('/logs'):
return _create_response_log(client, data)
return _create_response(client, data)
@ -70,8 +69,7 @@ class HassIOView(HomeAssistantView):
get = _handle
post = _handle
@asyncio.coroutine
def _command_proxy(self, path, request):
async def _command_proxy(self, path, request):
"""Return a client request with proxy origin for Hass.io supervisor.
This method is a coroutine.
@ -83,14 +81,14 @@ class HassIOView(HomeAssistantView):
data = None
headers = {X_HASSIO: os.environ.get('HASSIO_TOKEN', "")}
with async_timeout.timeout(10, loop=hass.loop):
data = yield from request.read()
data = await request.read()
if data:
headers[CONTENT_TYPE] = request.content_type
else:
data = None
method = getattr(self._websession, request.method.lower())
client = yield from method(
client = await method(
"http://{}/{}".format(self._host, path), data=data,
headers=headers, timeout=read_timeout
)

View file

@ -4,7 +4,6 @@ Component that will help set the Microsoft face detect processing.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/image_processing.microsoft_face_detect/
"""
import asyncio
import logging
import voluptuous as vol
@ -45,9 +44,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Microsoft Face detection platform."""
api = hass.data[DATA_MICROSOFT_FACE]
attributes = config[CONF_ATTRIBUTES]
@ -88,15 +86,14 @@ class MicrosoftFaceDetectEntity(ImageProcessingFaceEntity):
"""Return the name of the entity."""
return self._name
@asyncio.coroutine
def async_process_image(self, image):
async def async_process_image(self, image):
"""Process image.
This method is a coroutine.
"""
face_data = None
try:
face_data = yield from self._api.call_api(
face_data = await self._api.call_api(
'post', 'detect', image, binary=True,
params={'returnFaceAttributes': ",".join(self._attributes)})

View file

@ -4,7 +4,6 @@ Component that will help set the Microsoft face for verify processing.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/image_processing.microsoft_face_identify/
"""
import asyncio
import logging
import voluptuous as vol
@ -29,9 +28,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Microsoft Face identify platform."""
api = hass.data[DATA_MICROSOFT_FACE]
face_group = config[CONF_GROUP]
@ -80,22 +78,21 @@ class MicrosoftFaceIdentifyEntity(ImageProcessingFaceEntity):
"""Return the name of the entity."""
return self._name
@asyncio.coroutine
def async_process_image(self, image):
async def async_process_image(self, image):
"""Process image.
This method is a coroutine.
"""
detect = None
try:
face_data = yield from self._api.call_api(
face_data = await self._api.call_api(
'post', 'detect', image, binary=True)
if not face_data:
return
face_ids = [data['faceId'] for data in face_data]
detect = yield from self._api.call_api(
detect = await self._api.call_api(
'post', 'identify',
{'faceIds': face_ids, 'personGroupId': self._face_group})

View file

@ -48,9 +48,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the OpenALPR cloud API platform."""
confidence = config[CONF_CONFIDENCE]
params = {
@ -101,8 +100,7 @@ class OpenAlprCloudEntity(ImageProcessingAlprEntity):
"""Return the name of the entity."""
return self._name
@asyncio.coroutine
def async_process_image(self, image):
async def async_process_image(self, image):
"""Process image.
This method is a coroutine.
@ -116,11 +114,11 @@ class OpenAlprCloudEntity(ImageProcessingAlprEntity):
try:
with async_timeout.timeout(self.timeout, loop=self.hass.loop):
request = yield from websession.post(
request = await websession.post(
OPENALPR_API_URL, params=params, data=body
)
data = yield from request.json()
data = await request.json()
if request.status != 200:
_LOGGER.error("Error %d -> %s.",

View file

@ -55,9 +55,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the OpenALPR local platform."""
command = [config[CONF_ALPR_BIN], '-c', config[CONF_REGION], '-']
confidence = config[CONF_CONFIDENCE]
@ -173,8 +172,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
"""Return the name of the entity."""
return self._name
@asyncio.coroutine
def async_process_image(self, image):
async def async_process_image(self, image):
"""Process image.
This method is a coroutine.
@ -182,7 +180,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
result = {}
vehicles = 0
alpr = yield from asyncio.create_subprocess_exec(
alpr = await asyncio.create_subprocess_exec(
*self._cmd,
loop=self.hass.loop,
stdin=asyncio.subprocess.PIPE,
@ -191,7 +189,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
)
# Send image
stdout, _ = yield from alpr.communicate(input=image)
stdout, _ = await alpr.communicate(input=image)
stdout = io.StringIO(str(stdout, 'utf-8'))
while True:

View file

@ -4,7 +4,6 @@ Local optical character recognition processing of seven segments displays.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/image_processing.seven_segments/
"""
import asyncio
import logging
import io
import os
@ -44,9 +43,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Seven segments OCR platform."""
entities = []
for camera in config[CONF_SOURCE]:

View file

@ -4,7 +4,6 @@ Component to offer a way to set a numeric value from a slider or text box.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_number/
"""
import asyncio
import logging
import voluptuous as vol
@ -81,8 +80,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up an input slider."""
component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -120,7 +118,7 @@ def async_setup(hass, config):
'async_decrement'
)
yield from component.async_add_entities(entities)
await component.async_add_entities(entities)
return True
@ -175,13 +173,12 @@ class InputNumber(Entity):
ATTR_MODE: self._mode,
}
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Run when entity about to be added to hass."""
if self._current_value is not None:
return
state = yield from async_get_last_state(self.hass, self.entity_id)
state = await async_get_last_state(self.hass, self.entity_id)
value = state and float(state.state)
# Check against None because value can be 0
@ -190,8 +187,7 @@ class InputNumber(Entity):
else:
self._current_value = self._minimum
@asyncio.coroutine
def async_set_value(self, value):
async def async_set_value(self, value):
"""Set new value."""
num_value = float(value)
if num_value < self._minimum or num_value > self._maximum:
@ -199,10 +195,9 @@ class InputNumber(Entity):
num_value, self._minimum, self._maximum)
return
self._current_value = num_value
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_increment(self):
async def async_increment(self):
"""Increment value."""
new_value = self._current_value + self._step
if new_value > self._maximum:
@ -210,10 +205,9 @@ class InputNumber(Entity):
new_value, self._minimum, self._maximum)
return
self._current_value = new_value
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_decrement(self):
async def async_decrement(self):
"""Decrement value."""
new_value = self._current_value - self._step
if new_value < self._minimum:
@ -221,4 +215,4 @@ class InputNumber(Entity):
new_value, self._minimum, self._maximum)
return
self._current_value = new_value
yield from self.async_update_ha_state()
await self.async_update_ha_state()

View file

@ -4,7 +4,6 @@ Component to offer a way to select an option from a list.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_select/
"""
import asyncio
import logging
import voluptuous as vol
@ -77,8 +76,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up an input select."""
component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -114,7 +112,7 @@ def async_setup(hass, config):
'async_set_options'
)
yield from component.async_add_entities(entities)
await component.async_add_entities(entities)
return True
@ -129,13 +127,12 @@ class InputSelect(Entity):
self._options = options
self._icon = icon
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Run when entity about to be added."""
if self._current_option is not None:
return
state = yield from async_get_last_state(self.hass, self.entity_id)
state = await async_get_last_state(self.hass, self.entity_id)
if not state or state.state not in self._options:
self._current_option = self._options[0]
else:
@ -168,27 +165,24 @@ class InputSelect(Entity):
ATTR_OPTIONS: self._options,
}
@asyncio.coroutine
def async_select_option(self, option):
async def async_select_option(self, option):
"""Select new option."""
if option not in self._options:
_LOGGER.warning('Invalid option: %s (possible options: %s)',
option, ', '.join(self._options))
return
self._current_option = option
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_offset_index(self, offset):
async def async_offset_index(self, offset):
"""Offset current index."""
current_index = self._options.index(self._current_option)
new_index = (current_index + offset) % len(self._options)
self._current_option = self._options[new_index]
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_set_options(self, options):
async def async_set_options(self, options):
"""Set options."""
self._current_option = options[0]
self._options = options
yield from self.async_update_ha_state()
await self.async_update_ha_state()

View file

@ -4,7 +4,6 @@ Component to offer a way to enter a value into a text box.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_text/
"""
import asyncio
import logging
import voluptuous as vol
@ -73,8 +72,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up an input text box."""
component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -102,7 +100,7 @@ def async_setup(hass, config):
'async_set_value'
)
yield from component.async_add_entities(entities)
await component.async_add_entities(entities)
return True
@ -157,25 +155,23 @@ class InputText(Entity):
ATTR_MODE: self._mode,
}
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Run when entity about to be added to hass."""
if self._current_value is not None:
return
state = yield from async_get_last_state(self.hass, self.entity_id)
state = await async_get_last_state(self.hass, self.entity_id)
value = state and state.state
# Check against None because value can be 0
if value is not None and self._minimum <= len(value) <= self._maximum:
self._current_value = value
@asyncio.coroutine
def async_set_value(self, value):
async def async_set_value(self, value):
"""Select new value."""
if len(value) < self._minimum or len(value) > self._maximum:
_LOGGER.warning("Invalid value: %s (length range %s - %s)",
value, self._minimum, self._maximum)
return
self._current_value = value
yield from self.async_update_ha_state()
await self.async_update_ha_state()