Async syntax 3/8 (#17017)
* Async syntax 3, device_tracker & fan & hassio & image_processing & input * Pylint fixes
This commit is contained in:
parent
134eeecd65
commit
b24f9f5dfa
23 changed files with 194 additions and 286 deletions
|
@ -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))
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)})
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
|
|
||||||
|
|
|
@ -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.",
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue