Fix callback and async (#31281)
* Fix callback and async * Fix a return * Fix test * Fix mqtt tests * Fix some more callbackspull/31290/head
parent
ee602e40a6
commit
e9e44dbd97
|
@ -121,67 +121,49 @@ class AlarmControlPanel(Entity):
|
|||
"""Send disarm command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_disarm(self, code=None):
|
||||
"""Send disarm command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_disarm, code)
|
||||
async def async_alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_disarm, code)
|
||||
|
||||
def alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_arm_home(self, code=None):
|
||||
"""Send arm home command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_arm_home, code)
|
||||
async def async_alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_arm_home, code)
|
||||
|
||||
def alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_arm_away(self, code=None):
|
||||
"""Send arm away command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_arm_away, code)
|
||||
async def async_alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_arm_away, code)
|
||||
|
||||
def alarm_arm_night(self, code=None):
|
||||
"""Send arm night command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_arm_night(self, code=None):
|
||||
"""Send arm night command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_arm_night, code)
|
||||
async def async_alarm_arm_night(self, code=None):
|
||||
"""Send arm night command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_arm_night, code)
|
||||
|
||||
def alarm_trigger(self, code=None):
|
||||
"""Send alarm trigger command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_trigger(self, code=None):
|
||||
"""Send alarm trigger command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_trigger, code)
|
||||
async def async_alarm_trigger(self, code=None):
|
||||
"""Send alarm trigger command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_trigger, code)
|
||||
|
||||
def alarm_arm_custom_bypass(self, code=None):
|
||||
"""Send arm custom bypass command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_alarm_arm_custom_bypass(self, code=None):
|
||||
"""Send arm custom bypass command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(self.alarm_arm_custom_bypass, code)
|
||||
async def async_alarm_arm_custom_bypass(self, code=None):
|
||||
"""Send arm custom bypass command."""
|
||||
await self.hass.async_add_executor_job(self.alarm_arm_custom_bypass, code)
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
|
|
|
@ -20,6 +20,7 @@ from homeassistant.const import (
|
|||
STATE_OFF,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -55,9 +56,10 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
|
||||
_LOGGER.info("Provisioning Anthem AVR device at %s:%d", host, port)
|
||||
|
||||
@callback
|
||||
def async_anthemav_update_callback(message):
|
||||
"""Receive notification from transport that new data exists."""
|
||||
_LOGGER.info("Received update callback from AVR: %s", message)
|
||||
_LOGGER.debug("Received update callback from AVR: %s", message)
|
||||
hass.async_create_task(device.async_update_ha_state())
|
||||
|
||||
avr = await anthemav.Connection.create(
|
||||
|
|
|
@ -411,6 +411,7 @@ async def async_services_json(hass):
|
|||
return [{"domain": key, "services": value} for key, value in descriptions.items()]
|
||||
|
||||
|
||||
@ha.callback
|
||||
def async_events_json(hass):
|
||||
"""Generate event data to JSONify."""
|
||||
return [
|
||||
|
|
|
@ -229,62 +229,42 @@ class AppleTvDevice(MediaPlayerDevice):
|
|||
self._playing = None
|
||||
self._power.set_power_on(False)
|
||||
|
||||
def async_media_play_pause(self):
|
||||
"""Pause media on media player.
|
||||
async def async_media_play_pause(self):
|
||||
"""Pause media on media player."""
|
||||
if not self._playing:
|
||||
return
|
||||
state = self.state
|
||||
if state == STATE_PAUSED:
|
||||
await self.atv.remote_control.play()
|
||||
elif state == STATE_PLAYING:
|
||||
await self.atv.remote_control.pause()
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_play(self):
|
||||
"""Play media."""
|
||||
if self._playing:
|
||||
state = self.state
|
||||
if state == STATE_PAUSED:
|
||||
return self.atv.remote_control.play()
|
||||
if state == STATE_PLAYING:
|
||||
return self.atv.remote_control.pause()
|
||||
await self.atv.remote_control.play()
|
||||
|
||||
def async_media_play(self):
|
||||
"""Play media.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_stop(self):
|
||||
"""Stop the media player."""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.play()
|
||||
await self.atv.remote_control.stop()
|
||||
|
||||
def async_media_stop(self):
|
||||
"""Stop the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_pause(self):
|
||||
"""Pause the media player."""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.stop()
|
||||
await self.atv.remote_control.pause()
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Pause the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.pause()
|
||||
await self.atv.remote_control.next()
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_previous_track(self):
|
||||
"""Send previous track command."""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.next()
|
||||
await self.atv.remote_control.previous()
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send previous track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.previous()
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
if self._playing:
|
||||
return self.atv.remote_control.set_position(position)
|
||||
await self.atv.remote_control.set_position(position)
|
||||
|
|
|
@ -61,17 +61,10 @@ class AppleTVRemote(remote.RemoteDevice):
|
|||
"""
|
||||
self._power.set_power_on(False)
|
||||
|
||||
def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to one device.
|
||||
async def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to one device."""
|
||||
for single_command in command:
|
||||
if not hasattr(self._atv.remote_control, single_command):
|
||||
continue
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
# Send commands in specified order but schedule only one coroutine
|
||||
async def _send_commands():
|
||||
for single_command in command:
|
||||
if not hasattr(self._atv.remote_control, single_command):
|
||||
continue
|
||||
|
||||
await getattr(self._atv.remote_control, single_command)()
|
||||
|
||||
return _send_commands()
|
||||
await getattr(self._atv.remote_control, single_command)()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Support for the Asterisk Voicemail interface."""
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
from asterisk_mbox import ServerError
|
||||
|
@ -55,7 +56,9 @@ class AsteriskMailbox(Mailbox):
|
|||
|
||||
client = self.hass.data[ASTERISK_DOMAIN].client
|
||||
try:
|
||||
return client.mp3(msgid, sync=True)
|
||||
return await self.hass.async_add_executor_job(
|
||||
partial(client.mp3, msgid, sync=True)
|
||||
)
|
||||
except ServerError as err:
|
||||
raise StreamError(err)
|
||||
|
||||
|
@ -63,9 +66,9 @@ class AsteriskMailbox(Mailbox):
|
|||
"""Return a list of the current messages."""
|
||||
return self.hass.data[ASTERISK_DOMAIN].messages
|
||||
|
||||
def async_delete(self, msgid):
|
||||
async def async_delete(self, msgid):
|
||||
"""Delete the specified messages."""
|
||||
client = self.hass.data[ASTERISK_DOMAIN].client
|
||||
_LOGGER.info("Deleting: %s", msgid)
|
||||
client.delete(msgid)
|
||||
await self.hass.async_add_executor_job(client.delete, msgid)
|
||||
return True
|
||||
|
|
|
@ -92,6 +92,7 @@ async def async_attach_trigger(hass, config, action, automation_info):
|
|||
hass.data["litejet_system"].on_switch_pressed(number, pressed)
|
||||
hass.data["litejet_system"].on_switch_released(number, released)
|
||||
|
||||
@callback
|
||||
def async_remove():
|
||||
"""Remove all subscriptions used for this trigger."""
|
||||
return
|
||||
|
|
|
@ -5,7 +5,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.device_automation.const import CONF_IS_OFF, CONF_IS_ON
|
||||
from homeassistant.const import ATTR_DEVICE_CLASS, CONF_ENTITY_ID, CONF_FOR, CONF_TYPE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv
|
||||
from homeassistant.helpers.entity_registry import (
|
||||
async_entries_for_device,
|
||||
|
@ -232,6 +232,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -10,6 +10,7 @@ import socket
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
|
@ -64,67 +65,67 @@ SERVICE_SEND_SCHEMA = vol.Schema(
|
|||
SERVICE_LEARN_SCHEMA = vol.Schema({vol.Required(CONF_HOST): cv.string})
|
||||
|
||||
|
||||
@callback
|
||||
def async_setup_service(hass, host, device):
|
||||
"""Register a device for given host for use in services."""
|
||||
hass.data.setdefault(DOMAIN, {})[host] = device
|
||||
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_LEARN):
|
||||
if hass.services.has_service(DOMAIN, SERVICE_LEARN):
|
||||
return
|
||||
|
||||
async def _learn_command(call):
|
||||
"""Learn a packet from remote."""
|
||||
device = hass.data[DOMAIN][call.data[CONF_HOST]]
|
||||
async def _learn_command(call):
|
||||
"""Learn a packet from remote."""
|
||||
device = hass.data[DOMAIN][call.data[CONF_HOST]]
|
||||
|
||||
try:
|
||||
auth = await hass.async_add_executor_job(device.auth)
|
||||
except socket.timeout:
|
||||
_LOGGER.error("Failed to connect to device, timeout")
|
||||
try:
|
||||
auth = await hass.async_add_executor_job(device.auth)
|
||||
except socket.timeout:
|
||||
_LOGGER.error("Failed to connect to device, timeout")
|
||||
return
|
||||
if not auth:
|
||||
_LOGGER.error("Failed to connect to device")
|
||||
return
|
||||
|
||||
await hass.async_add_executor_job(device.enter_learning)
|
||||
|
||||
_LOGGER.info("Press the key you want Home Assistant to learn")
|
||||
start_time = utcnow()
|
||||
while (utcnow() - start_time) < timedelta(seconds=20):
|
||||
packet = await hass.async_add_executor_job(device.check_data)
|
||||
if packet:
|
||||
data = b64encode(packet).decode("utf8")
|
||||
log_msg = f"Received packet is: {data}"
|
||||
_LOGGER.info(log_msg)
|
||||
hass.components.persistent_notification.async_create(
|
||||
log_msg, title="Broadlink switch"
|
||||
)
|
||||
return
|
||||
if not auth:
|
||||
_LOGGER.error("Failed to connect to device")
|
||||
return
|
||||
|
||||
await hass.async_add_executor_job(device.enter_learning)
|
||||
|
||||
_LOGGER.info("Press the key you want Home Assistant to learn")
|
||||
start_time = utcnow()
|
||||
while (utcnow() - start_time) < timedelta(seconds=20):
|
||||
packet = await hass.async_add_executor_job(device.check_data)
|
||||
if packet:
|
||||
data = b64encode(packet).decode("utf8")
|
||||
log_msg = f"Received packet is: {data}"
|
||||
_LOGGER.info(log_msg)
|
||||
hass.components.persistent_notification.async_create(
|
||||
log_msg, title="Broadlink switch"
|
||||
)
|
||||
return
|
||||
await asyncio.sleep(1)
|
||||
_LOGGER.error("No signal was received")
|
||||
hass.components.persistent_notification.async_create(
|
||||
"No signal was received", title="Broadlink switch"
|
||||
)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_LEARN, _learn_command, schema=SERVICE_LEARN_SCHEMA
|
||||
await asyncio.sleep(1)
|
||||
_LOGGER.error("No signal was received")
|
||||
hass.components.persistent_notification.async_create(
|
||||
"No signal was received", title="Broadlink switch"
|
||||
)
|
||||
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_SEND):
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_LEARN, _learn_command, schema=SERVICE_LEARN_SCHEMA
|
||||
)
|
||||
|
||||
async def _send_packet(call):
|
||||
"""Send a packet."""
|
||||
device = hass.data[DOMAIN][call.data[CONF_HOST]]
|
||||
packets = call.data[CONF_PACKET]
|
||||
for packet in packets:
|
||||
for retry in range(DEFAULT_RETRY):
|
||||
async def _send_packet(call):
|
||||
"""Send a packet."""
|
||||
device = hass.data[DOMAIN][call.data[CONF_HOST]]
|
||||
packets = call.data[CONF_PACKET]
|
||||
for packet in packets:
|
||||
for retry in range(DEFAULT_RETRY):
|
||||
try:
|
||||
await hass.async_add_executor_job(device.send_data, packet)
|
||||
break
|
||||
except (socket.timeout, ValueError):
|
||||
try:
|
||||
await hass.async_add_executor_job(device.send_data, packet)
|
||||
break
|
||||
except (socket.timeout, ValueError):
|
||||
try:
|
||||
await hass.async_add_executor_job(device.auth)
|
||||
except socket.timeout:
|
||||
if retry == DEFAULT_RETRY - 1:
|
||||
_LOGGER.error("Failed to send packet to device")
|
||||
await hass.async_add_executor_job(device.auth)
|
||||
except socket.timeout:
|
||||
if retry == DEFAULT_RETRY - 1:
|
||||
_LOGGER.error("Failed to send packet to device")
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_SEND, _send_packet, schema=SERVICE_SEND_SCHEMA
|
||||
)
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_SEND, _send_packet, schema=SERVICE_SEND_SCHEMA
|
||||
)
|
||||
|
|
|
@ -364,19 +364,12 @@ class Camera(Entity):
|
|||
"""Return bytes of camera image."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@callback
|
||||
def async_camera_image(self):
|
||||
"""Return bytes of camera image.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.camera_image)
|
||||
async def async_camera_image(self):
|
||||
"""Return bytes of camera image."""
|
||||
return await self.hass.async_add_job(self.camera_image)
|
||||
|
||||
async def handle_async_still_stream(self, request, interval):
|
||||
"""Generate an HTTP MJPEG stream from camera images.
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
"""Generate an HTTP MJPEG stream from camera images."""
|
||||
return await async_get_still_stream(
|
||||
request, self.async_camera_image, self.content_type, interval
|
||||
)
|
||||
|
@ -386,7 +379,6 @@ class Camera(Entity):
|
|||
|
||||
This method can be overridden by camera plaforms to proxy
|
||||
a direct stream from the camera.
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
return await self.handle_async_still_stream(request, self.frame_interval)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from homeassistant.const import (
|
|||
CONF_ENTITY_ID,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -77,6 +77,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -236,23 +236,17 @@ class CoverDevice(Entity):
|
|||
"""Open the cover."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_open_cover(self, **kwargs):
|
||||
"""Open the cover.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.open_cover, **kwargs))
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
await self.hass.async_add_job(ft.partial(self.open_cover, **kwargs))
|
||||
|
||||
def close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close cover."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_close_cover(self, **kwargs):
|
||||
"""Close cover.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.close_cover, **kwargs))
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Close cover."""
|
||||
await self.hass.async_add_job(ft.partial(self.close_cover, **kwargs))
|
||||
|
||||
def toggle(self, **kwargs: Any) -> None:
|
||||
"""Toggle the entity."""
|
||||
|
@ -261,69 +255,52 @@ class CoverDevice(Entity):
|
|||
else:
|
||||
self.close_cover(**kwargs)
|
||||
|
||||
def async_toggle(self, **kwargs):
|
||||
"""Toggle the entity.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_toggle(self, **kwargs):
|
||||
"""Toggle the entity."""
|
||||
if self.is_closed:
|
||||
return self.async_open_cover(**kwargs)
|
||||
return self.async_close_cover(**kwargs)
|
||||
await self.async_open_cover(**kwargs)
|
||||
else:
|
||||
await self.async_close_cover(**kwargs)
|
||||
|
||||
def set_cover_position(self, **kwargs):
|
||||
"""Move the cover to a specific position."""
|
||||
pass
|
||||
|
||||
def async_set_cover_position(self, **kwargs):
|
||||
"""Move the cover to a specific position.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.set_cover_position, **kwargs))
|
||||
async def async_set_cover_position(self, **kwargs):
|
||||
"""Move the cover to a specific position."""
|
||||
await self.hass.async_add_job(ft.partial(self.set_cover_position, **kwargs))
|
||||
|
||||
def stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
pass
|
||||
|
||||
def async_stop_cover(self, **kwargs):
|
||||
"""Stop the cover.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.stop_cover, **kwargs))
|
||||
async def async_stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
await self.hass.async_add_job(ft.partial(self.stop_cover, **kwargs))
|
||||
|
||||
def open_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Open the cover tilt."""
|
||||
pass
|
||||
|
||||
def async_open_cover_tilt(self, **kwargs):
|
||||
"""Open the cover tilt.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.open_cover_tilt, **kwargs))
|
||||
async def async_open_cover_tilt(self, **kwargs):
|
||||
"""Open the cover tilt."""
|
||||
await self.hass.async_add_job(ft.partial(self.open_cover_tilt, **kwargs))
|
||||
|
||||
def close_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Close the cover tilt."""
|
||||
pass
|
||||
|
||||
def async_close_cover_tilt(self, **kwargs):
|
||||
"""Close the cover tilt.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.close_cover_tilt, **kwargs))
|
||||
async def async_close_cover_tilt(self, **kwargs):
|
||||
"""Close the cover tilt."""
|
||||
await self.hass.async_add_job(ft.partial(self.close_cover_tilt, **kwargs))
|
||||
|
||||
def set_cover_tilt_position(self, **kwargs):
|
||||
"""Move the cover tilt to a specific position."""
|
||||
pass
|
||||
|
||||
def async_set_cover_tilt_position(self, **kwargs):
|
||||
"""Move the cover tilt to a specific position.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(
|
||||
async def async_set_cover_tilt_position(self, **kwargs):
|
||||
"""Move the cover tilt to a specific position."""
|
||||
await self.hass.async_add_job(
|
||||
ft.partial(self.set_cover_tilt_position, **kwargs)
|
||||
)
|
||||
|
||||
|
@ -331,12 +308,9 @@ class CoverDevice(Entity):
|
|||
"""Stop the cover."""
|
||||
pass
|
||||
|
||||
def async_stop_cover_tilt(self, **kwargs):
|
||||
"""Stop the cover.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.stop_cover_tilt, **kwargs))
|
||||
async def async_stop_cover_tilt(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
await self.hass.async_add_job(ft.partial(self.stop_cover_tilt, **kwargs))
|
||||
|
||||
def toggle_tilt(self, **kwargs: Any) -> None:
|
||||
"""Toggle the entity."""
|
||||
|
@ -345,11 +319,9 @@ class CoverDevice(Entity):
|
|||
else:
|
||||
self.close_cover_tilt(**kwargs)
|
||||
|
||||
def async_toggle_tilt(self, **kwargs):
|
||||
"""Toggle the entity.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_toggle_tilt(self, **kwargs):
|
||||
"""Toggle the entity."""
|
||||
if self.current_cover_tilt_position == 0:
|
||||
return self.async_open_cover_tilt(**kwargs)
|
||||
return self.async_close_cover_tilt(**kwargs)
|
||||
await self.async_open_cover_tilt(**kwargs)
|
||||
else:
|
||||
await self.async_close_cover_tilt(**kwargs)
|
||||
|
|
|
@ -18,7 +18,7 @@ from homeassistant.const import (
|
|||
STATE_OPEN,
|
||||
STATE_OPENING,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import (
|
||||
condition,
|
||||
config_validation as cv,
|
||||
|
@ -163,6 +163,7 @@ async def async_get_condition_capabilities(hass: HomeAssistant, config: dict) ->
|
|||
}
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
@ -196,6 +197,7 @@ def async_condition_from_config(
|
|||
f"{{{{ state.attributes.{position} }}}}"
|
||||
)
|
||||
|
||||
@callback
|
||||
def template_if(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool:
|
||||
"""Validate template based if-condition."""
|
||||
value_template.hass = hass
|
||||
|
|
|
@ -71,7 +71,7 @@ class DemoMailbox(Mailbox):
|
|||
reverse=True,
|
||||
)
|
||||
|
||||
def async_delete(self, msgid):
|
||||
async def async_delete(self, msgid):
|
||||
"""Delete the specified messages."""
|
||||
if msgid in self._messages:
|
||||
_LOGGER.info("Deleting: %s", msgid)
|
||||
|
|
|
@ -24,7 +24,7 @@ from homeassistant.const import (
|
|||
CONF_PLATFORM,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from homeassistant.core import CALLBACK_TYPE, Context, HomeAssistant
|
||||
from homeassistant.core import CALLBACK_TYPE, Context, HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv
|
||||
from homeassistant.helpers.entity_registry import async_entries_for_device
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -121,6 +121,7 @@ async def async_call_action_from_config(
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(config: ConfigType) -> condition.ConditionCheckerType:
|
||||
"""Evaluate state based on configuration."""
|
||||
condition_type = config[CONF_TYPE]
|
||||
|
|
|
@ -113,29 +113,27 @@ async def async_setup(hass, config):
|
|||
return None
|
||||
return next_setting - LIGHT_TRANSITION_TIME * len(light_ids)
|
||||
|
||||
def async_turn_on_before_sunset(light_id):
|
||||
async def async_turn_on_before_sunset(light_id):
|
||||
"""Turn on lights."""
|
||||
if not anyone_home() or light.is_on(light_id):
|
||||
return
|
||||
hass.async_create_task(
|
||||
hass.services.async_call(
|
||||
DOMAIN_LIGHT,
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: light_id,
|
||||
ATTR_TRANSITION: LIGHT_TRANSITION_TIME.seconds,
|
||||
ATTR_PROFILE: light_profile,
|
||||
},
|
||||
)
|
||||
await hass.services.async_call(
|
||||
DOMAIN_LIGHT,
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: light_id,
|
||||
ATTR_TRANSITION: LIGHT_TRANSITION_TIME.seconds,
|
||||
ATTR_PROFILE: light_profile,
|
||||
},
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_turn_on_factory(light_id):
|
||||
"""Generate turn on callbacks as factory."""
|
||||
|
||||
@callback
|
||||
def async_turn_on_light(now):
|
||||
async def async_turn_on_light(now):
|
||||
"""Turn on specific light."""
|
||||
async_turn_on_before_sunset(light_id)
|
||||
await async_turn_on_before_sunset(light_id)
|
||||
|
||||
return async_turn_on_light
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||
STATE_HOME,
|
||||
STATE_NOT_HOME,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -65,6 +65,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
@ -76,6 +77,7 @@ def async_condition_from_config(
|
|||
else:
|
||||
state = STATE_NOT_HOME
|
||||
|
||||
@callback
|
||||
def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool:
|
||||
"""Test if an entity is a certain state."""
|
||||
return condition.state(hass, config[ATTR_ENTITY_ID], state)
|
||||
|
|
|
@ -491,34 +491,25 @@ class DeviceScanner:
|
|||
"""Scan for devices."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_scan_devices(self) -> Any:
|
||||
"""Scan for devices.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.scan_devices)
|
||||
async def async_scan_devices(self) -> Any:
|
||||
"""Scan for devices."""
|
||||
return await self.hass.async_add_job(self.scan_devices)
|
||||
|
||||
def get_device_name(self, device: str) -> str:
|
||||
"""Get the name of a device."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_get_device_name(self, device: str) -> Any:
|
||||
"""Get the name of a device.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.get_device_name, device)
|
||||
async def async_get_device_name(self, device: str) -> Any:
|
||||
"""Get the name of a device."""
|
||||
return await self.hass.async_add_job(self.get_device_name, device)
|
||||
|
||||
def get_extra_attributes(self, device: str) -> dict:
|
||||
"""Get the extra attributes of a device."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_get_extra_attributes(self, device: str) -> Any:
|
||||
"""Get the extra attributes of a device.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.get_extra_attributes, device)
|
||||
async def async_get_extra_attributes(self, device: str) -> Any:
|
||||
"""Get the extra attributes of a device."""
|
||||
return await self.hass.async_add_job(self.get_extra_attributes, device)
|
||||
|
||||
|
||||
async def async_load_config(
|
||||
|
|
|
@ -309,44 +309,26 @@ class EmbyDevice(MediaPlayerDevice):
|
|||
return SUPPORT_EMBY
|
||||
return None
|
||||
|
||||
def async_media_play(self):
|
||||
"""Play media.
|
||||
async def async_media_play(self):
|
||||
"""Play media."""
|
||||
await self.device.media_play()
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_play()
|
||||
async def async_media_pause(self):
|
||||
"""Pause the media player."""
|
||||
await self.device.media_pause()
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Pause the media player.
|
||||
async def async_media_stop(self):
|
||||
"""Stop the media player."""
|
||||
await self.device.media_stop()
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_pause()
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
await self.device.media_next()
|
||||
|
||||
def async_media_stop(self):
|
||||
"""Stop the media player.
|
||||
async def async_media_previous_track(self):
|
||||
"""Send next track command."""
|
||||
await self.device.media_previous()
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_stop()
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_next()
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_previous()
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.device.media_seek(position)
|
||||
async def async_media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
await self.device.media_seek(position)
|
||||
|
|
|
@ -21,6 +21,7 @@ from aioesphomeapi import (
|
|||
import attr
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.storage import Store
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
|
@ -71,6 +72,7 @@ class RuntimeEntryData:
|
|||
loaded_platforms = attr.ib(type=Set[str], factory=set)
|
||||
platform_load_lock = attr.ib(type=asyncio.Lock, factory=asyncio.Lock)
|
||||
|
||||
@callback
|
||||
def async_update_entity(
|
||||
self, hass: HomeAssistantType, component_key: str, key: int
|
||||
) -> None:
|
||||
|
@ -80,6 +82,7 @@ class RuntimeEntryData:
|
|||
)
|
||||
async_dispatcher_send(hass, signal)
|
||||
|
||||
@callback
|
||||
def async_remove_entity(
|
||||
self, hass: HomeAssistantType, component_key: str, key: int
|
||||
) -> None:
|
||||
|
@ -120,11 +123,13 @@ class RuntimeEntryData:
|
|||
signal = DISPATCHER_ON_LIST.format(entry_id=self.entry_id)
|
||||
async_dispatcher_send(hass, signal, infos)
|
||||
|
||||
@callback
|
||||
def async_update_state(self, hass: HomeAssistantType, state: EntityState) -> None:
|
||||
"""Distribute an update of state information to all platforms."""
|
||||
signal = DISPATCHER_ON_STATE.format(entry_id=self.entry_id)
|
||||
async_dispatcher_send(hass, signal, state)
|
||||
|
||||
@callback
|
||||
def async_update_device_state(self, hass: HomeAssistantType) -> None:
|
||||
"""Distribute an update of a core device state like availability."""
|
||||
signal = DISPATCHER_ON_DEVICE_UPDATE.format(entry_id=self.entry_id)
|
||||
|
|
|
@ -111,25 +111,20 @@ class FanEntity(ToggleEntity):
|
|||
"""Set the speed of the fan."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_set_speed(self, speed: str):
|
||||
"""Set the speed of the fan.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_set_speed(self, speed: str):
|
||||
"""Set the speed of the fan."""
|
||||
if speed is SPEED_OFF:
|
||||
return self.async_turn_off()
|
||||
return self.hass.async_add_job(self.set_speed, speed)
|
||||
await self.async_turn_off()
|
||||
else:
|
||||
await self.hass.async_add_job(self.set_speed, speed)
|
||||
|
||||
def set_direction(self, direction: str) -> None:
|
||||
"""Set the direction of the fan."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_set_direction(self, direction: str):
|
||||
"""Set the direction of the fan.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.set_direction, direction)
|
||||
async def async_set_direction(self, direction: str):
|
||||
"""Set the direction of the fan."""
|
||||
await self.hass.async_add_job(self.set_direction, direction)
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def turn_on(self, speed: Optional[str] = None, **kwargs) -> None:
|
||||
|
@ -137,25 +132,20 @@ class FanEntity(ToggleEntity):
|
|||
raise NotImplementedError()
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def async_turn_on(self, speed: Optional[str] = None, **kwargs):
|
||||
"""Turn on the fan.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_turn_on(self, speed: Optional[str] = None, **kwargs):
|
||||
"""Turn on the fan."""
|
||||
if speed is SPEED_OFF:
|
||||
return self.async_turn_off()
|
||||
return self.hass.async_add_job(ft.partial(self.turn_on, speed, **kwargs))
|
||||
await self.async_turn_off()
|
||||
else:
|
||||
await self.hass.async_add_job(ft.partial(self.turn_on, speed, **kwargs))
|
||||
|
||||
def oscillate(self, oscillating: bool) -> None:
|
||||
"""Oscillate the fan."""
|
||||
pass
|
||||
|
||||
def async_oscillate(self, oscillating: bool):
|
||||
"""Oscillate the fan.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.oscillate, oscillating)
|
||||
async def async_oscillate(self, oscillating: bool):
|
||||
"""Oscillate the fan."""
|
||||
await self.hass.async_add_job(self.oscillate, oscillating)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||
STATE_OFF,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -64,6 +64,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
@ -75,6 +76,7 @@ def async_condition_from_config(
|
|||
else:
|
||||
state = STATE_OFF
|
||||
|
||||
@callback
|
||||
def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool:
|
||||
"""Test if an entity is a certain state."""
|
||||
return condition.state(hass, config[ATTR_ENTITY_ID], state)
|
||||
|
|
|
@ -453,10 +453,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity):
|
|||
await self.hass.services.async_call(HA_DOMAIN, SERVICE_TURN_OFF, data)
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str):
|
||||
"""Set new preset mode.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Set new preset mode."""
|
||||
if preset_mode == PRESET_AWAY and not self._is_away:
|
||||
self._is_away = True
|
||||
self._saved_target_temp = self._target_temp
|
||||
|
|
|
@ -122,6 +122,7 @@ class AbstractConfig(ABC):
|
|||
]
|
||||
await gather(*jobs)
|
||||
|
||||
@callback
|
||||
def async_enable_report_state(self):
|
||||
"""Enable proactive mode."""
|
||||
# Circular dep
|
||||
|
@ -131,6 +132,7 @@ class AbstractConfig(ABC):
|
|||
if self._unsub_report_state is None:
|
||||
self._unsub_report_state = async_enable_report_state(self.hass, self)
|
||||
|
||||
@callback
|
||||
def async_disable_report_state(self):
|
||||
"""Disable report state."""
|
||||
if self._unsub_report_state is not None:
|
||||
|
|
|
@ -7,6 +7,7 @@ import aiohttp
|
|||
import hangups
|
||||
from hangups import ChatMessageEvent, ChatMessageSegment, Client, get_auth, hangouts_pb2
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import dispatcher, intent
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
|
@ -75,6 +76,7 @@ class HangoutsBot:
|
|||
return conv
|
||||
return None
|
||||
|
||||
@callback
|
||||
def async_update_conversation_commands(self):
|
||||
"""Refresh the commands for every conversation."""
|
||||
self._conversation_intents = {}
|
||||
|
@ -110,6 +112,7 @@ class HangoutsBot:
|
|||
self._async_handle_conversation_event
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_resolve_conversations(self, _):
|
||||
"""Resolve the list of default and error suppressed conversations."""
|
||||
self._default_conv_ids = []
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from homekit.model.characteristics import CharacteristicsTypes
|
||||
|
||||
from homeassistant.components.air_quality import AirQualityEntity
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -83,6 +84,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "air-quality":
|
||||
return False
|
||||
|
|
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
|||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -45,6 +46,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "security-system":
|
||||
return False
|
||||
|
|
|
@ -7,6 +7,7 @@ from homeassistant.components.binary_sensor import (
|
|||
DEVICE_CLASS_SMOKE,
|
||||
BinarySensorDevice,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -98,6 +99,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
entity_class = ENTITY_TYPES.get(service["stype"])
|
||||
if not entity_class:
|
||||
|
|
|
@ -20,6 +20,7 @@ from homeassistant.components.climate.const import (
|
|||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -50,6 +51,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "thermostat":
|
||||
return False
|
||||
|
|
|
@ -12,6 +12,7 @@ from homekit.exceptions import (
|
|||
from homekit.model.characteristics import CharacteristicsTypes
|
||||
from homekit.model.services import ServicesTypes
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
|
||||
from .const import DOMAIN, ENTITY_MAP, HOMEKIT_ACCESSORY_DISPATCH
|
||||
|
@ -116,6 +117,7 @@ class HKDevice:
|
|||
char for char in self.pollable_characteristics if char[0] != accessory_id
|
||||
]
|
||||
|
||||
@callback
|
||||
def async_set_unavailable(self):
|
||||
"""Mark state of all entities on this connection as unavailable."""
|
||||
self.available = False
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.components.cover import (
|
|||
CoverDevice,
|
||||
)
|
||||
from homeassistant.const import STATE_CLOSED, STATE_CLOSING, STATE_OPEN, STATE_OPENING
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -41,6 +42,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
info = {"aid": aid, "iid": service["iid"]}
|
||||
if service["stype"] == "garage-door-opener":
|
||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.components.fan import (
|
|||
SUPPORT_SET_SPEED,
|
||||
FanEntity,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -235,6 +236,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
entity_class = ENTITY_TYPES.get(service["stype"])
|
||||
if not entity_class:
|
||||
|
|
|
@ -12,6 +12,7 @@ from homeassistant.components.light import (
|
|||
SUPPORT_COLOR_TEMP,
|
||||
Light,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -23,6 +24,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "lightbulb":
|
||||
return False
|
||||
|
|
|
@ -5,6 +5,7 @@ from homekit.model.characteristics import CharacteristicsTypes
|
|||
|
||||
from homeassistant.components.lock import LockDevice
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -22,6 +23,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "lock-mechanism":
|
||||
return False
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from homekit.model.characteristics import CharacteristicsTypes
|
||||
|
||||
from homeassistant.const import DEVICE_CLASS_BATTERY, TEMP_CELSIUS
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -246,6 +247,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
entity_class = ENTITY_TYPES.get(service["stype"])
|
||||
if not entity_class:
|
||||
|
|
|
@ -45,6 +45,7 @@ class EntityMapStorage:
|
|||
"""Get a pairing cache item."""
|
||||
return self.storage_data.get(homekit_id)
|
||||
|
||||
@callback
|
||||
def async_create_or_update_map(self, homekit_id, config_num, accessories):
|
||||
"""Create a new pairing cache."""
|
||||
data = {"config_num": config_num, "accessories": accessories}
|
||||
|
@ -52,6 +53,7 @@ class EntityMapStorage:
|
|||
self._async_schedule_save()
|
||||
return data
|
||||
|
||||
@callback
|
||||
def async_delete_map(self, homekit_id):
|
||||
"""Delete pairing cache."""
|
||||
if homekit_id not in self.storage_data:
|
||||
|
|
|
@ -4,6 +4,7 @@ import logging
|
|||
from homekit.model.characteristics import CharacteristicsTypes
|
||||
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
|
@ -17,6 +18,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
@callback
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] not in ("switch", "outlet"):
|
||||
return False
|
||||
|
|
|
@ -13,6 +13,7 @@ from homeassistant.components.device_tracker import (
|
|||
)
|
||||
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
||||
from homeassistant.const import CONF_URL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import entity_registry
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
|
@ -70,6 +71,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
async_add_new_entities(hass, router.url, async_add_entities, tracked)
|
||||
|
||||
|
||||
@callback
|
||||
def async_add_new_entities(hass, router_url, async_add_entities, tracked):
|
||||
"""Add new entities that are not already being tracked."""
|
||||
router = hass.data[DOMAIN].routers[router_url]
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import asyncio
|
||||
|
||||
from homeassistant.core import callback
|
||||
|
||||
|
||||
async def async_pulse(hass, ihc_controller, ihc_id: int):
|
||||
"""Send a short on/off pulse to an IHC controller resource."""
|
||||
|
@ -10,6 +12,7 @@ async def async_pulse(hass, ihc_controller, ihc_id: int):
|
|||
await async_set_bool(hass, ihc_controller, ihc_id, False)
|
||||
|
||||
|
||||
@callback
|
||||
def async_set_bool(hass, ihc_controller, ihc_id: int, value: bool):
|
||||
"""Set a bool value on an IHC controller resource."""
|
||||
return hass.async_add_executor_job(
|
||||
|
@ -17,6 +20,7 @@ def async_set_bool(hass, ihc_controller, ihc_id: int, value: bool):
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_set_int(hass, ihc_controller, ihc_id: int, value: int):
|
||||
"""Set a int value on an IHC controller resource."""
|
||||
return hass.async_add_executor_job(
|
||||
|
|
|
@ -107,12 +107,9 @@ class ImageProcessingEntity(Entity):
|
|||
"""Process image."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_process_image(self, image):
|
||||
"""Process image.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.process_image, image)
|
||||
async def async_process_image(self, image):
|
||||
"""Process image."""
|
||||
return await self.hass.async_add_job(self.process_image, image)
|
||||
|
||||
async def async_update(self):
|
||||
"""Update image and process it.
|
||||
|
|
|
@ -326,6 +326,7 @@ class InputDatetime(RestoreEntity):
|
|||
"""Return unique id of the entity."""
|
||||
return self._config[CONF_ID]
|
||||
|
||||
@callback
|
||||
def async_set_datetime(self, date_val, time_val):
|
||||
"""Set a new date / time."""
|
||||
if self.has_date and self.has_time and date_val and time_val:
|
||||
|
|
|
@ -48,9 +48,8 @@ class KiraRemote(Entity):
|
|||
_LOGGER.info("Sending Command: %s to %s", *code_tuple)
|
||||
self._kira.sendCode(code_tuple)
|
||||
|
||||
def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to a device.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.send_command, command, **kwargs))
|
||||
async def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to a device."""
|
||||
return await self.hass.async_add_job(
|
||||
ft.partial(self.send_command, command, **kwargs)
|
||||
)
|
||||
|
|
|
@ -330,10 +330,7 @@ class KNXClimate(ClimateDevice):
|
|||
return list(filter(None, _presets))
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set new preset mode.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Set new preset mode."""
|
||||
if self.device.mode.supports_operation_mode:
|
||||
knx_operation_mode = HVACOperationMode(PRESET_MODES_INV.get(preset_mode))
|
||||
await self.device.mode.set_operation_mode(knx_operation_mode)
|
||||
|
|
|
@ -668,20 +668,14 @@ class KodiDevice(MediaPlayerDevice):
|
|||
assert (await self.server.Input.ExecuteAction("volumedown")) == "OK"
|
||||
|
||||
@cmd
|
||||
def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.server.Application.SetVolume(int(volume * 100))
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
await self.server.Application.SetVolume(int(volume * 100))
|
||||
|
||||
@cmd
|
||||
def async_mute_volume(self, mute):
|
||||
"""Mute (true) or unmute (false) media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.server.Application.SetMute(mute)
|
||||
async def async_mute_volume(self, mute):
|
||||
"""Mute (true) or unmute (false) media player."""
|
||||
await self.server.Application.SetMute(mute)
|
||||
|
||||
async def async_set_play_state(self, state):
|
||||
"""Handle play/pause/toggle."""
|
||||
|
@ -691,28 +685,19 @@ class KodiDevice(MediaPlayerDevice):
|
|||
await self.server.Player.PlayPause(players[0]["playerid"], state)
|
||||
|
||||
@cmd
|
||||
def async_media_play_pause(self):
|
||||
"""Pause media on media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_set_play_state("toggle")
|
||||
async def async_media_play_pause(self):
|
||||
"""Pause media on media player."""
|
||||
await self.async_set_play_state("toggle")
|
||||
|
||||
@cmd
|
||||
def async_media_play(self):
|
||||
"""Play media.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_set_play_state(True)
|
||||
async def async_media_play(self):
|
||||
"""Play media."""
|
||||
await self.async_set_play_state(True)
|
||||
|
||||
@cmd
|
||||
def async_media_pause(self):
|
||||
"""Pause the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_set_play_state(False)
|
||||
async def async_media_pause(self):
|
||||
"""Pause the media player."""
|
||||
await self.async_set_play_state(False)
|
||||
|
||||
@cmd
|
||||
async def async_media_stop(self):
|
||||
|
@ -735,20 +720,14 @@ class KodiDevice(MediaPlayerDevice):
|
|||
await self.server.Player.GoTo(players[0]["playerid"], direction)
|
||||
|
||||
@cmd
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._goto("next")
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
await self._goto("next")
|
||||
|
||||
@cmd
|
||||
def async_media_previous_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._goto("previous")
|
||||
async def async_media_previous_track(self):
|
||||
"""Send next track command."""
|
||||
await self._goto("previous")
|
||||
|
||||
@cmd
|
||||
async def async_media_seek(self, position):
|
||||
|
@ -772,21 +751,18 @@ class KodiDevice(MediaPlayerDevice):
|
|||
await self.server.Player.Seek(players[0]["playerid"], time)
|
||||
|
||||
@cmd
|
||||
def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Send the play_media command to the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Send the play_media command to the media player."""
|
||||
if media_type == "CHANNEL":
|
||||
return self.server.Player.Open({"item": {"channelid": int(media_id)}})
|
||||
if media_type == "PLAYLIST":
|
||||
return self.server.Player.Open({"item": {"playlistid": int(media_id)}})
|
||||
if media_type == "DIRECTORY":
|
||||
return self.server.Player.Open({"item": {"directory": str(media_id)}})
|
||||
if media_type == "PLUGIN":
|
||||
return self.server.Player.Open({"item": {"file": str(media_id)}})
|
||||
|
||||
return self.server.Player.Open({"item": {"file": str(media_id)}})
|
||||
await self.server.Player.Open({"item": {"channelid": int(media_id)}})
|
||||
elif media_type == "PLAYLIST":
|
||||
await self.server.Player.Open({"item": {"playlistid": int(media_id)}})
|
||||
elif media_type == "DIRECTORY":
|
||||
await self.server.Player.Open({"item": {"directory": str(media_id)}})
|
||||
elif media_type == "PLUGIN":
|
||||
await self.server.Player.Open({"item": {"file": str(media_id)}})
|
||||
else:
|
||||
await self.server.Player.Open({"item": {"file": str(media_id)}})
|
||||
|
||||
async def async_set_shuffle(self, shuffle):
|
||||
"""Set shuffle mode, for the first player."""
|
||||
|
|
|
@ -5,7 +5,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.device_automation import toggle_entity
|
||||
from homeassistant.const import CONF_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.condition import ConditionCheckerType
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
|
@ -16,6 +16,7 @@ CONDITION_SCHEMA = toggle_entity.CONDITION_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> ConditionCheckerType:
|
||||
|
|
|
@ -104,34 +104,25 @@ class LockDevice(Entity):
|
|||
"""Lock the lock."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_lock(self, **kwargs):
|
||||
"""Lock the lock.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.lock, **kwargs))
|
||||
async def async_lock(self, **kwargs):
|
||||
"""Lock the lock."""
|
||||
await self.hass.async_add_job(ft.partial(self.lock, **kwargs))
|
||||
|
||||
def unlock(self, **kwargs):
|
||||
"""Unlock the lock."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_unlock(self, **kwargs):
|
||||
"""Unlock the lock.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.unlock, **kwargs))
|
||||
async def async_unlock(self, **kwargs):
|
||||
"""Unlock the lock."""
|
||||
await self.hass.async_add_job(ft.partial(self.unlock, **kwargs))
|
||||
|
||||
def open(self, **kwargs):
|
||||
"""Open the door latch."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_open(self, **kwargs):
|
||||
"""Open the door latch.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.open, **kwargs))
|
||||
async def async_open(self, **kwargs):
|
||||
"""Open the door latch."""
|
||||
await self.hass.async_add_job(ft.partial(self.open, **kwargs))
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||
STATE_LOCKED,
|
||||
STATE_UNLOCKED,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -63,6 +63,7 @@ async def async_get_conditions(hass: HomeAssistant, device_id: str) -> List[dict
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -141,6 +141,7 @@ class Mailbox:
|
|||
self.hass = hass
|
||||
self.name = name
|
||||
|
||||
@callback
|
||||
def async_update(self):
|
||||
"""Send event notification of updated mailbox."""
|
||||
self.hass.bus.async_fire(EVENT)
|
||||
|
@ -168,7 +169,7 @@ class Mailbox:
|
|||
"""Return a list of the current messages."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_delete(self, msgid):
|
||||
async def async_delete(self, msgid):
|
||||
"""Delete the specified messages."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -236,7 +237,7 @@ class MailboxDeleteView(MailboxView):
|
|||
async def delete(self, request, platform, msgid):
|
||||
"""Delete items."""
|
||||
mailbox = self.get_mailbox(platform)
|
||||
mailbox.async_delete(msgid)
|
||||
await mailbox.async_delete(msgid)
|
||||
|
||||
|
||||
class MailboxMediaView(MailboxView):
|
||||
|
|
|
@ -29,7 +29,6 @@ from homeassistant.const import (
|
|||
STATE_ALARM_PENDING,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import async_track_state_change, track_point_in_time
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -427,17 +426,16 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
|
|||
self.hass, self.entity_id, self._async_state_changed_listener
|
||||
)
|
||||
|
||||
@callback
|
||||
def message_received(msg):
|
||||
async def message_received(msg):
|
||||
"""Run when new MQTT message has been received."""
|
||||
if msg.payload == self._payload_disarm:
|
||||
self.async_alarm_disarm(self._code)
|
||||
await self.async_alarm_disarm(self._code)
|
||||
elif msg.payload == self._payload_arm_home:
|
||||
self.async_alarm_arm_home(self._code)
|
||||
await self.async_alarm_arm_home(self._code)
|
||||
elif msg.payload == self._payload_arm_away:
|
||||
self.async_alarm_arm_away(self._code)
|
||||
await self.async_alarm_arm_away(self._code)
|
||||
elif msg.payload == self._payload_arm_night:
|
||||
self.async_alarm_arm_night(self._code)
|
||||
await self.async_alarm_arm_night(self._code)
|
||||
else:
|
||||
_LOGGER.warning("Received unexpected payload: %s", msg.payload)
|
||||
return
|
||||
|
|
|
@ -485,122 +485,89 @@ class MediaPlayerDevice(Entity):
|
|||
"""Turn the media player on."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_turn_on(self):
|
||||
"""Turn the media player on.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.turn_on)
|
||||
async def async_turn_on(self):
|
||||
"""Turn the media player on."""
|
||||
await self.hass.async_add_job(self.turn_on)
|
||||
|
||||
def turn_off(self):
|
||||
"""Turn the media player off."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_turn_off(self):
|
||||
"""Turn the media player off.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.turn_off)
|
||||
async def async_turn_off(self):
|
||||
"""Turn the media player off."""
|
||||
await self.hass.async_add_job(self.turn_off)
|
||||
|
||||
def mute_volume(self, mute):
|
||||
"""Mute the volume."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_mute_volume(self, mute):
|
||||
"""Mute the volume.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.mute_volume, mute)
|
||||
async def async_mute_volume(self, mute):
|
||||
"""Mute the volume."""
|
||||
await self.hass.async_add_job(self.mute_volume, mute)
|
||||
|
||||
def set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.set_volume_level, volume)
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
await self.hass.async_add_job(self.set_volume_level, volume)
|
||||
|
||||
def media_play(self):
|
||||
"""Send play command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_play(self):
|
||||
"""Send play command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_play)
|
||||
async def async_media_play(self):
|
||||
"""Send play command."""
|
||||
await self.hass.async_add_job(self.media_play)
|
||||
|
||||
def media_pause(self):
|
||||
"""Send pause command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Send pause command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_pause)
|
||||
async def async_media_pause(self):
|
||||
"""Send pause command."""
|
||||
await self.hass.async_add_job(self.media_pause)
|
||||
|
||||
def media_stop(self):
|
||||
"""Send stop command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_stop(self):
|
||||
"""Send stop command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_stop)
|
||||
async def async_media_stop(self):
|
||||
"""Send stop command."""
|
||||
await self.hass.async_add_job(self.media_stop)
|
||||
|
||||
def media_previous_track(self):
|
||||
"""Send previous track command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send previous track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_previous_track)
|
||||
async def async_media_previous_track(self):
|
||||
"""Send previous track command."""
|
||||
await self.hass.async_add_job(self.media_previous_track)
|
||||
|
||||
def media_next_track(self):
|
||||
"""Send next track command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_next_track)
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
await self.hass.async_add_job(self.media_next_track)
|
||||
|
||||
def media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.media_seek, position)
|
||||
async def async_media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
await self.hass.async_add_job(self.media_seek, position)
|
||||
|
||||
def play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(
|
||||
async def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media."""
|
||||
await self.hass.async_add_job(
|
||||
ft.partial(self.play_media, media_type, media_id, **kwargs)
|
||||
)
|
||||
|
||||
|
@ -608,45 +575,33 @@ class MediaPlayerDevice(Entity):
|
|||
"""Select input source."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_select_source(self, source):
|
||||
"""Select input source.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.select_source, source)
|
||||
async def async_select_source(self, source):
|
||||
"""Select input source."""
|
||||
await self.hass.async_add_job(self.select_source, source)
|
||||
|
||||
def select_sound_mode(self, sound_mode):
|
||||
"""Select sound mode."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_select_sound_mode(self, sound_mode):
|
||||
"""Select sound mode.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.select_sound_mode, sound_mode)
|
||||
async def async_select_sound_mode(self, sound_mode):
|
||||
"""Select sound mode."""
|
||||
await self.hass.async_add_job(self.select_sound_mode, sound_mode)
|
||||
|
||||
def clear_playlist(self):
|
||||
"""Clear players playlist."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_clear_playlist(self):
|
||||
"""Clear players playlist.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.clear_playlist)
|
||||
async def async_clear_playlist(self):
|
||||
"""Clear players playlist."""
|
||||
await self.hass.async_add_job(self.clear_playlist)
|
||||
|
||||
def set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.set_shuffle, shuffle)
|
||||
async def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode."""
|
||||
await self.hass.async_add_job(self.set_shuffle, shuffle)
|
||||
|
||||
# No need to overwrite these.
|
||||
@property
|
||||
|
@ -714,18 +669,17 @@ class MediaPlayerDevice(Entity):
|
|||
"""Boolean if shuffle is supported."""
|
||||
return bool(self.supported_features & SUPPORT_SHUFFLE_SET)
|
||||
|
||||
def async_toggle(self):
|
||||
"""Toggle the power on the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_toggle(self):
|
||||
"""Toggle the power on the media player."""
|
||||
if hasattr(self, "toggle"):
|
||||
# pylint: disable=no-member
|
||||
return self.hass.async_add_job(self.toggle)
|
||||
await self.hass.async_add_job(self.toggle)
|
||||
return
|
||||
|
||||
if self.state in [STATE_OFF, STATE_IDLE]:
|
||||
return self.async_turn_on()
|
||||
return self.async_turn_off()
|
||||
await self.async_turn_on()
|
||||
else:
|
||||
await self.async_turn_off()
|
||||
|
||||
async def async_volume_up(self):
|
||||
"""Turn volume up for media player.
|
||||
|
@ -753,18 +707,17 @@ class MediaPlayerDevice(Entity):
|
|||
if self.volume_level > 0 and self.supported_features & SUPPORT_VOLUME_SET:
|
||||
await self.async_set_volume_level(max(0, self.volume_level - 0.1))
|
||||
|
||||
def async_media_play_pause(self):
|
||||
"""Play or pause the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_play_pause(self):
|
||||
"""Play or pause the media player."""
|
||||
if hasattr(self, "media_play_pause"):
|
||||
# pylint: disable=no-member
|
||||
return self.hass.async_add_job(self.media_play_pause)
|
||||
await self.hass.async_add_job(self.media_play_pause)
|
||||
return
|
||||
|
||||
if self.state == STATE_PLAYING:
|
||||
return self.async_media_pause()
|
||||
return self.async_media_play()
|
||||
await self.async_media_pause()
|
||||
else:
|
||||
await self.async_media_play()
|
||||
|
||||
@property
|
||||
def entity_picture(self):
|
||||
|
|
|
@ -16,7 +16,7 @@ from homeassistant.const import (
|
|||
STATE_PAUSED,
|
||||
STATE_PLAYING,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -95,6 +95,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -774,27 +774,21 @@ class MQTT:
|
|||
async def async_publish(
|
||||
self, topic: str, payload: PublishPayloadType, qos: int, retain: bool
|
||||
) -> None:
|
||||
"""Publish a MQTT message.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Publish a MQTT message."""
|
||||
async with self._paho_lock:
|
||||
_LOGGER.debug("Transmitting message on %s: %s", topic, payload)
|
||||
await self.hass.async_add_job(
|
||||
await self.hass.async_add_executor_job(
|
||||
self._mqttc.publish, topic, payload, qos, retain
|
||||
)
|
||||
|
||||
async def async_connect(self) -> str:
|
||||
"""Connect to the host. Does process messages yet.
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
"""Connect to the host. Does process messages yet."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
result: int = None
|
||||
try:
|
||||
result = await self.hass.async_add_job(
|
||||
result = await self.hass.async_add_executor_job(
|
||||
self._mqttc.connect, self.broker, self.port, self.keepalive
|
||||
)
|
||||
except OSError as err:
|
||||
|
@ -808,19 +802,15 @@ class MQTT:
|
|||
self._mqttc.loop_start()
|
||||
return CONNECTION_SUCCESS
|
||||
|
||||
@callback
|
||||
def async_disconnect(self):
|
||||
"""Stop the MQTT client.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_disconnect(self):
|
||||
"""Stop the MQTT client."""
|
||||
|
||||
def stop():
|
||||
"""Stop the MQTT client."""
|
||||
self._mqttc.disconnect()
|
||||
self._mqttc.loop_stop()
|
||||
|
||||
return self.hass.async_add_job(stop)
|
||||
await self.hass.async_add_executor_job(stop)
|
||||
|
||||
async def async_subscribe(
|
||||
self,
|
||||
|
@ -865,7 +855,9 @@ class MQTT:
|
|||
"""
|
||||
async with self._paho_lock:
|
||||
result: int = None
|
||||
result, _ = await self.hass.async_add_job(self._mqttc.unsubscribe, topic)
|
||||
result, _ = await self.hass.async_add_executor_job(
|
||||
self._mqttc.unsubscribe, topic
|
||||
)
|
||||
_raise_on_error(result)
|
||||
|
||||
async def _async_perform_subscription(self, topic: str, qos: int) -> None:
|
||||
|
@ -874,7 +866,9 @@ class MQTT:
|
|||
|
||||
async with self._paho_lock:
|
||||
result: int = None
|
||||
result, _ = await self.hass.async_add_job(self._mqttc.subscribe, topic, qos)
|
||||
result, _ = await self.hass.async_add_executor_job(
|
||||
self._mqttc.subscribe, topic, qos
|
||||
)
|
||||
_raise_on_error(result)
|
||||
|
||||
def _mqtt_on_connect(self, _mqttc, _userdata, _flags, result_code: int) -> None:
|
||||
|
@ -1010,10 +1004,7 @@ class MqttAttributes(Entity):
|
|||
self._attributes_config = config
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe MQTT events.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Subscribe MQTT events."""
|
||||
await super().async_added_to_hass()
|
||||
await self._attributes_subscribe_topics()
|
||||
|
||||
|
@ -1080,10 +1071,7 @@ class MqttAvailability(Entity):
|
|||
self._avail_config = config
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe MQTT events.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Subscribe MQTT events."""
|
||||
await super().async_added_to_hass()
|
||||
await self._availability_subscribe_topics()
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Camera that loads a picture from an MQTT topic."""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -130,8 +128,7 @@ class MqttCamera(MqttDiscoveryUpdate, MqttEntityDeviceInfo, Camera):
|
|||
self.hass, self._sub_state
|
||||
)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_camera_image(self):
|
||||
async def async_camera_image(self):
|
||||
"""Return image response."""
|
||||
return self._last_image
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Support for a local MQTT broker."""
|
||||
import asyncio
|
||||
import logging
|
||||
import tempfile
|
||||
|
||||
|
@ -29,8 +28,7 @@ HBMQTT_CONFIG_SCHEMA = vol.Any(
|
|||
)
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_start(hass, password, server_config):
|
||||
async def async_start(hass, password, server_config):
|
||||
"""Initialize MQTT Server.
|
||||
|
||||
This method is a coroutine.
|
||||
|
@ -47,17 +45,16 @@ def async_start(hass, password, server_config):
|
|||
server_config = gen_server_config
|
||||
|
||||
broker = Broker(server_config, hass.loop)
|
||||
yield from broker.start()
|
||||
await broker.start()
|
||||
except BrokerException:
|
||||
_LOGGER.exception("Error initializing MQTT server")
|
||||
return False, None
|
||||
finally:
|
||||
passwd.close()
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_shutdown_mqtt_server(event):
|
||||
async def async_shutdown_mqtt_server(event):
|
||||
"""Shut down the MQTT server."""
|
||||
yield from broker.shutdown()
|
||||
await broker.shutdown()
|
||||
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_shutdown_mqtt_server)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import logging
|
|||
from homeassistant.components.binary_sensor import DOMAIN, BinarySensorDevice
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY
|
||||
from homeassistant.core import callback
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -81,6 +82,7 @@ class MyStromBinarySensor(BinarySensorDevice):
|
|||
"""Return true if the binary sensor is on."""
|
||||
return self._state
|
||||
|
||||
@callback
|
||||
def async_on_update(self, value):
|
||||
"""Receive an update."""
|
||||
self._state = value
|
||||
|
|
|
@ -177,10 +177,9 @@ class BaseNotificationService:
|
|||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_send_message(self, message, **kwargs):
|
||||
async def async_send_message(self, message, **kwargs):
|
||||
"""Send a message.
|
||||
|
||||
kwargs can contain ATTR_TITLE to specify a title.
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(partial(self.send_message, message, **kwargs))
|
||||
await self.hass.async_add_job(partial(self.send_message, message, **kwargs))
|
||||
|
|
|
@ -59,6 +59,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
server_id = config_entry.data[CONF_SERVER_IDENTIFIER]
|
||||
registry = await async_get_registry(hass)
|
||||
|
||||
@callback
|
||||
def async_new_media_players(new_entities):
|
||||
_async_add_entities(
|
||||
hass, registry, config_entry, async_add_entities, server_id, new_entities
|
||||
|
|
|
@ -119,12 +119,9 @@ class RemoteDevice(ToggleEntity):
|
|||
"""Send a command to a device."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to a device.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(
|
||||
async def async_send_command(self, command, **kwargs):
|
||||
"""Send a command to a device."""
|
||||
await self.hass.async_add_executor_job(
|
||||
ft.partial(self.send_command, command, **kwargs)
|
||||
)
|
||||
|
||||
|
@ -132,11 +129,6 @@ class RemoteDevice(ToggleEntity):
|
|||
"""Learn a command from a device."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_learn_command(self, **kwargs):
|
||||
"""Learn a command from a device.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_executor_job(
|
||||
ft.partial(self.learn_command, **kwargs)
|
||||
)
|
||||
async def async_learn_command(self, **kwargs):
|
||||
"""Learn a command from a device."""
|
||||
await self.hass.async_add_executor_job(ft.partial(self.learn_command, **kwargs))
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.const import (
|
|||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
@ -55,6 +56,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
async def async_setup(hass, config):
|
||||
"""Set up the REST command component."""
|
||||
|
||||
@callback
|
||||
def async_register_rest_command(name, command_config):
|
||||
"""Create service for rest command."""
|
||||
websession = async_get_clientsession(hass, command_config.get(CONF_VERIFY_SSL))
|
||||
|
|
|
@ -552,10 +552,10 @@ class SwitchableRflinkDevice(RflinkCommand, RestoreEntity):
|
|||
elif command in ["off", "alloff"]:
|
||||
self._state = False
|
||||
|
||||
def async_turn_on(self, **kwargs):
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the device on."""
|
||||
return self._async_handle_command("turn_on")
|
||||
await self._async_handle_command("turn_on")
|
||||
|
||||
def async_turn_off(self, **kwargs):
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the device off."""
|
||||
return self._async_handle_command("turn_off")
|
||||
await self._async_handle_command("turn_off")
|
||||
|
|
|
@ -146,17 +146,17 @@ class RflinkCover(RflinkCommand, CoverDevice, RestoreEntity):
|
|||
"""Return True because covers can be stopped midway."""
|
||||
return True
|
||||
|
||||
def async_close_cover(self, **kwargs):
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Turn the device close."""
|
||||
return self._async_handle_command("close_cover")
|
||||
await self._async_handle_command("close_cover")
|
||||
|
||||
def async_open_cover(self, **kwargs):
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Turn the device open."""
|
||||
return self._async_handle_command("open_cover")
|
||||
await self._async_handle_command("open_cover")
|
||||
|
||||
def async_stop_cover(self, **kwargs):
|
||||
async def async_stop_cover(self, **kwargs):
|
||||
"""Turn the device stop."""
|
||||
return self._async_handle_command("stop_cover")
|
||||
await self._async_handle_command("stop_cover")
|
||||
|
||||
|
||||
class InvertedRflinkCover(RflinkCover):
|
||||
|
|
|
@ -185,22 +185,23 @@ class RussoundZoneDevice(MediaPlayerDevice):
|
|||
"""
|
||||
return float(self._zone_var("volume", 0)) / 50.0
|
||||
|
||||
def async_turn_off(self):
|
||||
async def async_turn_off(self):
|
||||
"""Turn off the zone."""
|
||||
return self._russ.send_zone_event(self._zone_id, "ZoneOff")
|
||||
await self._russ.send_zone_event(self._zone_id, "ZoneOff")
|
||||
|
||||
def async_turn_on(self):
|
||||
async def async_turn_on(self):
|
||||
"""Turn on the zone."""
|
||||
return self._russ.send_zone_event(self._zone_id, "ZoneOn")
|
||||
await self._russ.send_zone_event(self._zone_id, "ZoneOn")
|
||||
|
||||
def async_set_volume_level(self, volume):
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Set the volume level."""
|
||||
rvol = int(volume * 50.0)
|
||||
return self._russ.send_zone_event(self._zone_id, "KeyPress", "Volume", rvol)
|
||||
await self._russ.send_zone_event(self._zone_id, "KeyPress", "Volume", rvol)
|
||||
|
||||
def async_select_source(self, source):
|
||||
async def async_select_source(self, source):
|
||||
"""Select the source input for this zone."""
|
||||
for source_id, name in self._sources:
|
||||
if name.lower() != source.lower():
|
||||
continue
|
||||
return self._russ.send_zone_event(self._zone_id, "SelectSource", source_id)
|
||||
await self._russ.send_zone_event(self._zone_id, "SelectSource", source_id)
|
||||
break
|
||||
|
|
|
@ -225,6 +225,7 @@ class SAJsensor(Entity):
|
|||
"""Return the date when the sensor was last updated."""
|
||||
return self._sensor.date
|
||||
|
||||
@callback
|
||||
def async_update_values(self, unknown_state=False):
|
||||
"""Update this sensor."""
|
||||
update = False
|
||||
|
|
|
@ -94,9 +94,6 @@ class Scene(Entity):
|
|||
"""Activate scene. Try to get entities into requested state."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_activate(self):
|
||||
"""Activate scene. Try to get entities into requested state.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(self.activate)
|
||||
async def async_activate(self):
|
||||
"""Activate scene. Try to get entities into requested state."""
|
||||
await self.hass.async_add_job(self.activate)
|
||||
|
|
|
@ -22,7 +22,7 @@ from homeassistant.const import (
|
|||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv
|
||||
from homeassistant.helpers.entity_registry import (
|
||||
async_entries_for_device,
|
||||
|
@ -128,6 +128,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -153,15 +153,14 @@ class ShoppingData:
|
|||
self.items = [itm for itm in self.items if not itm["complete"]]
|
||||
self.hass.async_add_job(self.save)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_load(self):
|
||||
async def async_load(self):
|
||||
"""Load items."""
|
||||
|
||||
def load():
|
||||
"""Load the items synchronously."""
|
||||
return load_json(self.hass.config.path(PERSISTENCE), default=[])
|
||||
|
||||
self.items = yield from self.hass.async_add_job(load)
|
||||
self.items = await self.hass.async_add_executor_job(load)
|
||||
|
||||
def save(self):
|
||||
"""Save the items."""
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.const import (
|
|||
CONF_VERIFY_SSL,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
@ -210,6 +211,7 @@ class SMAsensor(Entity):
|
|||
"""SMA sensors are updated & don't poll."""
|
||||
return False
|
||||
|
||||
@callback
|
||||
def async_update_values(self):
|
||||
"""Update this sensor."""
|
||||
update = False
|
||||
|
|
|
@ -281,12 +281,9 @@ class SqueezeBoxDevice(MediaPlayerDevice):
|
|||
return STATE_IDLE
|
||||
return None
|
||||
|
||||
def async_query(self, *parameters):
|
||||
"""Send a command to the LMS.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._lms.async_query(*parameters, player=self._id)
|
||||
async def async_query(self, *parameters):
|
||||
"""Send a command to the LMS."""
|
||||
return await self._lms.async_query(*parameters, player=self._id)
|
||||
|
||||
async def async_update(self):
|
||||
"""Retrieve the current state of the player."""
|
||||
|
@ -420,121 +417,85 @@ class SqueezeBoxDevice(MediaPlayerDevice):
|
|||
"""Flag media player features that are supported."""
|
||||
return SUPPORT_SQUEEZEBOX
|
||||
|
||||
def async_turn_off(self):
|
||||
"""Turn off media player.
|
||||
async def async_turn_off(self):
|
||||
"""Turn off media player."""
|
||||
await self.async_query("power", "0")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("power", "0")
|
||||
async def async_volume_up(self):
|
||||
"""Volume up media player."""
|
||||
await self.async_query("mixer", "volume", "+5")
|
||||
|
||||
def async_volume_up(self):
|
||||
"""Volume up media player.
|
||||
async def async_volume_down(self):
|
||||
"""Volume down media player."""
|
||||
await self.async_query("mixer", "volume", "-5")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("mixer", "volume", "+5")
|
||||
|
||||
def async_volume_down(self):
|
||||
"""Volume down media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("mixer", "volume", "-5")
|
||||
|
||||
def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
volume_percent = str(int(volume * 100))
|
||||
return self.async_query("mixer", "volume", volume_percent)
|
||||
await self.async_query("mixer", "volume", volume_percent)
|
||||
|
||||
def async_mute_volume(self, mute):
|
||||
"""Mute (true) or unmute (false) media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_mute_volume(self, mute):
|
||||
"""Mute (true) or unmute (false) media player."""
|
||||
mute_numeric = "1" if mute else "0"
|
||||
return self.async_query("mixer", "muting", mute_numeric)
|
||||
await self.async_query("mixer", "muting", mute_numeric)
|
||||
|
||||
def async_media_play_pause(self):
|
||||
"""Send pause command to media player.
|
||||
async def async_media_play_pause(self):
|
||||
"""Send pause command to media player."""
|
||||
await self.async_query("pause")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("pause")
|
||||
async def async_media_play(self):
|
||||
"""Send play command to media player."""
|
||||
await self.async_query("play")
|
||||
|
||||
def async_media_play(self):
|
||||
"""Send play command to media player.
|
||||
async def async_media_pause(self):
|
||||
"""Send pause command to media player."""
|
||||
await self.async_query("pause", "1")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("play")
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
await self.async_query("playlist", "index", "+1")
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Send pause command to media player.
|
||||
async def async_media_previous_track(self):
|
||||
"""Send next track command."""
|
||||
await self.async_query("playlist", "index", "-1")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("pause", "1")
|
||||
async def async_media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
await self.async_query("time", position)
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
async def async_turn_on(self):
|
||||
"""Turn the media player on."""
|
||||
await self.async_query("power", "1")
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("playlist", "index", "+1")
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("playlist", "index", "-1")
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("time", position)
|
||||
|
||||
def async_turn_on(self):
|
||||
"""Turn the media player on.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.async_query("power", "1")
|
||||
|
||||
def async_play_media(self, media_type, media_id, **kwargs):
|
||||
async def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""
|
||||
Send the play_media command to the media player.
|
||||
|
||||
If ATTR_MEDIA_ENQUEUE is True, add `media_id` to the current playlist.
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
if kwargs.get(ATTR_MEDIA_ENQUEUE):
|
||||
return self._add_uri_to_playlist(media_id)
|
||||
await self._add_uri_to_playlist(media_id)
|
||||
return
|
||||
|
||||
return self._play_uri(media_id)
|
||||
await self._play_uri(media_id)
|
||||
|
||||
def _play_uri(self, media_id):
|
||||
async def _play_uri(self, media_id):
|
||||
"""Replace the current play list with the uri."""
|
||||
return self.async_query("playlist", "play", media_id)
|
||||
await self.async_query("playlist", "play", media_id)
|
||||
|
||||
def _add_uri_to_playlist(self, media_id):
|
||||
async def _add_uri_to_playlist(self, media_id):
|
||||
"""Add an item to the existing playlist."""
|
||||
return self.async_query("playlist", "add", media_id)
|
||||
await self.async_query("playlist", "add", media_id)
|
||||
|
||||
def async_set_shuffle(self, shuffle):
|
||||
async def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode."""
|
||||
return self.async_query("playlist", "shuffle", int(shuffle))
|
||||
await self.async_query("playlist", "shuffle", int(shuffle))
|
||||
|
||||
def async_clear_playlist(self):
|
||||
async def async_clear_playlist(self):
|
||||
"""Send the media player the command for clear playlist."""
|
||||
return self.async_query("playlist", "clear")
|
||||
await self.async_query("playlist", "clear")
|
||||
|
||||
def async_call_method(self, command, parameters=None):
|
||||
async def async_call_method(self, command, parameters=None):
|
||||
"""
|
||||
Call Squeezebox JSON/RPC method.
|
||||
|
||||
|
@ -545,4 +506,4 @@ class SqueezeBoxDevice(MediaPlayerDevice):
|
|||
if parameters:
|
||||
for parameter in parameters:
|
||||
all_params.append(parameter)
|
||||
return self.async_query(*all_params)
|
||||
await self.async_query(*all_params)
|
||||
|
|
|
@ -5,7 +5,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.device_automation import toggle_entity
|
||||
from homeassistant.const import CONF_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.condition import ConditionCheckerType
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
|
@ -16,6 +16,7 @@ CONDITION_SCHEMA = toggle_entity.CONDITION_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> ConditionCheckerType:
|
||||
|
|
|
@ -124,17 +124,11 @@ class SwitcherControl(SwitchDevice):
|
|||
self.async_schedule_update_ha_state()
|
||||
|
||||
async def async_turn_on(self, **kwargs: Dict) -> None:
|
||||
"""Turn the entity on.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Turn the entity on."""
|
||||
await self._control_device(True)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Dict) -> None:
|
||||
"""Turn the entity off.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Turn the entity off."""
|
||||
await self._control_device(False)
|
||||
|
||||
async def _control_device(self, send_on: bool) -> None:
|
||||
|
|
|
@ -501,14 +501,12 @@ class Provider:
|
|||
"""Load tts audio file from provider."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_get_tts_audio(self, message, language, options=None):
|
||||
async def async_get_tts_audio(self, message, language, options=None):
|
||||
"""Load tts audio file from provider.
|
||||
|
||||
Return a tuple of file extension and data as bytes.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(
|
||||
return await self.hass.async_add_job(
|
||||
ft.partial(self.get_tts_audio, message, language, options=options)
|
||||
)
|
||||
|
||||
|
|
|
@ -137,10 +137,7 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
|||
self._state_template.hass = hass
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to children and template state changes.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
"""Subscribe to children and template state changes."""
|
||||
|
||||
@callback
|
||||
def async_on_dependency_update(*_):
|
||||
|
@ -416,132 +413,79 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
|||
"""When was the position of the current playing media valid."""
|
||||
return self._child_attr(ATTR_MEDIA_POSITION_UPDATED_AT)
|
||||
|
||||
def async_turn_on(self):
|
||||
"""Turn the media player on.
|
||||
async def async_turn_on(self):
|
||||
"""Turn the media player on."""
|
||||
await self._async_call_service(SERVICE_TURN_ON, allow_override=True)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_TURN_ON, allow_override=True)
|
||||
async def async_turn_off(self):
|
||||
"""Turn the media player off."""
|
||||
await self._async_call_service(SERVICE_TURN_OFF, allow_override=True)
|
||||
|
||||
def async_turn_off(self):
|
||||
"""Turn the media player off.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_TURN_OFF, allow_override=True)
|
||||
|
||||
def async_mute_volume(self, mute):
|
||||
"""Mute the volume.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_mute_volume(self, mute):
|
||||
"""Mute the volume."""
|
||||
data = {ATTR_MEDIA_VOLUME_MUTED: mute}
|
||||
return self._async_call_service(SERVICE_VOLUME_MUTE, data, allow_override=True)
|
||||
await self._async_call_service(SERVICE_VOLUME_MUTE, data, allow_override=True)
|
||||
|
||||
def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
data = {ATTR_MEDIA_VOLUME_LEVEL: volume}
|
||||
return self._async_call_service(SERVICE_VOLUME_SET, data, allow_override=True)
|
||||
await self._async_call_service(SERVICE_VOLUME_SET, data, allow_override=True)
|
||||
|
||||
def async_media_play(self):
|
||||
"""Send play command.
|
||||
async def async_media_play(self):
|
||||
"""Send play command."""
|
||||
await self._async_call_service(SERVICE_MEDIA_PLAY)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_PLAY)
|
||||
async def async_media_pause(self):
|
||||
"""Send pause command."""
|
||||
await self._async_call_service(SERVICE_MEDIA_PAUSE)
|
||||
|
||||
def async_media_pause(self):
|
||||
"""Send pause command.
|
||||
async def async_media_stop(self):
|
||||
"""Send stop command."""
|
||||
await self._async_call_service(SERVICE_MEDIA_STOP)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_PAUSE)
|
||||
async def async_media_previous_track(self):
|
||||
"""Send previous track command."""
|
||||
await self._async_call_service(SERVICE_MEDIA_PREVIOUS_TRACK)
|
||||
|
||||
def async_media_stop(self):
|
||||
"""Send stop command.
|
||||
async def async_media_next_track(self):
|
||||
"""Send next track command."""
|
||||
await self._async_call_service(SERVICE_MEDIA_NEXT_TRACK)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_STOP)
|
||||
|
||||
def async_media_previous_track(self):
|
||||
"""Send previous track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_PREVIOUS_TRACK)
|
||||
|
||||
def async_media_next_track(self):
|
||||
"""Send next track command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_NEXT_TRACK)
|
||||
|
||||
def async_media_seek(self, position):
|
||||
"""Send seek command.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_media_seek(self, position):
|
||||
"""Send seek command."""
|
||||
data = {ATTR_MEDIA_SEEK_POSITION: position}
|
||||
return self._async_call_service(SERVICE_MEDIA_SEEK, data)
|
||||
await self._async_call_service(SERVICE_MEDIA_SEEK, data)
|
||||
|
||||
def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media."""
|
||||
data = {ATTR_MEDIA_CONTENT_TYPE: media_type, ATTR_MEDIA_CONTENT_ID: media_id}
|
||||
return self._async_call_service(SERVICE_PLAY_MEDIA, data)
|
||||
await self._async_call_service(SERVICE_PLAY_MEDIA, data)
|
||||
|
||||
def async_volume_up(self):
|
||||
"""Turn volume up for media player.
|
||||
async def async_volume_up(self):
|
||||
"""Turn volume up for media player."""
|
||||
await self._async_call_service(SERVICE_VOLUME_UP, allow_override=True)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_VOLUME_UP, allow_override=True)
|
||||
async def async_volume_down(self):
|
||||
"""Turn volume down for media player."""
|
||||
await self._async_call_service(SERVICE_VOLUME_DOWN, allow_override=True)
|
||||
|
||||
def async_volume_down(self):
|
||||
"""Turn volume down for media player.
|
||||
async def async_media_play_pause(self):
|
||||
"""Play or pause the media player."""
|
||||
await self._async_call_service(SERVICE_MEDIA_PLAY_PAUSE)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_VOLUME_DOWN, allow_override=True)
|
||||
|
||||
def async_media_play_pause(self):
|
||||
"""Play or pause the media player.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_MEDIA_PLAY_PAUSE)
|
||||
|
||||
def async_select_source(self, source):
|
||||
"""Set the input source.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_select_source(self, source):
|
||||
"""Set the input source."""
|
||||
data = {ATTR_INPUT_SOURCE: source}
|
||||
return self._async_call_service(
|
||||
SERVICE_SELECT_SOURCE, data, allow_override=True
|
||||
)
|
||||
await self._async_call_service(SERVICE_SELECT_SOURCE, data, allow_override=True)
|
||||
|
||||
def async_clear_playlist(self):
|
||||
"""Clear players playlist.
|
||||
async def async_clear_playlist(self):
|
||||
"""Clear players playlist."""
|
||||
await self._async_call_service(SERVICE_CLEAR_PLAYLIST)
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self._async_call_service(SERVICE_CLEAR_PLAYLIST)
|
||||
|
||||
def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffling.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffling."""
|
||||
data = {ATTR_MEDIA_SHUFFLE: shuffle}
|
||||
return self._async_call_service(SERVICE_SHUFFLE_SET, data, allow_override=True)
|
||||
await self._async_call_service(SERVICE_SHUFFLE_SET, data, allow_override=True)
|
||||
|
||||
async def async_update(self):
|
||||
"""Update state in HA."""
|
||||
|
|
|
@ -11,7 +11,7 @@ from homeassistant.const import (
|
|||
CONF_ENTITY_ID,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -62,6 +62,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
|
|
@ -251,73 +251,75 @@ class Volumio(MediaPlayerDevice):
|
|||
"""Flag of media commands that are supported."""
|
||||
return SUPPORT_VOLUMIO
|
||||
|
||||
def async_media_next_track(self):
|
||||
async def async_media_next_track(self):
|
||||
"""Send media_next command to media player."""
|
||||
return self.send_volumio_msg("commands", params={"cmd": "next"})
|
||||
await self.send_volumio_msg("commands", params={"cmd": "next"})
|
||||
|
||||
def async_media_previous_track(self):
|
||||
async def async_media_previous_track(self):
|
||||
"""Send media_previous command to media player."""
|
||||
return self.send_volumio_msg("commands", params={"cmd": "prev"})
|
||||
await self.send_volumio_msg("commands", params={"cmd": "prev"})
|
||||
|
||||
def async_media_play(self):
|
||||
async def async_media_play(self):
|
||||
"""Send media_play command to media player."""
|
||||
return self.send_volumio_msg("commands", params={"cmd": "play"})
|
||||
await self.send_volumio_msg("commands", params={"cmd": "play"})
|
||||
|
||||
def async_media_pause(self):
|
||||
async def async_media_pause(self):
|
||||
"""Send media_pause command to media player."""
|
||||
if self._state["trackType"] == "webradio":
|
||||
return self.send_volumio_msg("commands", params={"cmd": "stop"})
|
||||
return self.send_volumio_msg("commands", params={"cmd": "pause"})
|
||||
await self.send_volumio_msg("commands", params={"cmd": "stop"})
|
||||
else:
|
||||
await self.send_volumio_msg("commands", params={"cmd": "pause"})
|
||||
|
||||
def async_set_volume_level(self, volume):
|
||||
async def async_set_volume_level(self, volume):
|
||||
"""Send volume_up command to media player."""
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "volume", "volume": int(volume * 100)}
|
||||
)
|
||||
|
||||
def async_volume_up(self):
|
||||
async def async_volume_up(self):
|
||||
"""Service to send the Volumio the command for volume up."""
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "volume", "volume": "plus"}
|
||||
)
|
||||
|
||||
def async_volume_down(self):
|
||||
async def async_volume_down(self):
|
||||
"""Service to send the Volumio the command for volume down."""
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "volume", "volume": "minus"}
|
||||
)
|
||||
|
||||
def async_mute_volume(self, mute):
|
||||
async def async_mute_volume(self, mute):
|
||||
"""Send mute command to media player."""
|
||||
mutecmd = "mute" if mute else "unmute"
|
||||
if mute:
|
||||
# mute is implemented as 0 volume, do save last volume level
|
||||
self._lastvol = self._state["volume"]
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "volume", "volume": mutecmd}
|
||||
)
|
||||
return
|
||||
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "volume", "volume": self._lastvol}
|
||||
)
|
||||
|
||||
def async_set_shuffle(self, shuffle):
|
||||
async def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode."""
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "random", "value": str(shuffle).lower()}
|
||||
)
|
||||
|
||||
def async_select_source(self, source):
|
||||
async def async_select_source(self, source):
|
||||
"""Choose a different available playlist and play it."""
|
||||
self._currentplaylist = source
|
||||
return self.send_volumio_msg(
|
||||
await self.send_volumio_msg(
|
||||
"commands", params={"cmd": "playplaylist", "name": source}
|
||||
)
|
||||
|
||||
def async_clear_playlist(self):
|
||||
async def async_clear_playlist(self):
|
||||
"""Clear players playlist."""
|
||||
self._currentplaylist = None
|
||||
return self.send_volumio_msg("commands", params={"cmd": "clearQueue"})
|
||||
await self.send_volumio_msg("commands", params={"cmd": "clearQueue"})
|
||||
|
||||
@Throttle(PLAYLIST_UPDATE_INTERVAL)
|
||||
async def _async_update_playlists(self, **kwargs):
|
||||
|
|
|
@ -780,6 +780,7 @@ async def async_binding_operation(zha_gateway, source_ieee, target_ieee, operati
|
|||
zdo.debug(fmt, *(log_msg[2] + (outcome,)))
|
||||
|
||||
|
||||
@callback
|
||||
def async_load_api(hass):
|
||||
"""Set up the web socket API."""
|
||||
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
||||
|
@ -1058,6 +1059,7 @@ def async_load_api(hass):
|
|||
websocket_api.async_register_command(hass, websocket_unbind_devices)
|
||||
|
||||
|
||||
@callback
|
||||
def async_unload_api(hass):
|
||||
"""Unload the ZHA API."""
|
||||
hass.services.async_remove(DOMAIN, SERVICE_PERMIT)
|
||||
|
|
|
@ -125,6 +125,7 @@ class BinarySensor(ZhaEntity, BinarySensorDevice):
|
|||
"""Return device class from component DEVICE_CLASSES."""
|
||||
return self._device_class
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Set the state."""
|
||||
self._state = bool(state)
|
||||
|
|
|
@ -273,6 +273,7 @@ class ZHAGateway:
|
|||
"""Return Group for given group id."""
|
||||
return self.groups.get(group_id)
|
||||
|
||||
@callback
|
||||
def async_get_group_by_name(self, group_name):
|
||||
"""Get ZHA group by name."""
|
||||
for group in self.groups.values():
|
||||
|
|
|
@ -113,6 +113,7 @@ class ZhaCover(ZhaEntity, CoverDevice):
|
|||
"""
|
||||
return self._current_position
|
||||
|
||||
@callback
|
||||
def async_set_position(self, pos):
|
||||
"""Handle position update from channel."""
|
||||
_LOGGER.debug("setting position: %s", pos)
|
||||
|
@ -123,6 +124,7 @@ class ZhaCover(ZhaEntity, CoverDevice):
|
|||
self._state = STATE_OPEN
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Handle state update from channel."""
|
||||
_LOGGER.debug("state=%s", state)
|
||||
|
|
|
@ -99,16 +99,19 @@ class ZhaEntity(RestoreEntity, LogMixin, entity.Entity):
|
|||
"""Return entity availability."""
|
||||
return self._available
|
||||
|
||||
@callback
|
||||
def async_set_available(self, available):
|
||||
"""Set entity availability."""
|
||||
self._available = available
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@callback
|
||||
def async_update_state_attribute(self, key, value):
|
||||
"""Update a single device state attribute."""
|
||||
self._device_state_attributes.update({key: value})
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Set the entity state."""
|
||||
pass
|
||||
|
|
|
@ -136,6 +136,7 @@ class ZhaFan(ZhaEntity, FanEntity):
|
|||
"""Return state attributes."""
|
||||
return self.state_attributes
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Handle state update from channel."""
|
||||
self._state = VALUE_TO_SPEED.get(state, self._state)
|
||||
|
|
|
@ -170,6 +170,7 @@ class Light(ZhaEntity, light.Light):
|
|||
"""Flag supported features."""
|
||||
return self._supported_features
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Set the state."""
|
||||
self._state = bool(state)
|
||||
|
|
|
@ -125,6 +125,7 @@ class ZhaDoorLock(ZhaEntity, LockDevice):
|
|||
await super().async_update()
|
||||
await self.async_get_state()
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Handle state update from channel."""
|
||||
self._state = VALUE_TO_STATE.get(state, self._state)
|
||||
|
|
|
@ -149,6 +149,7 @@ class Sensor(ZhaEntity):
|
|||
return None
|
||||
return self._state
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Handle state update from channel."""
|
||||
if state is not None:
|
||||
|
@ -202,6 +203,7 @@ class Battery(Sensor):
|
|||
state_attrs["battery_quantity"] = battery_quantity
|
||||
return state_attrs
|
||||
|
||||
@callback
|
||||
def async_update_state_attribute(self, key, value):
|
||||
"""Update a single device state attribute."""
|
||||
if key == "battery_voltage":
|
||||
|
|
|
@ -93,6 +93,7 @@ class Switch(ZhaEntity, SwitchDevice):
|
|||
self._state = False
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@callback
|
||||
def async_set_state(self, state):
|
||||
"""Handle state update from channel."""
|
||||
self._state = bool(state)
|
||||
|
|
|
@ -260,6 +260,7 @@ class DeviceRegistry:
|
|||
|
||||
return new
|
||||
|
||||
@callback
|
||||
def async_remove_device(self, device_id: str) -> None:
|
||||
"""Remove a device from the device registry."""
|
||||
del self.devices[device_id]
|
||||
|
|
|
@ -596,23 +596,17 @@ class ToggleEntity(Entity):
|
|||
"""Turn the entity on."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_turn_on(self, **kwargs):
|
||||
"""Turn the entity on.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.turn_on, **kwargs))
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the entity on."""
|
||||
await self.hass.async_add_job(ft.partial(self.turn_on, **kwargs))
|
||||
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity off."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def async_turn_off(self, **kwargs):
|
||||
"""Turn the entity off.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
return self.hass.async_add_job(ft.partial(self.turn_off, **kwargs))
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the entity off."""
|
||||
await self.hass.async_add_job(ft.partial(self.turn_off, **kwargs))
|
||||
|
||||
def toggle(self, **kwargs: Any) -> None:
|
||||
"""Toggle the entity."""
|
||||
|
@ -621,11 +615,9 @@ class ToggleEntity(Entity):
|
|||
else:
|
||||
self.turn_on(**kwargs)
|
||||
|
||||
def async_toggle(self, **kwargs):
|
||||
"""Toggle the entity.
|
||||
|
||||
This method must be run in the event loop and returns a coroutine.
|
||||
"""
|
||||
async def async_toggle(self, **kwargs):
|
||||
"""Toggle the entity."""
|
||||
if self.is_on:
|
||||
return self.async_turn_off(**kwargs)
|
||||
return self.async_turn_on(**kwargs)
|
||||
await self.async_turn_off(**kwargs)
|
||||
else:
|
||||
await self.async_turn_on(**kwargs)
|
||||
|
|
|
@ -115,6 +115,7 @@ class RestoreStateData:
|
|||
self.last_states: Dict[str, StoredState] = {}
|
||||
self.entity_ids: Set[str] = set()
|
||||
|
||||
@callback
|
||||
def async_get_stored_states(self) -> List[StoredState]:
|
||||
"""Get the set of states which should be stored.
|
||||
|
||||
|
|
|
@ -214,6 +214,7 @@ class Script:
|
|||
"""Stop running script."""
|
||||
run_callback_threadsafe(self.hass.loop, self.async_stop).result()
|
||||
|
||||
@callback
|
||||
def async_stop(self) -> None:
|
||||
"""Stop running script."""
|
||||
if self._cur == -1:
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||
STATE_OFF,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, config_validation as cv, entity_registry
|
||||
from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
|
@ -67,6 +67,7 @@ async def async_get_conditions(
|
|||
return conditions
|
||||
|
||||
|
||||
@callback
|
||||
def async_condition_from_config(
|
||||
config: ConfigType, config_validation: bool
|
||||
) -> condition.ConditionCheckerType:
|
||||
|
@ -78,6 +79,7 @@ def async_condition_from_config(
|
|||
else:
|
||||
state = STATE_OFF
|
||||
|
||||
@callback
|
||||
def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool:
|
||||
"""Test if an entity is a certain state."""
|
||||
return condition.state(hass, config[ATTR_ENTITY_ID], state)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""The tests for the MQTT component embedded server."""
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
from unittest.mock import MagicMock, Mock
|
||||
|
||||
from asynctest import CoroutineMock, patch
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.const import CONF_PASSWORD
|
||||
|
@ -21,7 +23,7 @@ class TestMQTT:
|
|||
|
||||
@patch("passlib.apps.custom_app_context", Mock(return_value=""))
|
||||
@patch("tempfile.NamedTemporaryFile", Mock(return_value=MagicMock()))
|
||||
@patch("hbmqtt.broker.Broker", Mock(return_value=MagicMock()))
|
||||
@patch("hbmqtt.broker.Broker", Mock(return_value=MagicMock(start=CoroutineMock())))
|
||||
@patch("hbmqtt.broker.Broker.start", Mock(return_value=mock_coro()))
|
||||
@patch("homeassistant.components.mqtt.MQTT")
|
||||
def test_creating_config_with_pass_and_no_http_pass(self, mock_mqtt):
|
||||
|
@ -43,7 +45,7 @@ class TestMQTT:
|
|||
|
||||
@patch("passlib.apps.custom_app_context", Mock(return_value=""))
|
||||
@patch("tempfile.NamedTemporaryFile", Mock(return_value=MagicMock()))
|
||||
@patch("hbmqtt.broker.Broker", Mock(return_value=MagicMock()))
|
||||
@patch("hbmqtt.broker.Broker", Mock(return_value=MagicMock(start=CoroutineMock())))
|
||||
@patch("hbmqtt.broker.Broker.start", Mock(return_value=mock_coro()))
|
||||
@patch("homeassistant.components.mqtt.MQTT")
|
||||
def test_creating_config_with_pass_and_http_pass(self, mock_mqtt):
|
||||
|
|
Loading…
Reference in New Issue