Async syntax 2, camera & climate & config (#17016)
This commit is contained in:
parent
38e371c5d9
commit
8444b9ba03
22 changed files with 119 additions and 194 deletions
|
@ -4,7 +4,6 @@ This component provides HA camera support for Abode Security System.
|
||||||
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/camera.abode/
|
https://home-assistant.io/components/camera.abode/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
@ -51,10 +50,9 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||||
self._event = event
|
self._event = event
|
||||||
self._response = None
|
self._response = None
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_added_to_hass(self):
|
||||||
def async_added_to_hass(self):
|
|
||||||
"""Subscribe Abode events."""
|
"""Subscribe Abode events."""
|
||||||
yield from super().async_added_to_hass()
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
self.hass.async_add_job(
|
self.hass.async_add_job(
|
||||||
self._data.abode.events.add_timeline_callback,
|
self._data.abode.events.add_timeline_callback,
|
||||||
|
|
|
@ -4,7 +4,6 @@ This component provides basic support for Amcrest IP cameras.
|
||||||
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/camera.amcrest/
|
https://home-assistant.io/components/camera.amcrest/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.components.amcrest import (
|
from homeassistant.components.amcrest import (
|
||||||
|
@ -21,9 +20,8 @@ DEPENDENCIES = ['amcrest', 'ffmpeg']
|
||||||
_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 an Amcrest IP Camera."""
|
"""Set up an Amcrest IP Camera."""
|
||||||
if discovery_info is None:
|
if discovery_info is None:
|
||||||
return
|
return
|
||||||
|
@ -57,12 +55,11 @@ class AmcrestCam(Camera):
|
||||||
response = self._camera.snapshot(channel=self._resolution)
|
response = self._camera.snapshot(channel=self._resolution)
|
||||||
return response.data
|
return response.data
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def handle_async_mjpeg_stream(self, request):
|
||||||
def handle_async_mjpeg_stream(self, request):
|
|
||||||
"""Return an MJPEG stream."""
|
"""Return an MJPEG stream."""
|
||||||
# The snapshot implementation is handled by the parent class
|
# The snapshot implementation is handled by the parent class
|
||||||
if self._stream_source == STREAM_SOURCE_LIST['snapshot']:
|
if self._stream_source == STREAM_SOURCE_LIST['snapshot']:
|
||||||
yield from super().handle_async_mjpeg_stream(request)
|
await super().handle_async_mjpeg_stream(request)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._stream_source == STREAM_SOURCE_LIST['mjpeg']:
|
if self._stream_source == STREAM_SOURCE_LIST['mjpeg']:
|
||||||
|
@ -72,7 +69,7 @@ class AmcrestCam(Camera):
|
||||||
stream_coro = websession.get(
|
stream_coro = websession.get(
|
||||||
streaming_url, auth=self._token, timeout=TIMEOUT)
|
streaming_url, auth=self._token, timeout=TIMEOUT)
|
||||||
|
|
||||||
yield from async_aiohttp_proxy_web(self.hass, request, stream_coro)
|
await async_aiohttp_proxy_web(self.hass, request, stream_coro)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# streaming via fmpeg
|
# streaming via fmpeg
|
||||||
|
@ -80,13 +77,13 @@ class AmcrestCam(Camera):
|
||||||
|
|
||||||
streaming_url = self._camera.rtsp_url(typeno=self._resolution)
|
streaming_url = self._camera.rtsp_url(typeno=self._resolution)
|
||||||
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
yield from stream.open_camera(
|
await stream.open_camera(
|
||||||
streaming_url, extra_cmd=self._ffmpeg_arguments)
|
streaming_url, extra_cmd=self._ffmpeg_arguments)
|
||||||
|
|
||||||
yield from async_aiohttp_proxy_stream(
|
await async_aiohttp_proxy_stream(
|
||||||
self.hass, request, stream,
|
self.hass, request, stream,
|
||||||
'multipart/x-mixed-replace;boundary=ffserver')
|
'multipart/x-mixed-replace;boundary=ffserver')
|
||||||
yield from stream.close()
|
await stream.close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
|
@ -75,35 +75,33 @@ class CanaryCamera(Camera):
|
||||||
"""Return the camera motion detection status."""
|
"""Return the camera motion detection status."""
|
||||||
return not self._location.is_recording
|
return not self._location.is_recording
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_camera_image(self):
|
||||||
def async_camera_image(self):
|
|
||||||
"""Return a still image response from the camera."""
|
"""Return a still image response from the camera."""
|
||||||
self.renew_live_stream_session()
|
self.renew_live_stream_session()
|
||||||
|
|
||||||
from haffmpeg import ImageFrame, IMAGE_JPEG
|
from haffmpeg import ImageFrame, IMAGE_JPEG
|
||||||
ffmpeg = ImageFrame(self._ffmpeg.binary, loop=self.hass.loop)
|
ffmpeg = ImageFrame(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
image = yield from asyncio.shield(ffmpeg.get_image(
|
image = await asyncio.shield(ffmpeg.get_image(
|
||||||
self._live_stream_session.live_stream_url,
|
self._live_stream_session.live_stream_url,
|
||||||
output_format=IMAGE_JPEG,
|
output_format=IMAGE_JPEG,
|
||||||
extra_cmd=self._ffmpeg_arguments), loop=self.hass.loop)
|
extra_cmd=self._ffmpeg_arguments), loop=self.hass.loop)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def handle_async_mjpeg_stream(self, request):
|
||||||
def handle_async_mjpeg_stream(self, request):
|
|
||||||
"""Generate an HTTP MJPEG stream from the camera."""
|
"""Generate an HTTP MJPEG stream from the camera."""
|
||||||
if self._live_stream_session is None:
|
if self._live_stream_session is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
from haffmpeg import CameraMjpeg
|
from haffmpeg import CameraMjpeg
|
||||||
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
yield from stream.open_camera(
|
await stream.open_camera(
|
||||||
self._live_stream_session.live_stream_url,
|
self._live_stream_session.live_stream_url,
|
||||||
extra_cmd=self._ffmpeg_arguments)
|
extra_cmd=self._ffmpeg_arguments)
|
||||||
|
|
||||||
yield from async_aiohttp_proxy_stream(
|
await async_aiohttp_proxy_stream(
|
||||||
self.hass, request, stream,
|
self.hass, request, stream,
|
||||||
'multipart/x-mixed-replace;boundary=ffserver')
|
'multipart/x-mixed-replace;boundary=ffserver')
|
||||||
yield from stream.close()
|
await stream.close()
|
||||||
|
|
||||||
@Throttle(MIN_TIME_BETWEEN_SESSION_RENEW)
|
@Throttle(MIN_TIME_BETWEEN_SESSION_RENEW)
|
||||||
def renew_live_stream_session(self):
|
def renew_live_stream_session(self):
|
||||||
|
|
|
@ -27,9 +27,8 @@ _LOGGER = logging.getLogger(__name__)
|
||||||
_TIMEOUT = 10 # seconds
|
_TIMEOUT = 10 # seconds
|
||||||
|
|
||||||
|
|
||||||
@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 DoorBird camera platform."""
|
"""Set up the DoorBird camera platform."""
|
||||||
for doorstation in hass.data[DOORBIRD_DOMAIN]:
|
for doorstation in hass.data[DOORBIRD_DOMAIN]:
|
||||||
device = doorstation.device
|
device = doorstation.device
|
||||||
|
@ -66,8 +65,7 @@ class DoorBirdCamera(Camera):
|
||||||
"""Get the name of the camera."""
|
"""Get the name of the camera."""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_camera_image(self):
|
||||||
def async_camera_image(self):
|
|
||||||
"""Pull a still image from the camera."""
|
"""Pull a still image from the camera."""
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
@ -77,9 +75,9 @@ class DoorBirdCamera(Camera):
|
||||||
try:
|
try:
|
||||||
websession = async_get_clientsession(self.hass)
|
websession = async_get_clientsession(self.hass)
|
||||||
with async_timeout.timeout(_TIMEOUT, loop=self.hass.loop):
|
with async_timeout.timeout(_TIMEOUT, loop=self.hass.loop):
|
||||||
response = yield from websession.get(self._url)
|
response = await websession.get(self._url)
|
||||||
|
|
||||||
self._last_image = yield from response.read()
|
self._last_image = await response.read()
|
||||||
self._last_update = now
|
self._last_update = now
|
||||||
return self._last_image
|
return self._last_image
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
|
|
|
@ -46,9 +46,8 @@ 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 a generic IP Camera."""
|
"""Set up a generic IP Camera."""
|
||||||
async_add_entities([GenericCamera(hass, config)])
|
async_add_entities([GenericCamera(hass, config)])
|
||||||
|
|
||||||
|
@ -93,8 +92,7 @@ class GenericCamera(Camera):
|
||||||
return run_coroutine_threadsafe(
|
return run_coroutine_threadsafe(
|
||||||
self.async_camera_image(), self.hass.loop).result()
|
self.async_camera_image(), self.hass.loop).result()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_camera_image(self):
|
||||||
def async_camera_image(self):
|
|
||||||
"""Return a still image response from the camera."""
|
"""Return a still image response from the camera."""
|
||||||
try:
|
try:
|
||||||
url = self._still_image_url.async_render()
|
url = self._still_image_url.async_render()
|
||||||
|
@ -118,7 +116,7 @@ class GenericCamera(Camera):
|
||||||
_LOGGER.error("Error getting camera image: %s", error)
|
_LOGGER.error("Error getting camera image: %s", error)
|
||||||
return self._last_image
|
return self._last_image
|
||||||
|
|
||||||
self._last_image = yield from self.hass.async_add_job(
|
self._last_image = await self.hass.async_add_job(
|
||||||
fetch)
|
fetch)
|
||||||
# async
|
# async
|
||||||
else:
|
else:
|
||||||
|
@ -126,9 +124,9 @@ class GenericCamera(Camera):
|
||||||
websession = async_get_clientsession(
|
websession = async_get_clientsession(
|
||||||
self.hass, verify_ssl=self.verify_ssl)
|
self.hass, verify_ssl=self.verify_ssl)
|
||||||
with async_timeout.timeout(10, loop=self.hass.loop):
|
with async_timeout.timeout(10, loop=self.hass.loop):
|
||||||
response = yield from websession.get(
|
response = await websession.get(
|
||||||
url, auth=self._auth)
|
url, auth=self._auth)
|
||||||
self._last_image = yield from response.read()
|
self._last_image = await response.read()
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
_LOGGER.error("Timeout getting camera image")
|
_LOGGER.error("Timeout getting camera image")
|
||||||
return self._last_image
|
return self._last_image
|
||||||
|
|
|
@ -41,9 +41,8 @@ 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 a MJPEG IP Camera."""
|
"""Set up a MJPEG IP Camera."""
|
||||||
if discovery_info:
|
if discovery_info:
|
||||||
config = PLATFORM_SCHEMA(discovery_info)
|
config = PLATFORM_SCHEMA(discovery_info)
|
||||||
|
@ -82,23 +81,22 @@ class MjpegCamera(Camera):
|
||||||
self._username, password=self._password
|
self._username, password=self._password
|
||||||
)
|
)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_camera_image(self):
|
||||||
def async_camera_image(self):
|
|
||||||
"""Return a still image response from the camera."""
|
"""Return a still image response from the camera."""
|
||||||
# DigestAuth is not supported
|
# DigestAuth is not supported
|
||||||
if self._authentication == HTTP_DIGEST_AUTHENTICATION or \
|
if self._authentication == HTTP_DIGEST_AUTHENTICATION or \
|
||||||
self._still_image_url is None:
|
self._still_image_url is None:
|
||||||
image = yield from self.hass.async_add_job(
|
image = await self.hass.async_add_job(
|
||||||
self.camera_image)
|
self.camera_image)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
websession = async_get_clientsession(self.hass)
|
websession = async_get_clientsession(self.hass)
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(10, loop=self.hass.loop):
|
with async_timeout.timeout(10, loop=self.hass.loop):
|
||||||
response = yield from websession.get(
|
response = await websession.get(
|
||||||
self._still_image_url, auth=self._auth)
|
self._still_image_url, auth=self._auth)
|
||||||
|
|
||||||
image = yield from response.read()
|
image = await response.read()
|
||||||
return image
|
return image
|
||||||
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
|
|
|
@ -110,8 +110,7 @@ class RingCam(Camera):
|
||||||
'video_url': self._video_url,
|
'video_url': self._video_url,
|
||||||
}
|
}
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_camera_image(self):
|
||||||
def async_camera_image(self):
|
|
||||||
"""Return a still image response from the camera."""
|
"""Return a still image response from the camera."""
|
||||||
from haffmpeg import ImageFrame, IMAGE_JPEG
|
from haffmpeg import ImageFrame, IMAGE_JPEG
|
||||||
ffmpeg = ImageFrame(self._ffmpeg.binary, loop=self.hass.loop)
|
ffmpeg = ImageFrame(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
|
@ -119,13 +118,12 @@ class RingCam(Camera):
|
||||||
if self._video_url is None:
|
if self._video_url is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
image = yield from asyncio.shield(ffmpeg.get_image(
|
image = await asyncio.shield(ffmpeg.get_image(
|
||||||
self._video_url, output_format=IMAGE_JPEG,
|
self._video_url, output_format=IMAGE_JPEG,
|
||||||
extra_cmd=self._ffmpeg_arguments), loop=self.hass.loop)
|
extra_cmd=self._ffmpeg_arguments), loop=self.hass.loop)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def handle_async_mjpeg_stream(self, request):
|
||||||
def handle_async_mjpeg_stream(self, request):
|
|
||||||
"""Generate an HTTP MJPEG stream from the camera."""
|
"""Generate an HTTP MJPEG stream from the camera."""
|
||||||
from haffmpeg import CameraMjpeg
|
from haffmpeg import CameraMjpeg
|
||||||
|
|
||||||
|
@ -133,13 +131,13 @@ class RingCam(Camera):
|
||||||
return
|
return
|
||||||
|
|
||||||
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
yield from stream.open_camera(
|
await stream.open_camera(
|
||||||
self._video_url, extra_cmd=self._ffmpeg_arguments)
|
self._video_url, extra_cmd=self._ffmpeg_arguments)
|
||||||
|
|
||||||
yield from async_aiohttp_proxy_stream(
|
await async_aiohttp_proxy_stream(
|
||||||
self.hass, request, stream,
|
self.hass, request, stream,
|
||||||
'multipart/x-mixed-replace;boundary=ffserver')
|
'multipart/x-mixed-replace;boundary=ffserver')
|
||||||
yield from stream.close()
|
await stream.close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
|
|
|
@ -4,7 +4,6 @@ Support for Synology Surveillance Station Cameras.
|
||||||
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/camera.synology/
|
https://home-assistant.io/components/camera.synology/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
@ -38,9 +37,8 @@ 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 a Synology IP Camera."""
|
"""Set up a Synology IP Camera."""
|
||||||
verify_ssl = config.get(CONF_VERIFY_SSL)
|
verify_ssl = config.get(CONF_VERIFY_SSL)
|
||||||
timeout = config.get(CONF_TIMEOUT)
|
timeout = config.get(CONF_TIMEOUT)
|
||||||
|
@ -87,15 +85,14 @@ class SynologyCamera(Camera):
|
||||||
"""Return bytes of camera image."""
|
"""Return bytes of camera image."""
|
||||||
return self._surveillance.get_camera_image(self._camera_id)
|
return self._surveillance.get_camera_image(self._camera_id)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def handle_async_mjpeg_stream(self, request):
|
||||||
def handle_async_mjpeg_stream(self, request):
|
|
||||||
"""Return a MJPEG stream image response directly from the camera."""
|
"""Return a MJPEG stream image response directly from the camera."""
|
||||||
streaming_url = self._camera.video_stream_url
|
streaming_url = self._camera.video_stream_url
|
||||||
|
|
||||||
websession = async_get_clientsession(self.hass, self._verify_ssl)
|
websession = async_get_clientsession(self.hass, self._verify_ssl)
|
||||||
stream_coro = websession.get(streaming_url)
|
stream_coro = websession.get(streaming_url)
|
||||||
|
|
||||||
yield from async_aiohttp_proxy_web(self.hass, request, stream_coro)
|
await async_aiohttp_proxy_web(self.hass, request, stream_coro)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
|
@ -67,9 +67,8 @@ 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 generic thermostat platform."""
|
"""Set up the generic thermostat platform."""
|
||||||
name = config.get(CONF_NAME)
|
name = config.get(CONF_NAME)
|
||||||
heater_entity_id = config.get(CONF_HEATER)
|
heater_entity_id = config.get(CONF_HEATER)
|
||||||
|
@ -147,12 +146,10 @@ class GenericThermostat(ClimateDevice):
|
||||||
if sensor_state and sensor_state.state != STATE_UNKNOWN:
|
if sensor_state and sensor_state.state != STATE_UNKNOWN:
|
||||||
self._async_update_temp(sensor_state)
|
self._async_update_temp(sensor_state)
|
||||||
|
|
||||||
@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."""
|
||||||
# Check If we have an old state
|
# Check If we have an old state
|
||||||
old_state = yield from async_get_last_state(self.hass,
|
old_state = await async_get_last_state(self.hass, self.entity_id)
|
||||||
self.entity_id)
|
|
||||||
if old_state is not None:
|
if old_state is not None:
|
||||||
# If we have no initial temperature, restore
|
# If we have no initial temperature, restore
|
||||||
if self._target_temp is None:
|
if self._target_temp is None:
|
||||||
|
|
|
@ -4,7 +4,6 @@ Support for MQTT climate devices.
|
||||||
For more details about this platform, please refer to the documentation
|
For more details about this platform, please refer to the documentation
|
||||||
https://home-assistant.io/components/climate.mqtt/
|
https://home-assistant.io/components/climate.mqtt/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -258,11 +257,10 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._max_temp = max_temp
|
self._max_temp = max_temp
|
||||||
self._discovery_hash = discovery_hash
|
self._discovery_hash = discovery_hash
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_added_to_hass(self):
|
||||||
def async_added_to_hass(self):
|
|
||||||
"""Handle being added to home assistant."""
|
"""Handle being added to home assistant."""
|
||||||
yield from MqttAvailability.async_added_to_hass(self)
|
await MqttAvailability.async_added_to_hass(self)
|
||||||
yield from MqttDiscoveryUpdate.async_added_to_hass(self)
|
await MqttDiscoveryUpdate.async_added_to_hass(self)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_current_temp_received(topic, payload, qos):
|
def handle_current_temp_received(topic, payload, qos):
|
||||||
|
@ -279,7 +277,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
_LOGGER.error("Could not parse temperature from %s", payload)
|
_LOGGER.error("Could not parse temperature from %s", payload)
|
||||||
|
|
||||||
if self._topic[CONF_CURRENT_TEMPERATURE_TOPIC] is not None:
|
if self._topic[CONF_CURRENT_TEMPERATURE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_CURRENT_TEMPERATURE_TOPIC],
|
self.hass, self._topic[CONF_CURRENT_TEMPERATURE_TOPIC],
|
||||||
handle_current_temp_received, self._qos)
|
handle_current_temp_received, self._qos)
|
||||||
|
|
||||||
|
@ -297,7 +295,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_MODE_STATE_TOPIC] is not None:
|
if self._topic[CONF_MODE_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_MODE_STATE_TOPIC],
|
self.hass, self._topic[CONF_MODE_STATE_TOPIC],
|
||||||
handle_mode_received, self._qos)
|
handle_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -316,7 +314,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
_LOGGER.error("Could not parse temperature from %s", payload)
|
_LOGGER.error("Could not parse temperature from %s", payload)
|
||||||
|
|
||||||
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is not None:
|
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_TEMPERATURE_STATE_TOPIC],
|
self.hass, self._topic[CONF_TEMPERATURE_STATE_TOPIC],
|
||||||
handle_temperature_received, self._qos)
|
handle_temperature_received, self._qos)
|
||||||
|
|
||||||
|
@ -335,7 +333,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is not None:
|
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_FAN_MODE_STATE_TOPIC],
|
self.hass, self._topic[CONF_FAN_MODE_STATE_TOPIC],
|
||||||
handle_fan_mode_received, self._qos)
|
handle_fan_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -354,7 +352,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is not None:
|
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_SWING_MODE_STATE_TOPIC],
|
self.hass, self._topic[CONF_SWING_MODE_STATE_TOPIC],
|
||||||
handle_swing_mode_received, self._qos)
|
handle_swing_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -380,7 +378,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_AWAY_MODE_STATE_TOPIC] is not None:
|
if self._topic[CONF_AWAY_MODE_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_AWAY_MODE_STATE_TOPIC],
|
self.hass, self._topic[CONF_AWAY_MODE_STATE_TOPIC],
|
||||||
handle_away_mode_received, self._qos)
|
handle_away_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -405,7 +403,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_AUX_STATE_TOPIC] is not None:
|
if self._topic[CONF_AUX_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_AUX_STATE_TOPIC],
|
self.hass, self._topic[CONF_AUX_STATE_TOPIC],
|
||||||
handle_aux_mode_received, self._qos)
|
handle_aux_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -420,7 +418,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
|
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
|
||||||
yield from mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._topic[CONF_HOLD_STATE_TOPIC],
|
self.hass, self._topic[CONF_HOLD_STATE_TOPIC],
|
||||||
handle_hold_mode_received, self._qos)
|
handle_hold_mode_received, self._qos)
|
||||||
|
|
||||||
|
@ -489,12 +487,11 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
"""Return the list of available fan modes."""
|
"""Return the list of available fan modes."""
|
||||||
return self._fan_list
|
return self._fan_list
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_temperature(self, **kwargs):
|
||||||
def async_set_temperature(self, **kwargs):
|
|
||||||
"""Set new target temperatures."""
|
"""Set new target temperatures."""
|
||||||
if kwargs.get(ATTR_OPERATION_MODE) is not None:
|
if kwargs.get(ATTR_OPERATION_MODE) is not None:
|
||||||
operation_mode = kwargs.get(ATTR_OPERATION_MODE)
|
operation_mode = kwargs.get(ATTR_OPERATION_MODE)
|
||||||
yield from self.async_set_operation_mode(operation_mode)
|
await self.async_set_operation_mode(operation_mode)
|
||||||
|
|
||||||
if kwargs.get(ATTR_TEMPERATURE) is not None:
|
if kwargs.get(ATTR_TEMPERATURE) is not None:
|
||||||
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is None:
|
if self._topic[CONF_TEMPERATURE_STATE_TOPIC] is None:
|
||||||
|
@ -508,8 +505,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
|
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_swing_mode(self, swing_mode):
|
||||||
def async_set_swing_mode(self, swing_mode):
|
|
||||||
"""Set new swing mode."""
|
"""Set new swing mode."""
|
||||||
if self._send_if_off or self._current_operation != STATE_OFF:
|
if self._send_if_off or self._current_operation != STATE_OFF:
|
||||||
mqtt.async_publish(
|
mqtt.async_publish(
|
||||||
|
@ -520,8 +516,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._current_swing_mode = swing_mode
|
self._current_swing_mode = swing_mode
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_fan_mode(self, fan_mode):
|
||||||
def async_set_fan_mode(self, fan_mode):
|
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
if self._send_if_off or self._current_operation != STATE_OFF:
|
if self._send_if_off or self._current_operation != STATE_OFF:
|
||||||
mqtt.async_publish(
|
mqtt.async_publish(
|
||||||
|
@ -532,8 +527,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._current_fan_mode = fan_mode
|
self._current_fan_mode = fan_mode
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_operation_mode(self, operation_mode) -> None:
|
||||||
def async_set_operation_mode(self, operation_mode) -> None:
|
|
||||||
"""Set new operation mode."""
|
"""Set new operation mode."""
|
||||||
if self._topic[CONF_POWER_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_POWER_COMMAND_TOPIC] is not None:
|
||||||
if (self._current_operation == STATE_OFF and
|
if (self._current_operation == STATE_OFF and
|
||||||
|
@ -566,8 +560,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
"""List of available swing modes."""
|
"""List of available swing modes."""
|
||||||
return self._swing_list
|
return self._swing_list
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_away_mode_on(self):
|
||||||
def async_turn_away_mode_on(self):
|
|
||||||
"""Turn away mode on."""
|
"""Turn away mode on."""
|
||||||
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
|
||||||
mqtt.async_publish(self.hass,
|
mqtt.async_publish(self.hass,
|
||||||
|
@ -578,8 +571,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._away = True
|
self._away = True
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_away_mode_off(self):
|
||||||
def async_turn_away_mode_off(self):
|
|
||||||
"""Turn away mode off."""
|
"""Turn away mode off."""
|
||||||
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None:
|
||||||
mqtt.async_publish(self.hass,
|
mqtt.async_publish(self.hass,
|
||||||
|
@ -590,8 +582,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._away = False
|
self._away = False
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_hold_mode(self, hold_mode):
|
||||||
def async_set_hold_mode(self, hold_mode):
|
|
||||||
"""Update hold mode on."""
|
"""Update hold mode on."""
|
||||||
if self._topic[CONF_HOLD_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_HOLD_COMMAND_TOPIC] is not None:
|
||||||
mqtt.async_publish(self.hass,
|
mqtt.async_publish(self.hass,
|
||||||
|
@ -602,8 +593,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._hold = hold_mode
|
self._hold = hold_mode
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_aux_heat_on(self):
|
||||||
def async_turn_aux_heat_on(self):
|
|
||||||
"""Turn auxiliary heater on."""
|
"""Turn auxiliary heater on."""
|
||||||
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
|
||||||
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
|
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
|
||||||
|
@ -613,8 +603,7 @@ class MqttClimate(MqttAvailability, MqttDiscoveryUpdate, ClimateDevice):
|
||||||
self._aux = True
|
self._aux = True
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_aux_heat_off(self):
|
||||||
def async_turn_aux_heat_off(self):
|
|
||||||
"""Turn auxiliary heater off."""
|
"""Turn auxiliary heater off."""
|
||||||
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
|
if self._topic[CONF_AUX_COMMAND_TOPIC] is not None:
|
||||||
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
|
mqtt.async_publish(self.hass, self._topic[CONF_AUX_COMMAND_TOPIC],
|
||||||
|
|
|
@ -4,7 +4,6 @@ Support for Radio Thermostat wifi-enabled home thermostats.
|
||||||
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/climate.radiotherm/
|
https://home-assistant.io/components/climate.radiotherm/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -145,8 +144,7 @@ class RadioThermostat(ClimateDevice):
|
||||||
"""Return the list of supported features."""
|
"""Return the list of supported features."""
|
||||||
return SUPPORT_FLAGS
|
return SUPPORT_FLAGS
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_added_to_hass(self):
|
||||||
def async_added_to_hass(self):
|
|
||||||
"""Register callbacks."""
|
"""Register callbacks."""
|
||||||
# Set the time on the device. This shouldn't be in the
|
# Set the time on the device. This shouldn't be in the
|
||||||
# constructor because it's a network call. We can't put it in
|
# constructor because it's a network call. We can't put it in
|
||||||
|
|
|
@ -58,9 +58,8 @@ FIELD_TO_FLAG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@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 Sensibo devices."""
|
"""Set up Sensibo devices."""
|
||||||
import pysensibo
|
import pysensibo
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ def async_setup_platform(hass, config, async_add_entities,
|
||||||
devices = []
|
devices = []
|
||||||
try:
|
try:
|
||||||
for dev in (
|
for dev in (
|
||||||
yield from client.async_get_devices(_INITIAL_FETCH_FIELDS)):
|
await client.async_get_devices(_INITIAL_FETCH_FIELDS)):
|
||||||
if config[CONF_ID] == ALL or dev['id'] in config[CONF_ID]:
|
if config[CONF_ID] == ALL or dev['id'] in config[CONF_ID]:
|
||||||
devices.append(SensiboClimate(
|
devices.append(SensiboClimate(
|
||||||
client, dev, hass.config.units.temperature_unit))
|
client, dev, hass.config.units.temperature_unit))
|
||||||
|
@ -82,8 +81,7 @@ def async_setup_platform(hass, config, async_add_entities,
|
||||||
if devices:
|
if devices:
|
||||||
async_add_entities(devices)
|
async_add_entities(devices)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_assume_state(service):
|
||||||
def async_assume_state(service):
|
|
||||||
"""Set state according to external service call.."""
|
"""Set state according to external service call.."""
|
||||||
entity_ids = service.data.get(ATTR_ENTITY_ID)
|
entity_ids = service.data.get(ATTR_ENTITY_ID)
|
||||||
if entity_ids:
|
if entity_ids:
|
||||||
|
@ -94,12 +92,12 @@ def async_setup_platform(hass, config, async_add_entities,
|
||||||
|
|
||||||
update_tasks = []
|
update_tasks = []
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
yield from climate.async_assume_state(
|
await climate.async_assume_state(
|
||||||
service.data.get(ATTR_STATE))
|
service.data.get(ATTR_STATE))
|
||||||
update_tasks.append(climate.async_update_ha_state(True))
|
update_tasks.append(climate.async_update_ha_state(True))
|
||||||
|
|
||||||
if update_tasks:
|
if update_tasks:
|
||||||
yield from asyncio.wait(update_tasks, loop=hass.loop)
|
await asyncio.wait(update_tasks, loop=hass.loop)
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_ASSUME_STATE, async_assume_state,
|
DOMAIN, SERVICE_ASSUME_STATE, async_assume_state,
|
||||||
schema=ASSUME_STATE_SCHEMA)
|
schema=ASSUME_STATE_SCHEMA)
|
||||||
|
@ -262,8 +260,7 @@ class SensiboClimate(ClimateDevice):
|
||||||
"""Return unique ID based on Sensibo ID."""
|
"""Return unique ID based on Sensibo ID."""
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_temperature(self, **kwargs):
|
||||||
def async_set_temperature(self, **kwargs):
|
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
temperature = kwargs.get(ATTR_TEMPERATURE)
|
temperature = kwargs.get(ATTR_TEMPERATURE)
|
||||||
if temperature is None:
|
if temperature is None:
|
||||||
|
@ -283,52 +280,46 @@ class SensiboClimate(ClimateDevice):
|
||||||
return
|
return
|
||||||
|
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'targetTemperature', temperature, self._ac_states)
|
self._id, 'targetTemperature', temperature, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_fan_mode(self, fan_mode):
|
||||||
def async_set_fan_mode(self, fan_mode):
|
|
||||||
"""Set new target fan mode."""
|
"""Set new target fan mode."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'fanLevel', fan_mode, self._ac_states)
|
self._id, 'fanLevel', fan_mode, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_operation_mode(self, operation_mode):
|
||||||
def async_set_operation_mode(self, operation_mode):
|
|
||||||
"""Set new target operation mode."""
|
"""Set new target operation mode."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'mode', operation_mode, self._ac_states)
|
self._id, 'mode', operation_mode, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_set_swing_mode(self, swing_mode):
|
||||||
def async_set_swing_mode(self, swing_mode):
|
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'swing', swing_mode, self._ac_states)
|
self._id, 'swing', swing_mode, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_on(self):
|
||||||
def async_turn_on(self):
|
|
||||||
"""Turn Sensibo unit on."""
|
"""Turn Sensibo unit on."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'on', True, self._ac_states)
|
self._id, 'on', True, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_turn_off(self):
|
||||||
def async_turn_off(self):
|
|
||||||
"""Turn Sensibo unit on."""
|
"""Turn Sensibo unit on."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id, 'on', False, self._ac_states)
|
self._id, 'on', False, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_assume_state(self, state):
|
||||||
def async_assume_state(self, state):
|
|
||||||
"""Set external state."""
|
"""Set external state."""
|
||||||
change_needed = (state != STATE_OFF and not self.is_on) \
|
change_needed = (state != STATE_OFF and not self.is_on) \
|
||||||
or (state == STATE_OFF and self.is_on)
|
or (state == STATE_OFF and self.is_on)
|
||||||
if change_needed:
|
if change_needed:
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
await self._client.async_set_ac_state_property(
|
||||||
self._id,
|
self._id,
|
||||||
'on',
|
'on',
|
||||||
state != STATE_OFF, # value
|
state != STATE_OFF, # value
|
||||||
|
@ -341,12 +332,11 @@ class SensiboClimate(ClimateDevice):
|
||||||
else:
|
else:
|
||||||
self._external_state = state
|
self._external_state = state
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_update(self):
|
||||||
def async_update(self):
|
|
||||||
"""Retrieve latest state."""
|
"""Retrieve latest state."""
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
data = yield from self._client.async_get_device(
|
data = await self._client.async_get_device(
|
||||||
self._id, _FETCH_FIELDS)
|
self._id, _FETCH_FIELDS)
|
||||||
self._do_update(data)
|
self._do_update(data)
|
||||||
except aiohttp.client_exceptions.ClientError:
|
except aiohttp.client_exceptions.ClientError:
|
||||||
|
|
|
@ -4,7 +4,6 @@ Support for Wink thermostats, Air Conditioners, and Water Heaters.
|
||||||
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/climate.wink/
|
https://home-assistant.io/components/climate.wink/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
|
@ -92,8 +91,7 @@ class WinkThermostat(WinkDevice, ClimateDevice):
|
||||||
"""Return the list of supported features."""
|
"""Return the list of supported features."""
|
||||||
return SUPPORT_FLAGS_THERMOSTAT
|
return SUPPORT_FLAGS_THERMOSTAT
|
||||||
|
|
||||||
@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']['climate'].append(self)
|
self.hass.data[DOMAIN]['entities']['climate'].append(self)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Provide configuration end points for Automations."""
|
"""Provide configuration end points for Automations."""
|
||||||
import asyncio
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
@ -12,8 +11,7 @@ import homeassistant.helpers.config_validation as cv
|
||||||
CONFIG_PATH = 'automations.yaml'
|
CONFIG_PATH = 'automations.yaml'
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Automation config API."""
|
"""Set up the Automation config API."""
|
||||||
async def hook(hass):
|
async def hook(hass):
|
||||||
"""post_write_hook for Config View that reloads automations."""
|
"""post_write_hook for Config View that reloads automations."""
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Http views to control the config manager."""
|
"""Http views to control the config manager."""
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow
|
from homeassistant import config_entries, data_entry_flow
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
|
@ -7,8 +6,7 @@ from homeassistant.helpers.data_entry_flow import (
|
||||||
FlowManagerIndexView, FlowManagerResourceView)
|
FlowManagerIndexView, FlowManagerResourceView)
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Enable the Home Assistant views."""
|
"""Enable the Home Assistant views."""
|
||||||
hass.http.register_view(ConfigManagerEntryIndexView)
|
hass.http.register_view(ConfigManagerEntryIndexView)
|
||||||
hass.http.register_view(ConfigManagerEntryResourceView)
|
hass.http.register_view(ConfigManagerEntryResourceView)
|
||||||
|
@ -44,8 +42,7 @@ class ConfigManagerEntryIndexView(HomeAssistantView):
|
||||||
url = '/api/config/config_entries/entry'
|
url = '/api/config/config_entries/entry'
|
||||||
name = 'api:config:config_entries:entry'
|
name = 'api:config:config_entries:entry'
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def get(self, request):
|
||||||
def get(self, request):
|
|
||||||
"""List flows in progress."""
|
"""List flows in progress."""
|
||||||
hass = request.app['hass']
|
hass = request.app['hass']
|
||||||
return self.json([{
|
return self.json([{
|
||||||
|
@ -64,13 +61,12 @@ class ConfigManagerEntryResourceView(HomeAssistantView):
|
||||||
url = '/api/config/config_entries/entry/{entry_id}'
|
url = '/api/config/config_entries/entry/{entry_id}'
|
||||||
name = 'api:config:config_entries:entry:resource'
|
name = 'api:config:config_entries:entry:resource'
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def delete(self, request, entry_id):
|
||||||
def delete(self, request, entry_id):
|
|
||||||
"""Delete a config entry."""
|
"""Delete a config entry."""
|
||||||
hass = request.app['hass']
|
hass = request.app['hass']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = yield from hass.config_entries.async_remove(entry_id)
|
result = await hass.config_entries.async_remove(entry_id)
|
||||||
except config_entries.UnknownEntry:
|
except config_entries.UnknownEntry:
|
||||||
return self.json_message('Invalid entry specified', 404)
|
return self.json_message('Invalid entry specified', 404)
|
||||||
|
|
||||||
|
@ -83,8 +79,7 @@ class ConfigManagerFlowIndexView(FlowManagerIndexView):
|
||||||
url = '/api/config/config_entries/flow'
|
url = '/api/config/config_entries/flow'
|
||||||
name = 'api:config:config_entries:flow'
|
name = 'api:config:config_entries:flow'
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def get(self, request):
|
||||||
def get(self, request):
|
|
||||||
"""List flows that are in progress but not started by a user.
|
"""List flows that are in progress but not started by a user.
|
||||||
|
|
||||||
Example of a non-user initiated flow is a discovered Hue hub that
|
Example of a non-user initiated flow is a discovered Hue hub that
|
||||||
|
@ -110,7 +105,6 @@ class ConfigManagerAvailableFlowView(HomeAssistantView):
|
||||||
url = '/api/config/config_entries/flow_handlers'
|
url = '/api/config/config_entries/flow_handlers'
|
||||||
name = 'api:config:config_entries:flow_handlers'
|
name = 'api:config:config_entries:flow_handlers'
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def get(self, request):
|
||||||
def get(self, request):
|
|
||||||
"""List available flow handlers."""
|
"""List available flow handlers."""
|
||||||
return self.json(config_entries.FLOWS)
|
return self.json(config_entries.FLOWS)
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
"""Component to interact with Hassbian tools."""
|
"""Component to interact with Hassbian tools."""
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.config import async_check_ha_config_file
|
from homeassistant.config import async_check_ha_config_file
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Hassbian config."""
|
"""Set up the Hassbian config."""
|
||||||
hass.http.register_view(CheckConfigView)
|
hass.http.register_view(CheckConfigView)
|
||||||
return True
|
return True
|
||||||
|
@ -18,10 +16,9 @@ class CheckConfigView(HomeAssistantView):
|
||||||
url = '/api/config/core/check_config'
|
url = '/api/config/core/check_config'
|
||||||
name = 'api:config:core:check_config'
|
name = 'api:config:core:check_config'
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def post(self, request):
|
||||||
def post(self, request):
|
|
||||||
"""Validate configuration and return results."""
|
"""Validate configuration and return results."""
|
||||||
errors = yield from async_check_ha_config_file(request.app['hass'])
|
errors = await async_check_ha_config_file(request.app['hass'])
|
||||||
|
|
||||||
state = 'invalid' if errors else 'valid'
|
state = 'invalid' if errors else 'valid'
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Provide configuration end points for Customize."""
|
"""Provide configuration end points for Customize."""
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from homeassistant.components.config import EditKeyBasedConfigView
|
from homeassistant.components.config import EditKeyBasedConfigView
|
||||||
from homeassistant.components import async_reload_core_config
|
from homeassistant.components import async_reload_core_config
|
||||||
|
@ -10,8 +9,7 @@ import homeassistant.helpers.config_validation as cv
|
||||||
CONFIG_PATH = 'customize.yaml'
|
CONFIG_PATH = 'customize.yaml'
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Customize config API."""
|
"""Set up the Customize config API."""
|
||||||
hass.http.register_view(CustomizeConfigView(
|
hass.http.register_view(CustomizeConfigView(
|
||||||
'customize', 'config', CONFIG_PATH, cv.entity_id, dict,
|
'customize', 'config', CONFIG_PATH, cv.entity_id, dict,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Provide configuration end points for Groups."""
|
"""Provide configuration end points for Groups."""
|
||||||
import asyncio
|
|
||||||
from homeassistant.const import SERVICE_RELOAD
|
from homeassistant.const import SERVICE_RELOAD
|
||||||
from homeassistant.components.config import EditKeyBasedConfigView
|
from homeassistant.components.config import EditKeyBasedConfigView
|
||||||
from homeassistant.components.group import DOMAIN, GROUP_SCHEMA
|
from homeassistant.components.group import DOMAIN, GROUP_SCHEMA
|
||||||
|
@ -9,13 +8,11 @@ import homeassistant.helpers.config_validation as cv
|
||||||
CONFIG_PATH = 'groups.yaml'
|
CONFIG_PATH = 'groups.yaml'
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Group config API."""
|
"""Set up the Group config API."""
|
||||||
@asyncio.coroutine
|
async def hook(hass):
|
||||||
def hook(hass):
|
|
||||||
"""post_write_hook for Config View that reloads groups."""
|
"""post_write_hook for Config View that reloads groups."""
|
||||||
yield from hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
||||||
|
|
||||||
hass.http.register_view(EditKeyBasedConfigView(
|
hass.http.register_view(EditKeyBasedConfigView(
|
||||||
'group', 'config', CONFIG_PATH, cv.slug, GROUP_SCHEMA,
|
'group', 'config', CONFIG_PATH, cv.slug, GROUP_SCHEMA,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Component to interact with Hassbian tools."""
|
"""Component to interact with Hassbian tools."""
|
||||||
import asyncio
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -30,8 +29,7 @@ _TEST_OUTPUT = """
|
||||||
""" # noqa
|
""" # noqa
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Hassbian config."""
|
"""Set up the Hassbian config."""
|
||||||
# Test if is Hassbian
|
# Test if is Hassbian
|
||||||
test_mode = 'FORCE_HASSBIAN' in os.environ
|
test_mode = 'FORCE_HASSBIAN' in os.environ
|
||||||
|
@ -46,8 +44,7 @@ def async_setup(hass):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def hassbian_status(hass, test_mode=False):
|
||||||
def hassbian_status(hass, test_mode=False):
|
|
||||||
"""Query for the Hassbian status."""
|
"""Query for the Hassbian status."""
|
||||||
# Fetch real output when not in test mode
|
# Fetch real output when not in test mode
|
||||||
if test_mode:
|
if test_mode:
|
||||||
|
@ -66,10 +63,9 @@ class HassbianSuitesView(HomeAssistantView):
|
||||||
"""Initialize suites view."""
|
"""Initialize suites view."""
|
||||||
self._test_mode = test_mode
|
self._test_mode = test_mode
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def get(self, request):
|
||||||
def get(self, request):
|
|
||||||
"""Request suite status."""
|
"""Request suite status."""
|
||||||
inp = yield from hassbian_status(request.app['hass'], self._test_mode)
|
inp = await hassbian_status(request.app['hass'], self._test_mode)
|
||||||
|
|
||||||
return self.json(inp['suites'])
|
return self.json(inp['suites'])
|
||||||
|
|
||||||
|
@ -84,8 +80,7 @@ class HassbianSuiteInstallView(HomeAssistantView):
|
||||||
"""Initialize suite view."""
|
"""Initialize suite view."""
|
||||||
self._test_mode = test_mode
|
self._test_mode = test_mode
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def post(self, request, suite):
|
||||||
def post(self, request, suite):
|
|
||||||
"""Request suite status."""
|
"""Request suite status."""
|
||||||
# do real install if not in test mode
|
# do real install if not in test mode
|
||||||
return self.json({"status": "ok"})
|
return self.json({"status": "ok"})
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Provide configuration end points for scripts."""
|
"""Provide configuration end points for scripts."""
|
||||||
import asyncio
|
|
||||||
|
|
||||||
from homeassistant.components.config import EditKeyBasedConfigView
|
from homeassistant.components.config import EditKeyBasedConfigView
|
||||||
from homeassistant.components.script import DOMAIN, SCRIPT_ENTRY_SCHEMA
|
from homeassistant.components.script import DOMAIN, SCRIPT_ENTRY_SCHEMA
|
||||||
|
@ -10,8 +9,7 @@ import homeassistant.helpers.config_validation as cv
|
||||||
CONFIG_PATH = 'scripts.yaml'
|
CONFIG_PATH = 'scripts.yaml'
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the script config API."""
|
"""Set up the script config API."""
|
||||||
async def hook(hass):
|
async def hook(hass):
|
||||||
"""post_write_hook for Config View that reloads scripts."""
|
"""post_write_hook for Config View that reloads scripts."""
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Provide configuration end points for Z-Wave."""
|
"""Provide configuration end points for Z-Wave."""
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
@ -16,8 +15,7 @@ CONFIG_PATH = 'zwave_device_config.yaml'
|
||||||
OZW_LOG_FILENAME = 'OZW_Log.txt'
|
OZW_LOG_FILENAME = 'OZW_Log.txt'
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass):
|
||||||
def async_setup(hass):
|
|
||||||
"""Set up the Z-Wave config API."""
|
"""Set up the Z-Wave config API."""
|
||||||
hass.http.register_view(EditKeyBasedConfigView(
|
hass.http.register_view(EditKeyBasedConfigView(
|
||||||
'zwave', 'device_config', CONFIG_PATH, cv.entity_id,
|
'zwave', 'device_config', CONFIG_PATH, cv.entity_id,
|
||||||
|
@ -41,8 +39,7 @@ class ZWaveLogView(HomeAssistantView):
|
||||||
name = "api:zwave:ozwlog"
|
name = "api:zwave:ozwlog"
|
||||||
|
|
||||||
# pylint: disable=no-self-use
|
# pylint: disable=no-self-use
|
||||||
@asyncio.coroutine
|
async def get(self, request):
|
||||||
def get(self, request):
|
|
||||||
"""Retrieve the lines from ZWave log."""
|
"""Retrieve the lines from ZWave log."""
|
||||||
try:
|
try:
|
||||||
lines = int(request.query.get('lines', 0))
|
lines = int(request.query.get('lines', 0))
|
||||||
|
@ -50,7 +47,7 @@ class ZWaveLogView(HomeAssistantView):
|
||||||
return Response(text='Invalid datetime', status=400)
|
return Response(text='Invalid datetime', status=400)
|
||||||
|
|
||||||
hass = request.app['hass']
|
hass = request.app['hass']
|
||||||
response = yield from hass.async_add_job(self._get_log, hass, lines)
|
response = await hass.async_add_job(self._get_log, hass, lines)
|
||||||
|
|
||||||
return Response(text='\n'.join(response))
|
return Response(text='\n'.join(response))
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ This will return a request id that has to be used for future calls.
|
||||||
A callback has to be provided to `request_config` which will be called when
|
A callback has to be provided to `request_config` which will be called when
|
||||||
the user has submitted configuration information.
|
the user has submitted configuration information.
|
||||||
"""
|
"""
|
||||||
import asyncio
|
|
||||||
import functools as ft
|
import functools as ft
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -122,8 +121,7 @@ def request_done(hass, request_id):
|
||||||
).result()
|
).result()
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_setup(hass, config):
|
||||||
def async_setup(hass, config):
|
|
||||||
"""Set up the configurator component."""
|
"""Set up the configurator component."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -207,8 +205,7 @@ class Configurator:
|
||||||
|
|
||||||
self.hass.bus.async_listen_once(EVENT_TIME_CHANGED, deferred_remove)
|
self.hass.bus.async_listen_once(EVENT_TIME_CHANGED, deferred_remove)
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def async_handle_service_call(self, call):
|
||||||
def async_handle_service_call(self, call):
|
|
||||||
"""Handle a configure service call."""
|
"""Handle a configure service call."""
|
||||||
request_id = call.data.get(ATTR_CONFIGURE_ID)
|
request_id = call.data.get(ATTR_CONFIGURE_ID)
|
||||||
|
|
||||||
|
@ -220,8 +217,8 @@ class Configurator:
|
||||||
|
|
||||||
# field validation goes here?
|
# field validation goes here?
|
||||||
if callback:
|
if callback:
|
||||||
yield from self.hass.async_add_job(callback,
|
await self.hass.async_add_job(callback,
|
||||||
call.data.get(ATTR_FIELDS, {}))
|
call.data.get(ATTR_FIELDS, {}))
|
||||||
|
|
||||||
def _generate_unique_id(self):
|
def _generate_unique_id(self):
|
||||||
"""Generate a unique configurator ID."""
|
"""Generate a unique configurator ID."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue