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) hass.services.call(DOMAIN, SERVICE_SEE, data)
@asyncio.coroutine async def async_setup(hass: HomeAssistantType, config: ConfigType):
def async_setup(hass: HomeAssistantType, config: ConfigType):
"""Set up the device tracker.""" """Set up the device tracker."""
yaml_path = hass.config.path(YAML_DEVICES) yaml_path = hass.config.path(YAML_DEVICES)
@ -153,14 +152,13 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
if track_new is None: if track_new is None:
track_new = defaults.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) 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( tracker = DeviceTracker(
hass, consider_home, track_new, defaults, devices) hass, consider_home, track_new, defaults, devices)
@asyncio.coroutine async def async_setup_platform(p_type, p_config, disc_info=None):
def async_setup_platform(p_type, p_config, disc_info=None):
"""Set up a device tracker platform.""" """Set up a device tracker platform."""
platform = yield from async_prepare_setup_platform( platform = await async_prepare_setup_platform(
hass, config, DOMAIN, p_type) hass, config, DOMAIN, p_type)
if platform is None: if platform is None:
return return
@ -170,16 +168,16 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
scanner = None scanner = None
setup = None setup = None
if hasattr(platform, 'async_get_scanner'): if hasattr(platform, 'async_get_scanner'):
scanner = yield from platform.async_get_scanner( scanner = await platform.async_get_scanner(
hass, {DOMAIN: p_config}) hass, {DOMAIN: p_config})
elif hasattr(platform, 'get_scanner'): 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}) platform.get_scanner, hass, {DOMAIN: p_config})
elif hasattr(platform, 'async_setup_scanner'): 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) hass, p_config, tracker.async_see, disc_info)
elif hasattr(platform, 'setup_scanner'): 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, platform.setup_scanner, hass, p_config, tracker.see,
disc_info) disc_info)
else: 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 setup_tasks = [async_setup_platform(p_type, p_config) for p_type, p_config
in config_per_platform(config, DOMAIN)] in config_per_platform(config, DOMAIN)]
if setup_tasks: if setup_tasks:
yield from asyncio.wait(setup_tasks, loop=hass.loop) await asyncio.wait(setup_tasks, loop=hass.loop)
tracker.async_setup_group() tracker.async_setup_group()
@asyncio.coroutine async def async_platform_discovered(platform, info):
def async_platform_discovered(platform, info):
"""Load a platform.""" """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) 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( async_track_utc_time_change(
hass, tracker.async_update_stale, second=range(0, 60, 5)) hass, tracker.async_update_stale, second=range(0, 60, 5))
@asyncio.coroutine async def async_see_service(call):
def async_see_service(call):
"""Service to see a device.""" """Service to see a device."""
# Temp workaround for iOS, introduced in 0.65 # Temp workaround for iOS, introduced in 0.65
data = dict(call.data) data = dict(call.data)
data.pop('hostname', None) data.pop('hostname', None)
data.pop('battery_status', None) data.pop('battery_status', None)
yield from tracker.async_see(**data) await tracker.async_see(**data)
hass.services.async_register( hass.services.async_register(
DOMAIN, SERVICE_SEE, async_see_service, SERVICE_SEE_PAYLOAD_SCHEMA) DOMAIN, SERVICE_SEE, async_see_service, SERVICE_SEE_PAYLOAD_SCHEMA)
# restore # restore
yield from tracker.async_setup_tracked_device() await tracker.async_setup_tracked_device()
return True return True
@ -269,8 +265,7 @@ class DeviceTracker:
picture, icon, consider_home) picture, icon, consider_home)
) )
@asyncio.coroutine async def async_see(
def async_see(
self, mac: str = None, dev_id: str = None, host_name: str = None, self, mac: str = None, dev_id: str = None, host_name: str = None,
location_name: str = None, gps: GPSType = None, location_name: str = None, gps: GPSType = None,
gps_accuracy: int = None, battery: int = None, gps_accuracy: int = None, battery: int = None,
@ -293,11 +288,11 @@ class DeviceTracker:
device = self.devices.get(dev_id) device = self.devices.get(dev_id)
if device: if device:
yield from device.async_seen( await device.async_seen(
host_name, location_name, gps, gps_accuracy, battery, host_name, location_name, gps, gps_accuracy, battery,
attributes, source_type, consider_home) attributes, source_type, consider_home)
if device.track: if device.track:
yield from device.async_update_ha_state() await device.async_update_ha_state()
return return
# If no device can be found, create it # If no device can be found, create it
@ -311,12 +306,12 @@ class DeviceTracker:
if mac is not None: if mac is not None:
self.mac_to_dev[mac] = device self.mac_to_dev[mac] = device
yield from device.async_seen( await device.async_seen(
host_name, location_name, gps, gps_accuracy, battery, attributes, host_name, location_name, gps, gps_accuracy, battery, attributes,
source_type) source_type)
if device.track: if device.track:
yield from device.async_update_ha_state() await device.async_update_ha_state()
# During init, we ignore the group # During init, we ignore the group
if self.group and self.track_new: if self.group and self.track_new:
@ -378,17 +373,15 @@ class DeviceTracker:
device.stale(now): device.stale(now):
self.hass.async_add_job(device.async_update_ha_state(True)) self.hass.async_add_job(device.async_update_ha_state(True))
@asyncio.coroutine async def async_setup_tracked_device(self):
def async_setup_tracked_device(self):
"""Set up all not exists tracked devices. """Set up all not exists tracked devices.
This method is a coroutine. This method is a coroutine.
""" """
@asyncio.coroutine async def async_init_single_device(dev):
def async_init_single_device(dev):
"""Init a single device_tracker entity.""" """Init a single device_tracker entity."""
yield from dev.async_added_to_hass() await dev.async_added_to_hass()
yield from dev.async_update_ha_state() await dev.async_update_ha_state()
tasks = [] tasks = []
for device in self.devices.values(): for device in self.devices.values():
@ -397,7 +390,7 @@ class DeviceTracker:
async_init_single_device(device))) async_init_single_device(device)))
if tasks: if tasks:
yield from asyncio.wait(tasks, loop=self.hass.loop) await asyncio.wait(tasks, loop=self.hass.loop)
class Device(Entity): class Device(Entity):
@ -495,8 +488,8 @@ class Device(Entity):
"""If device should be hidden.""" """If device should be hidden."""
return self.away_hide and self.state != STATE_HOME return self.away_hide and self.state != STATE_HOME
@asyncio.coroutine async def async_seen(
def async_seen(self, host_name: str = None, location_name: str = None, self, host_name: str = None, location_name: str = None,
gps: GPSType = None, gps_accuracy=0, battery: int = None, gps: GPSType = None, gps_accuracy=0, battery: int = None,
attributes: dict = None, attributes: dict = None,
source_type: str = SOURCE_TYPE_GPS, source_type: str = SOURCE_TYPE_GPS,
@ -526,7 +519,7 @@ class Device(Entity):
"Could not parse gps value for %s: %s", self.dev_id, gps) "Could not parse gps value for %s: %s", self.dev_id, gps)
# pylint: disable=not-an-iterable # pylint: disable=not-an-iterable
yield from self.async_update() await self.async_update()
def stale(self, now: dt_util.dt.datetime = None): def stale(self, now: dt_util.dt.datetime = None):
"""Return if device state is stale. """Return if device state is stale.
@ -536,8 +529,7 @@ class Device(Entity):
return self.last_seen and \ return self.last_seen and \
(now or dt_util.utcnow()) - self.last_seen > self.consider_home (now or dt_util.utcnow()) - self.last_seen > self.consider_home
@asyncio.coroutine async def async_update(self):
def async_update(self):
"""Update state of entity. """Update state of entity.
This method is a coroutine. This method is a coroutine.
@ -563,10 +555,9 @@ class Device(Entity):
self._state = STATE_HOME self._state = STATE_HOME
self.last_update_home = True self.last_update_home = True
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Add an entity.""" """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: if not state:
return return
self._state = state.state self._state = state.state
@ -629,8 +620,7 @@ def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta):
async_load_config(path, hass, consider_home), hass.loop).result() async_load_config(path, hass, consider_home), hass.loop).result()
@asyncio.coroutine async def async_load_config(path: str, hass: HomeAssistantType,
def async_load_config(path: str, hass: HomeAssistantType,
consider_home: timedelta): consider_home: timedelta):
"""Load devices from YAML configuration file. """Load devices from YAML configuration file.
@ -651,7 +641,7 @@ def async_load_config(path: str, hass: HomeAssistantType,
try: try:
result = [] result = []
try: try:
devices = yield from hass.async_add_job( devices = await hass.async_add_job(
load_yaml_config_file, path) load_yaml_config_file, path)
except HomeAssistantError as err: except HomeAssistantError as err:
_LOGGER.error("Unable to load %s: %s", path, str(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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.geofency/ https://home-assistant.io/components/device_tracker.geofency/
""" """
import asyncio
from functools import partial from functools import partial
import logging import logging
@ -58,10 +57,9 @@ class GeofencyView(HomeAssistantView):
self.see = see self.see = see
self.mobile_beacons = [slugify(beacon) for beacon in mobile_beacons] self.mobile_beacons = [slugify(beacon) for beacon in mobile_beacons]
@asyncio.coroutine async def post(self, request):
def post(self, request):
"""Handle Geofency requests.""" """Handle Geofency requests."""
data = yield from request.post() data = await request.post()
hass = request.app['hass'] hass = request.app['hass']
data = self._validate_data(data) data = self._validate_data(data)
@ -69,7 +67,7 @@ class GeofencyView(HomeAssistantView):
return ("Invalid data", HTTP_UNPROCESSABLE_ENTITY) return ("Invalid data", HTTP_UNPROCESSABLE_ENTITY)
if self._is_mobile_beacon(data): 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: if data['entry'] == LOCATION_ENTRY:
location_name = data['name'] location_name = data['name']
else: else:
@ -78,7 +76,7 @@ class GeofencyView(HomeAssistantView):
data[ATTR_LATITUDE] = data[ATTR_CURRENT_LATITUDE] data[ATTR_LATITUDE] = data[ATTR_CURRENT_LATITUDE]
data[ATTR_LONGITUDE] = data[ATTR_CURRENT_LONGITUDE] 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 @staticmethod
def _validate_data(data): def _validate_data(data):
@ -121,12 +119,11 @@ class GeofencyView(HomeAssistantView):
return "{}_{}".format(BEACON_DEV_PREFIX, data['name']) return "{}_{}".format(BEACON_DEV_PREFIX, data['name'])
return data['device'] return data['device']
@asyncio.coroutine async def _set_location(self, hass, data, location_name):
def _set_location(self, hass, data, location_name):
"""Fire HA event to set location.""" """Fire HA event to set location."""
device = self._device_name(data) device = self._device_name(data)
yield from hass.async_add_job( await hass.async_add_job(
partial(self.see, dev_id=device, partial(self.see, dev_id=device,
gps=(data[ATTR_LATITUDE], data[ATTR_LONGITUDE]), gps=(data[ATTR_LATITUDE], data[ATTR_LONGITUDE]),
location_name=location_name, 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.locative/ https://home-assistant.io/components/device_tracker.locative/
""" """
import asyncio
from functools import partial from functools import partial
import logging import logging
@ -38,21 +37,18 @@ class LocativeView(HomeAssistantView):
"""Initialize Locative URL endpoints.""" """Initialize Locative URL endpoints."""
self.see = see self.see = see
@asyncio.coroutine async def get(self, request):
def get(self, request):
"""Locative message received as GET.""" """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 return res
@asyncio.coroutine async def post(self, request):
def post(self, request):
"""Locative message received.""" """Locative message received."""
data = yield from request.post() data = await request.post()
res = yield from self._handle(request.app['hass'], data) res = await self._handle(request.app['hass'], data)
return res return res
@asyncio.coroutine async def _handle(self, hass, data):
def _handle(self, hass, data):
"""Handle locative request.""" """Handle locative request."""
if 'latitude' not in data or 'longitude' not in data: if 'latitude' not in data or 'longitude' not in data:
return ('Latitude and longitude not specified.', return ('Latitude and longitude not specified.',
@ -79,7 +75,7 @@ class LocativeView(HomeAssistantView):
gps_location = (data[ATTR_LATITUDE], data[ATTR_LONGITUDE]) gps_location = (data[ATTR_LATITUDE], data[ATTR_LONGITUDE])
if direction == 'enter': if direction == 'enter':
yield from hass.async_add_job( await hass.async_add_job(
partial(self.see, dev_id=device, location_name=location_name, partial(self.see, dev_id=device, location_name=location_name,
gps=gps_location)) gps=gps_location))
return 'Setting location to {}'.format(location_name) 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: if current_state is None or current_state.state == location_name:
location_name = STATE_NOT_HOME location_name = STATE_NOT_HOME
yield from hass.async_add_job( await hass.async_add_job(
partial(self.see, dev_id=device, partial(self.see, dev_id=device,
location_name=location_name, gps=gps_location)) location_name=location_name, gps=gps_location))
return 'Setting location to not home' 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/ https://home-assistant.io/components/device_tracker.meraki/
""" """
import asyncio
import logging import logging
import json import json
@ -33,8 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
@asyncio.coroutine async def async_setup_scanner(hass, config, async_see, discovery_info=None):
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an endpoint for the Meraki tracker.""" """Set up an endpoint for the Meraki tracker."""
hass.http.register_view( hass.http.register_view(
MerakiView(config, async_see)) MerakiView(config, async_see))
@ -54,16 +52,14 @@ class MerakiView(HomeAssistantView):
self.validator = config[CONF_VALIDATOR] self.validator = config[CONF_VALIDATOR]
self.secret = config[CONF_SECRET] self.secret = config[CONF_SECRET]
@asyncio.coroutine async def get(self, request):
def get(self, request):
"""Meraki message received as GET.""" """Meraki message received as GET."""
return self.validator return self.validator
@asyncio.coroutine async def post(self, request):
def post(self, request):
"""Meraki CMX message received.""" """Meraki CMX message received."""
try: try:
data = yield from request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message('Invalid JSON', HTTP_BAD_REQUEST) return self.json_message('Invalid JSON', HTTP_BAD_REQUEST)
_LOGGER.debug("Meraki Data from Post: %s", json.dumps(data)) _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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.mqtt/ https://home-assistant.io/components/device_tracker.mqtt/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -25,8 +24,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend({
}) })
@asyncio.coroutine async def async_setup_scanner(hass, config, async_see, discovery_info=None):
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up the MQTT tracker.""" """Set up the MQTT tracker."""
devices = config[CONF_DEVICES] devices = config[CONF_DEVICES]
qos = config[CONF_QOS] qos = config[CONF_QOS]
@ -38,7 +36,7 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
hass.async_add_job( hass.async_add_job(
async_see(dev_id=dev_id, location_name=payload)) async_see(dev_id=dev_id, location_name=payload))
yield from mqtt.async_subscribe( await mqtt.async_subscribe(
hass, topic, async_message_received, qos) hass, topic, async_message_received, qos)
return True 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.mqtt_json/ https://home-assistant.io/components/device_tracker.mqtt_json/
""" """
import asyncio
import json import json
import logging import logging
@ -35,8 +34,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend({
}) })
@asyncio.coroutine async def async_setup_scanner(hass, config, async_see, discovery_info=None):
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up the MQTT JSON tracker.""" """Set up the MQTT JSON tracker."""
devices = config[CONF_DEVICES] devices = config[CONF_DEVICES]
qos = config[CONF_QOS] 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) kwargs = _parse_see_args(dev_id, data)
hass.async_add_job(async_see(**kwargs)) hass.async_add_job(async_see(**kwargs))
yield from mqtt.async_subscribe( await mqtt.async_subscribe(
hass, topic, async_message_received, qos) hass, topic, async_message_received, qos)
return True 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks/ https://home-assistant.io/components/device_tracker.owntracks/
""" """
import asyncio
import base64 import base64
import json import json
import logging import logging
@ -73,13 +72,11 @@ def get_cipher():
return (KEYLEN, decrypt) return (KEYLEN, decrypt)
@asyncio.coroutine async def async_setup_scanner(hass, config, async_see, discovery_info=None):
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker.""" """Set up an OwnTracks tracker."""
context = context_from_config(async_see, config) context = context_from_config(async_see, config)
@asyncio.coroutine async def async_handle_mqtt_message(topic, payload, qos):
def async_handle_mqtt_message(topic, payload, qos):
"""Handle incoming OwnTracks message.""" """Handle incoming OwnTracks message."""
try: try:
message = json.loads(payload) message = json.loads(payload)
@ -90,9 +87,9 @@ def async_setup_scanner(hass, config, async_see, discovery_info=None):
message['topic'] = topic 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) hass, context.mqtt_topic, async_handle_mqtt_message, 1)
return True return True
@ -266,8 +263,7 @@ class OwnTracksContext:
return True return True
@asyncio.coroutine async def async_see_beacons(self, hass, dev_id, kwargs_param):
def async_see_beacons(self, hass, dev_id, kwargs_param):
"""Set active beacons to the current location.""" """Set active beacons to the current location."""
kwargs = kwargs_param.copy() kwargs = kwargs_param.copy()
@ -290,12 +286,11 @@ class OwnTracksContext:
for beacon in self.mobile_beacons_active[dev_id]: for beacon in self.mobile_beacons_active[dev_id]:
kwargs['dev_id'] = "{}_{}".format(BEACON_DEV_ID, beacon) kwargs['dev_id'] = "{}_{}".format(BEACON_DEV_ID, beacon)
kwargs['host_name'] = beacon kwargs['host_name'] = beacon
yield from self.async_see(**kwargs) await self.async_see(**kwargs)
@HANDLERS.register('location') @HANDLERS.register('location')
@asyncio.coroutine async def async_handle_location_message(hass, context, message):
def async_handle_location_message(hass, context, message):
"""Handle a location message.""" """Handle a location message."""
if not context.async_valid_accuracy(message): if not context.async_valid_accuracy(message):
return return
@ -312,12 +307,11 @@ def async_handle_location_message(hass, context, message):
context.regions_entered[-1]) context.regions_entered[-1])
return return
yield from context.async_see(**kwargs) await context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs) await context.async_see_beacons(hass, dev_id, kwargs)
@asyncio.coroutine async def _async_transition_message_enter(hass, context, message, location):
def _async_transition_message_enter(hass, context, message, location):
"""Execute enter event.""" """Execute enter event."""
zone = hass.states.get("zone.{}".format(slugify(location))) zone = hass.states.get("zone.{}".format(slugify(location)))
dev_id, kwargs = _parse_see_args(message, context.mqtt_topic) 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: if location not in beacons:
beacons.add(location) beacons.add(location)
_LOGGER.info("Added beacon %s", 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: else:
# Normal region # Normal region
regions = context.regions_entered[dev_id] regions = context.regions_entered[dev_id]
@ -339,12 +333,11 @@ def _async_transition_message_enter(hass, context, message, location):
regions.append(location) regions.append(location)
_LOGGER.info("Enter region %s", location) _LOGGER.info("Enter region %s", location)
_set_gps_from_zone(kwargs, location, zone) _set_gps_from_zone(kwargs, location, zone)
yield from context.async_see(**kwargs) await context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs) await context.async_see_beacons(hass, dev_id, kwargs)
@asyncio.coroutine async def _async_transition_message_leave(hass, context, message, location):
def _async_transition_message_leave(hass, context, message, location):
"""Execute leave event.""" """Execute leave event."""
dev_id, kwargs = _parse_see_args(message, context.mqtt_topic) dev_id, kwargs = _parse_see_args(message, context.mqtt_topic)
regions = context.regions_entered[dev_id] regions = context.regions_entered[dev_id]
@ -356,7 +349,7 @@ def _async_transition_message_leave(hass, context, message, location):
if location in beacons: if location in beacons:
beacons.remove(location) beacons.remove(location)
_LOGGER.info("Remove beacon %s", 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: else:
new_region = regions[-1] if regions else None new_region = regions[-1] if regions else None
if new_region: if new_region:
@ -365,21 +358,20 @@ def _async_transition_message_leave(hass, context, message, location):
"zone.{}".format(slugify(new_region))) "zone.{}".format(slugify(new_region)))
_set_gps_from_zone(kwargs, new_region, zone) _set_gps_from_zone(kwargs, new_region, zone)
_LOGGER.info("Exit to %s", new_region) _LOGGER.info("Exit to %s", new_region)
yield from context.async_see(**kwargs) await context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs) await context.async_see_beacons(hass, dev_id, kwargs)
return return
_LOGGER.info("Exit to GPS") _LOGGER.info("Exit to GPS")
# Check for GPS accuracy # Check for GPS accuracy
if context.async_valid_accuracy(message): if context.async_valid_accuracy(message):
yield from context.async_see(**kwargs) await context.async_see(**kwargs)
yield from context.async_see_beacons(hass, dev_id, kwargs) await context.async_see_beacons(hass, dev_id, kwargs)
@HANDLERS.register('transition') @HANDLERS.register('transition')
@asyncio.coroutine async def async_handle_transition_message(hass, context, message):
def async_handle_transition_message(hass, context, message):
"""Handle a transition message.""" """Handle a transition message."""
if message.get('desc') is None: if message.get('desc') is None:
_LOGGER.error( _LOGGER.error(
@ -399,10 +391,10 @@ def async_handle_transition_message(hass, context, message):
location = STATE_HOME location = STATE_HOME
if message['event'] == 'enter': if message['event'] == 'enter':
yield from _async_transition_message_enter( await _async_transition_message_enter(
hass, context, message, location) hass, context, message, location)
elif message['event'] == 'leave': elif message['event'] == 'leave':
yield from _async_transition_message_leave( await _async_transition_message_leave(
hass, context, message, location) hass, context, message, location)
else: else:
_LOGGER.error( _LOGGER.error(
@ -410,8 +402,7 @@ def async_handle_transition_message(hass, context, message):
message['event']) message['event'])
@asyncio.coroutine async def async_handle_waypoint(hass, name_base, waypoint):
def async_handle_waypoint(hass, name_base, waypoint):
"""Handle a waypoint.""" """Handle a waypoint."""
name = waypoint['desc'] name = waypoint['desc']
pretty_name = '{} - {}'.format(name_base, name) 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 = zone_comp.Zone(hass, pretty_name, lat, lon, rad,
zone_comp.ICON_IMPORT, False) zone_comp.ICON_IMPORT, False)
zone.entity_id = entity_id zone.entity_id = entity_id
yield from zone.async_update_ha_state() await zone.async_update_ha_state()
@HANDLERS.register('waypoint') @HANDLERS.register('waypoint')
@HANDLERS.register('waypoints') @HANDLERS.register('waypoints')
@asyncio.coroutine async def async_handle_waypoints_message(hass, context, message):
def async_handle_waypoints_message(hass, context, message):
"""Handle a waypoints message.""" """Handle a waypoints message."""
if not context.import_waypoints: if not context.import_waypoints:
return return
@ -456,12 +446,11 @@ def async_handle_waypoints_message(hass, context, message):
name_base = ' '.join(_parse_topic(message['topic'], context.mqtt_topic)) name_base = ' '.join(_parse_topic(message['topic'], context.mqtt_topic))
for wayp in wayps: for wayp in wayps:
yield from async_handle_waypoint(hass, name_base, wayp) await async_handle_waypoint(hass, name_base, wayp)
@HANDLERS.register('encrypted') @HANDLERS.register('encrypted')
@asyncio.coroutine async def async_handle_encrypted_message(hass, context, message):
def async_handle_encrypted_message(hass, context, message):
"""Handle an encrypted message.""" """Handle an encrypted message."""
plaintext_payload = _decrypt_payload(context.secret, message['topic'], plaintext_payload = _decrypt_payload(context.secret, message['topic'],
message['data']) message['data'])
@ -472,7 +461,7 @@ def async_handle_encrypted_message(hass, context, message):
decrypted = json.loads(plaintext_payload) decrypted = json.loads(plaintext_payload)
decrypted['topic'] = message['topic'] decrypted['topic'] = message['topic']
yield from async_handle_message(hass, context, decrypted) await async_handle_message(hass, context, decrypted)
@HANDLERS.register('lwt') @HANDLERS.register('lwt')
@ -481,24 +470,21 @@ def async_handle_encrypted_message(hass, context, message):
@HANDLERS.register('cmd') @HANDLERS.register('cmd')
@HANDLERS.register('steps') @HANDLERS.register('steps')
@HANDLERS.register('card') @HANDLERS.register('card')
@asyncio.coroutine async def async_handle_not_impl_msg(hass, context, message):
def async_handle_not_impl_msg(hass, context, message):
"""Handle valid but not implemented message types.""" """Handle valid but not implemented message types."""
_LOGGER.debug('Not handling %s message: %s', message.get("_type"), message) _LOGGER.debug('Not handling %s message: %s', message.get("_type"), message)
@asyncio.coroutine async def async_handle_unsupported_msg(hass, context, message):
def async_handle_unsupported_msg(hass, context, message):
"""Handle an unsupported or invalid message type.""" """Handle an unsupported or invalid message type."""
_LOGGER.warning('Received unsupported message type: %s.', _LOGGER.warning('Received unsupported message type: %s.',
message.get('_type')) message.get('_type'))
@asyncio.coroutine async def async_handle_message(hass, context, message):
def async_handle_message(hass, context, message):
"""Handle an OwnTracks message.""" """Handle an OwnTracks message."""
msgtype = message.get('_type') msgtype = message.get('_type')
handler = HANDLERS.get(msgtype, async_handle_unsupported_msg) 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks_http/ https://home-assistant.io/components/device_tracker.owntracks_http/
""" """
import asyncio
import re import re
from aiohttp.web_exceptions import HTTPInternalServerError from aiohttp.web_exceptions import HTTPInternalServerError
@ -19,8 +18,7 @@ from .owntracks import ( # NOQA
DEPENDENCIES = ['http'] DEPENDENCIES = ['http']
@asyncio.coroutine async def async_setup_scanner(hass, config, async_see, discovery_info=None):
def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up an OwnTracks tracker.""" """Set up an OwnTracks tracker."""
context = context_from_config(async_see, config) context = context_from_config(async_see, config)
@ -39,19 +37,18 @@ class OwnTracksView(HomeAssistantView):
"""Initialize OwnTracks URL endpoints.""" """Initialize OwnTracks URL endpoints."""
self.context = context self.context = context
@asyncio.coroutine async def post(self, request, user, device):
def post(self, request, user, device):
"""Handle an OwnTracks message.""" """Handle an OwnTracks message."""
hass = request.app['hass'] hass = request.app['hass']
subscription = self.context.mqtt_topic subscription = self.context.mqtt_topic
topic = re.sub('/#$', '', subscription) topic = re.sub('/#$', '', subscription)
message = yield from request.json() message = await request.json()
message['topic'] = '{}/{}/{}'.format(topic, user, device) message['topic'] = '{}/{}/{}'.format(topic, user, device)
try: try:
yield from async_handle_message(hass, self.context, message) await async_handle_message(hass, self.context, message)
return self.json([]) return self.json([])
except ValueError: except ValueError:

View file

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

View file

@ -3,7 +3,6 @@
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/fan.dyson/ https://home-assistant.io/components/fan.dyson/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -77,8 +76,7 @@ class DysonPureCoolLinkDevice(FanEntity):
self.hass = hass self.hass = hass
self._device = device self._device = device
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Call when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.async_add_job( self.hass.async_add_job(
self._device.add_message_listener, self.on_message) 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 For more details about this component, please refer to the documentation at
https://home-assistant.io/components/fan.insteon/ https://home-assistant.io/components/fan.insteon/
""" """
import asyncio
import logging import logging
from homeassistant.components.fan import (SPEED_OFF, from homeassistant.components.fan import (SPEED_OFF,
@ -28,8 +27,7 @@ FAN_SPEEDS = [STATE_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_entities,
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None): discovery_info=None):
"""Set up the INSTEON device class for the hass platform.""" """Set up the INSTEON device class for the hass platform."""
insteon_modem = hass.data['insteon'].get('modem') insteon_modem = hass.data['insteon'].get('modem')
@ -64,20 +62,17 @@ class InsteonFan(InsteonEntity, FanEntity):
"""Flag supported features.""" """Flag supported features."""
return SUPPORT_SET_SPEED return SUPPORT_SET_SPEED
@asyncio.coroutine async def async_turn_on(self, speed: str = None, **kwargs) -> None:
def async_turn_on(self, speed: str = None, **kwargs) -> None:
"""Turn on the entity.""" """Turn on the entity."""
if speed is None: if speed is None:
speed = SPEED_MEDIUM speed = SPEED_MEDIUM
yield from self.async_set_speed(speed) await self.async_set_speed(speed)
@asyncio.coroutine async def async_turn_off(self, **kwargs) -> None:
def async_turn_off(self, **kwargs) -> None:
"""Turn off the entity.""" """Turn off the entity."""
yield from self.async_set_speed(SPEED_OFF) await self.async_set_speed(SPEED_OFF)
@asyncio.coroutine async def async_set_speed(self, speed: str) -> None:
def async_set_speed(self, speed: str) -> None:
"""Set the speed of the fan.""" """Set the speed of the fan."""
fan_speed = SPEED_TO_HEX[speed] fan_speed = SPEED_TO_HEX[speed]
if fan_speed == 0x00: 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/fan.wink/ https://home-assistant.io/components/fan.wink/
""" """
import asyncio
import logging import logging
from homeassistant.components.fan import ( from homeassistant.components.fan import (
@ -33,8 +32,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class WinkFanDevice(WinkDevice, FanEntity): class WinkFanDevice(WinkDevice, FanEntity):
"""Representation of a Wink fan.""" """Representation of a Wink fan."""
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Call when entity is added to hass.""" """Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['fan'].append(self) 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/hassio/ https://home-assistant.io/components/hassio/
""" """
import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
import os import os
@ -134,11 +133,10 @@ def is_hassio(hass):
@bind_hass @bind_hass
@asyncio.coroutine async def async_check_config(hass):
def async_check_config(hass):
"""Check configuration over Hass.io API.""" """Check configuration over Hass.io API."""
hassio = hass.data[DOMAIN] hassio = hass.data[DOMAIN]
result = yield from hassio.check_homeassistant_config() result = await hassio.check_homeassistant_config()
if not result: if not result:
return "Hass.io config check API error" return "Hass.io config check API error"
@ -147,8 +145,7 @@ def async_check_config(hass):
return None return None
@asyncio.coroutine async def async_setup(hass, config):
def async_setup(hass, config):
"""Set up the Hass.io component.""" """Set up the Hass.io component."""
try: try:
host = os.environ['HASSIO'] host = os.environ['HASSIO']
@ -165,27 +162,27 @@ def async_setup(hass, config):
websession = hass.helpers.aiohttp_client.async_get_clientsession() websession = hass.helpers.aiohttp_client.async_get_clientsession()
hass.data[DOMAIN] = hassio = HassIO(hass.loop, websession, host) 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") _LOGGER.error("Not connected with Hass.io")
return False return False
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
data = yield from store.async_load() data = await store.async_load()
if data is None: if data is None:
data = {} data = {}
refresh_token = None refresh_token = None
if 'hassio_user' in data: 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: if user and user.refresh_tokens:
refresh_token = list(user.refresh_tokens.values())[0] refresh_token = list(user.refresh_tokens.values())[0]
if refresh_token is None: if refresh_token is None:
user = yield from hass.auth.async_create_system_user('Hass.io') user = await hass.auth.async_create_system_user('Hass.io')
refresh_token = yield from hass.auth.async_create_refresh_token(user) refresh_token = await hass.auth.async_create_refresh_token(user)
data['hassio_user'] = user.id 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 # This overrides the normal API call that would be forwarded
development_repo = config.get(DOMAIN, {}).get(CONF_FRONTEND_REPO) 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)) hass.http.register_view(HassIOView(host, websession))
if 'frontend' in hass.config.components: 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', frontend_url_path='hassio',
webcomponent_name='hassio-main', webcomponent_name='hassio-main',
sidebar_title='Hass.io', sidebar_title='Hass.io',
@ -212,13 +209,12 @@ def async_setup(hass, config):
else: else:
token = None 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: if 'homeassistant' in config:
yield from hassio.update_hass_timezone(config['homeassistant']) await hassio.update_hass_timezone(config['homeassistant'])
@asyncio.coroutine async def async_service_handler(service):
def async_service_handler(service):
"""Handle service calls for Hass.io.""" """Handle service calls for Hass.io."""
api_command = MAP_SERVICE_API[service.service][0] api_command = MAP_SERVICE_API[service.service][0]
data = service.data.copy() data = service.data.copy()
@ -233,7 +229,7 @@ def async_setup(hass, config):
payload = data payload = data
# Call API # Call API
ret = yield from hassio.send_command( ret = await hassio.send_command(
api_command.format(addon=addon, snapshot=snapshot), api_command.format(addon=addon, snapshot=snapshot),
payload=payload, timeout=MAP_SERVICE_API[service.service][2] payload=payload, timeout=MAP_SERVICE_API[service.service][2]
) )
@ -245,10 +241,9 @@ def async_setup(hass, config):
hass.services.async_register( hass.services.async_register(
DOMAIN, service, async_service_handler, schema=settings[1]) DOMAIN, service, async_service_handler, schema=settings[1])
@asyncio.coroutine async def update_homeassistant_version(now):
def update_homeassistant_version(now):
"""Update last available Home Assistant version.""" """Update last available Home Assistant version."""
data = yield from hassio.get_homeassistant_info() data = await hassio.get_homeassistant_info()
if data: if data:
hass.data[DATA_HOMEASSISTANT_VERSION] = data['last_version'] hass.data[DATA_HOMEASSISTANT_VERSION] = data['last_version']
@ -256,16 +251,15 @@ def async_setup(hass, config):
update_homeassistant_version, utcnow() + HASSIO_UPDATE_INTERVAL) update_homeassistant_version, utcnow() + HASSIO_UPDATE_INTERVAL)
# Fetch last version # Fetch last version
yield from update_homeassistant_version(None) await update_homeassistant_version(None)
@asyncio.coroutine async def async_handle_core_service(call):
def async_handle_core_service(call):
"""Service handler for handling core services.""" """Service handler for handling core services."""
if call.service == SERVICE_HOMEASSISTANT_STOP: if call.service == SERVICE_HOMEASSISTANT_STOP:
yield from hassio.stop_homeassistant() await hassio.stop_homeassistant()
return return
error = yield from async_check_config(hass) error = await async_check_config(hass)
if error: if error:
_LOGGER.error(error) _LOGGER.error(error)
hass.components.persistent_notification.async_create( hass.components.persistent_notification.async_create(
@ -274,7 +268,7 @@ def async_setup(hass, config):
return return
if call.service == SERVICE_HOMEASSISTANT_RESTART: if call.service == SERVICE_HOMEASSISTANT_RESTART:
yield from hassio.restart_homeassistant() await hassio.restart_homeassistant()
# Mock core services # Mock core services
for service in (SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART, for service in (SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART,

View file

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

View file

@ -54,15 +54,14 @@ class HassIOView(HomeAssistantView):
self._host = host self._host = host
self._websession = websession self._websession = websession
@asyncio.coroutine async def _handle(self, request, path):
def _handle(self, request, path):
"""Route data to Hass.io.""" """Route data to Hass.io."""
if _need_auth(path) and not request[KEY_AUTHENTICATED]: if _need_auth(path) and not request[KEY_AUTHENTICATED]:
return web.Response(status=401) 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'): if path.endswith('/logs'):
return _create_response_log(client, data) return _create_response_log(client, data)
return _create_response(client, data) return _create_response(client, data)
@ -70,8 +69,7 @@ class HassIOView(HomeAssistantView):
get = _handle get = _handle
post = _handle post = _handle
@asyncio.coroutine async def _command_proxy(self, path, request):
def _command_proxy(self, path, request):
"""Return a client request with proxy origin for Hass.io supervisor. """Return a client request with proxy origin for Hass.io supervisor.
This method is a coroutine. This method is a coroutine.
@ -83,14 +81,14 @@ class HassIOView(HomeAssistantView):
data = None data = None
headers = {X_HASSIO: os.environ.get('HASSIO_TOKEN', "")} headers = {X_HASSIO: os.environ.get('HASSIO_TOKEN', "")}
with async_timeout.timeout(10, loop=hass.loop): with async_timeout.timeout(10, loop=hass.loop):
data = yield from request.read() data = await request.read()
if data: if data:
headers[CONTENT_TYPE] = request.content_type headers[CONTENT_TYPE] = request.content_type
else: else:
data = None data = None
method = getattr(self._websession, request.method.lower()) method = getattr(self._websession, request.method.lower())
client = yield from method( client = await method(
"http://{}/{}".format(self._host, path), data=data, "http://{}/{}".format(self._host, path), data=data,
headers=headers, timeout=read_timeout 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/image_processing.microsoft_face_detect/ https://home-assistant.io/components/image_processing.microsoft_face_detect/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -45,8 +44,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_entities,
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None): discovery_info=None):
"""Set up the Microsoft Face detection platform.""" """Set up the Microsoft Face detection platform."""
api = hass.data[DATA_MICROSOFT_FACE] api = hass.data[DATA_MICROSOFT_FACE]
@ -88,15 +86,14 @@ class MicrosoftFaceDetectEntity(ImageProcessingFaceEntity):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._name return self._name
@asyncio.coroutine async def async_process_image(self, image):
def async_process_image(self, image):
"""Process image. """Process image.
This method is a coroutine. This method is a coroutine.
""" """
face_data = None face_data = None
try: try:
face_data = yield from self._api.call_api( face_data = await self._api.call_api(
'post', 'detect', image, binary=True, 'post', 'detect', image, binary=True,
params={'returnFaceAttributes': ",".join(self._attributes)}) 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 For more details about this component, please refer to the documentation at
https://home-assistant.io/components/image_processing.microsoft_face_identify/ https://home-assistant.io/components/image_processing.microsoft_face_identify/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -29,8 +28,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_entities,
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None): discovery_info=None):
"""Set up the Microsoft Face identify platform.""" """Set up the Microsoft Face identify platform."""
api = hass.data[DATA_MICROSOFT_FACE] api = hass.data[DATA_MICROSOFT_FACE]
@ -80,22 +78,21 @@ class MicrosoftFaceIdentifyEntity(ImageProcessingFaceEntity):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._name return self._name
@asyncio.coroutine async def async_process_image(self, image):
def async_process_image(self, image):
"""Process image. """Process image.
This method is a coroutine. This method is a coroutine.
""" """
detect = None detect = None
try: try:
face_data = yield from self._api.call_api( face_data = await self._api.call_api(
'post', 'detect', image, binary=True) 'post', 'detect', image, binary=True)
if not face_data: if not face_data:
return return
face_ids = [data['faceId'] for data in face_data] face_ids = [data['faceId'] for data in face_data]
detect = yield from self._api.call_api( detect = await self._api.call_api(
'post', 'identify', 'post', 'identify',
{'faceIds': face_ids, 'personGroupId': self._face_group}) {'faceIds': face_ids, 'personGroupId': self._face_group})

View file

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

View file

@ -55,8 +55,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_entities,
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None): discovery_info=None):
"""Set up the OpenALPR local platform.""" """Set up the OpenALPR local platform."""
command = [config[CONF_ALPR_BIN], '-c', config[CONF_REGION], '-'] command = [config[CONF_ALPR_BIN], '-c', config[CONF_REGION], '-']
@ -173,8 +172,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._name return self._name
@asyncio.coroutine async def async_process_image(self, image):
def async_process_image(self, image):
"""Process image. """Process image.
This method is a coroutine. This method is a coroutine.
@ -182,7 +180,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
result = {} result = {}
vehicles = 0 vehicles = 0
alpr = yield from asyncio.create_subprocess_exec( alpr = await asyncio.create_subprocess_exec(
*self._cmd, *self._cmd,
loop=self.hass.loop, loop=self.hass.loop,
stdin=asyncio.subprocess.PIPE, stdin=asyncio.subprocess.PIPE,
@ -191,7 +189,7 @@ class OpenAlprLocalEntity(ImageProcessingAlprEntity):
) )
# Send image # Send image
stdout, _ = yield from alpr.communicate(input=image) stdout, _ = await alpr.communicate(input=image)
stdout = io.StringIO(str(stdout, 'utf-8')) stdout = io.StringIO(str(stdout, 'utf-8'))
while True: 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 For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/image_processing.seven_segments/ https://home-assistant.io/components/image_processing.seven_segments/
""" """
import asyncio
import logging import logging
import io import io
import os import os
@ -44,8 +43,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
}) })
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_entities,
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None): discovery_info=None):
"""Set up the Seven segments OCR platform.""" """Set up the Seven segments OCR platform."""
entities = [] entities = []

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 For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_number/ at https://home-assistant.io/components/input_number/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -81,8 +80,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA) }, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine async def async_setup(hass, config):
def async_setup(hass, config):
"""Set up an input slider.""" """Set up an input slider."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -120,7 +118,7 @@ def async_setup(hass, config):
'async_decrement' 'async_decrement'
) )
yield from component.async_add_entities(entities) await component.async_add_entities(entities)
return True return True
@ -175,13 +173,12 @@ class InputNumber(Entity):
ATTR_MODE: self._mode, ATTR_MODE: self._mode,
} }
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Run when entity about to be added to hass.""" """Run when entity about to be added to hass."""
if self._current_value is not None: if self._current_value is not None:
return 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) value = state and float(state.state)
# Check against None because value can be 0 # Check against None because value can be 0
@ -190,8 +187,7 @@ class InputNumber(Entity):
else: else:
self._current_value = self._minimum self._current_value = self._minimum
@asyncio.coroutine async def async_set_value(self, value):
def async_set_value(self, value):
"""Set new value.""" """Set new value."""
num_value = float(value) num_value = float(value)
if num_value < self._minimum or num_value > self._maximum: if num_value < self._minimum or num_value > self._maximum:
@ -199,10 +195,9 @@ class InputNumber(Entity):
num_value, self._minimum, self._maximum) num_value, self._minimum, self._maximum)
return return
self._current_value = num_value self._current_value = num_value
yield from self.async_update_ha_state() await self.async_update_ha_state()
@asyncio.coroutine async def async_increment(self):
def async_increment(self):
"""Increment value.""" """Increment value."""
new_value = self._current_value + self._step new_value = self._current_value + self._step
if new_value > self._maximum: if new_value > self._maximum:
@ -210,10 +205,9 @@ class InputNumber(Entity):
new_value, self._minimum, self._maximum) new_value, self._minimum, self._maximum)
return return
self._current_value = new_value self._current_value = new_value
yield from self.async_update_ha_state() await self.async_update_ha_state()
@asyncio.coroutine async def async_decrement(self):
def async_decrement(self):
"""Decrement value.""" """Decrement value."""
new_value = self._current_value - self._step new_value = self._current_value - self._step
if new_value < self._minimum: if new_value < self._minimum:
@ -221,4 +215,4 @@ class InputNumber(Entity):
new_value, self._minimum, self._maximum) new_value, self._minimum, self._maximum)
return return
self._current_value = new_value 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 For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_select/ at https://home-assistant.io/components/input_select/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -77,8 +76,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA) }, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine async def async_setup(hass, config):
def async_setup(hass, config):
"""Set up an input select.""" """Set up an input select."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -114,7 +112,7 @@ def async_setup(hass, config):
'async_set_options' 'async_set_options'
) )
yield from component.async_add_entities(entities) await component.async_add_entities(entities)
return True return True
@ -129,13 +127,12 @@ class InputSelect(Entity):
self._options = options self._options = options
self._icon = icon self._icon = icon
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Run when entity about to be added.""" """Run when entity about to be added."""
if self._current_option is not None: if self._current_option is not None:
return 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: if not state or state.state not in self._options:
self._current_option = self._options[0] self._current_option = self._options[0]
else: else:
@ -168,27 +165,24 @@ class InputSelect(Entity):
ATTR_OPTIONS: self._options, ATTR_OPTIONS: self._options,
} }
@asyncio.coroutine async def async_select_option(self, option):
def async_select_option(self, option):
"""Select new option.""" """Select new option."""
if option not in self._options: if option not in self._options:
_LOGGER.warning('Invalid option: %s (possible options: %s)', _LOGGER.warning('Invalid option: %s (possible options: %s)',
option, ', '.join(self._options)) option, ', '.join(self._options))
return return
self._current_option = option self._current_option = option
yield from self.async_update_ha_state() await self.async_update_ha_state()
@asyncio.coroutine async def async_offset_index(self, offset):
def async_offset_index(self, offset):
"""Offset current index.""" """Offset current index."""
current_index = self._options.index(self._current_option) current_index = self._options.index(self._current_option)
new_index = (current_index + offset) % len(self._options) new_index = (current_index + offset) % len(self._options)
self._current_option = self._options[new_index] self._current_option = self._options[new_index]
yield from self.async_update_ha_state() await self.async_update_ha_state()
@asyncio.coroutine async def async_set_options(self, options):
def async_set_options(self, options):
"""Set options.""" """Set options."""
self._current_option = options[0] self._current_option = options[0]
self._options = options 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 For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_text/ at https://home-assistant.io/components/input_text/
""" """
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -73,8 +72,7 @@ CONFIG_SCHEMA = vol.Schema({
}, required=True, extra=vol.ALLOW_EXTRA) }, required=True, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine async def async_setup(hass, config):
def async_setup(hass, config):
"""Set up an input text box.""" """Set up an input text box."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -102,7 +100,7 @@ def async_setup(hass, config):
'async_set_value' 'async_set_value'
) )
yield from component.async_add_entities(entities) await component.async_add_entities(entities)
return True return True
@ -157,25 +155,23 @@ class InputText(Entity):
ATTR_MODE: self._mode, ATTR_MODE: self._mode,
} }
@asyncio.coroutine async def async_added_to_hass(self):
def async_added_to_hass(self):
"""Run when entity about to be added to hass.""" """Run when entity about to be added to hass."""
if self._current_value is not None: if self._current_value is not None:
return 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 value = state and state.state
# Check against None because value can be 0 # Check against None because value can be 0
if value is not None and self._minimum <= len(value) <= self._maximum: if value is not None and self._minimum <= len(value) <= self._maximum:
self._current_value = value self._current_value = value
@asyncio.coroutine async def async_set_value(self, value):
def async_set_value(self, value):
"""Select new value.""" """Select new value."""
if len(value) < self._minimum or len(value) > self._maximum: if len(value) < self._minimum or len(value) > self._maximum:
_LOGGER.warning("Invalid value: %s (length range %s - %s)", _LOGGER.warning("Invalid value: %s (length range %s - %s)",
value, self._minimum, self._maximum) value, self._minimum, self._maximum)
return return
self._current_value = value self._current_value = value
yield from self.async_update_ha_state() await self.async_update_ha_state()