Make mysensors updates and platform setup async (#13603)

* Use async updates but keep methods that interact with mysensors
  gateway thread, eg turn_on and turn_off, non async.
* Use Python 3.5 async syntax.
This commit is contained in:
Martin Hjelmare 2018-04-01 17:36:26 +02:00 committed by Paulus Schoutsen
parent ff9f500c51
commit c8f2810fac
9 changed files with 65 additions and 57 deletions

View file

@ -21,11 +21,12 @@ SENSORS = {
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the MySensors platform for binary sensors."""
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the mysensors platform for binary sensors."""
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsBinarySensor,
add_devices=add_devices)
async_add_devices=async_add_devices)
class MySensorsBinarySensor(mysensors.MySensorsEntity, BinarySensorDevice):

View file

@ -31,10 +31,12 @@ SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH |
SUPPORT_OPERATION_MODE)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the MySensors climate."""
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the mysensors climate."""
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsHVAC, add_devices=add_devices)
hass, DOMAIN, discovery_info, MySensorsHVAC,
async_add_devices=async_add_devices)
class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
@ -163,8 +165,8 @@ class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice):
self._values[self.value_type] = operation_mode
self.schedule_update_ha_state()
def update(self):
async def async_update(self):
"""Update the controller with the latest value from a sensor."""
super().update()
await super().async_update()
self._values[self.value_type] = DICT_MYS_TO_HA[
self._values[self.value_type]]

View file

@ -9,10 +9,12 @@ from homeassistant.components.cover import ATTR_POSITION, DOMAIN, CoverDevice
from homeassistant.const import STATE_OFF, STATE_ON
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the MySensors platform for covers."""
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the mysensors platform for covers."""
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsCover, add_devices=add_devices)
hass, DOMAIN, discovery_info, MySensorsCover,
async_add_devices=async_add_devices)
class MySensorsCover(mysensors.MySensorsEntity, CoverDevice):

View file

@ -6,15 +6,15 @@ https://home-assistant.io/components/device_tracker.mysensors/
"""
from homeassistant.components import mysensors
from homeassistant.components.device_tracker import DOMAIN
from homeassistant.helpers.dispatcher import dispatcher_connect
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.util import slugify
def setup_scanner(hass, config, see, discovery_info=None):
async def async_setup_scanner(hass, config, async_see, discovery_info=None):
"""Set up the MySensors device scanner."""
new_devices = mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsDeviceScanner,
device_args=(see, ))
device_args=(async_see, ))
if not new_devices:
return False
@ -22,9 +22,9 @@ def setup_scanner(hass, config, see, discovery_info=None):
dev_id = (
id(device.gateway), device.node_id, device.child_id,
device.value_type)
dispatcher_connect(
async_dispatcher_connect(
hass, mysensors.SIGNAL_CALLBACK.format(*dev_id),
device.update_callback)
device.async_update_callback)
return True
@ -32,20 +32,20 @@ def setup_scanner(hass, config, see, discovery_info=None):
class MySensorsDeviceScanner(mysensors.MySensorsDevice):
"""Represent a MySensors scanner."""
def __init__(self, see, *args):
def __init__(self, async_see, *args):
"""Set up instance."""
super().__init__(*args)
self.see = see
self.async_see = async_see
def update_callback(self):
async def async_update_callback(self):
"""Update the device."""
self.update()
await self.async_update()
node = self.gateway.sensors[self.node_id]
child = node.children[self.child_id]
position = child.values[self.value_type]
latitude, longitude, _ = position.split(',')
self.see(
await self.async_see(
dev_id=slugify(self.name),
host_name=self.name,
gps=(latitude, longitude),

View file

@ -15,8 +15,9 @@ import homeassistant.util.color as color_util
SUPPORT_MYSENSORS_RGBW = SUPPORT_COLOR | SUPPORT_WHITE_VALUE
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the MySensors platform for lights."""
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the mysensors platform for lights."""
device_class_map = {
'S_DIMMER': MySensorsLightDimmer,
'S_RGB_LIGHT': MySensorsLightRGB,
@ -24,7 +25,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
}
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, device_class_map,
add_devices=add_devices)
async_add_devices=async_add_devices)
class MySensorsLight(mysensors.MySensorsEntity, Light):
@ -140,12 +141,12 @@ class MySensorsLight(mysensors.MySensorsEntity, Light):
self._values[value_type] = STATE_OFF
self.schedule_update_ha_state()
def _update_light(self):
def _async_update_light(self):
"""Update the controller with values from light child."""
value_type = self.gateway.const.SetReq.V_LIGHT
self._state = self._values[value_type] == STATE_ON
def _update_dimmer(self):
def _async_update_dimmer(self):
"""Update the controller with values from dimmer child."""
value_type = self.gateway.const.SetReq.V_DIMMER
if value_type in self._values:
@ -153,7 +154,7 @@ class MySensorsLight(mysensors.MySensorsEntity, Light):
if self._brightness == 0:
self._state = False
def _update_rgb_or_w(self):
def _async_update_rgb_or_w(self):
"""Update the controller with values from RGB or RGBW child."""
value = self._values[self.value_type]
color_list = rgb_hex_to_rgb_list(value)
@ -177,11 +178,11 @@ class MySensorsLightDimmer(MySensorsLight):
if self.gateway.optimistic:
self.schedule_update_ha_state()
def update(self):
async def async_update(self):
"""Update the controller with the latest value from a sensor."""
super().update()
self._update_light()
self._update_dimmer()
await super().async_update()
self._async_update_light()
self._async_update_dimmer()
class MySensorsLightRGB(MySensorsLight):
@ -203,12 +204,12 @@ class MySensorsLightRGB(MySensorsLight):
if self.gateway.optimistic:
self.schedule_update_ha_state()
def update(self):
async def async_update(self):
"""Update the controller with the latest value from a sensor."""
super().update()
self._update_light()
self._update_dimmer()
self._update_rgb_or_w()
await super().async_update()
self._async_update_light()
self._async_update_dimmer()
self._async_update_rgb_or_w()
class MySensorsLightRGBW(MySensorsLightRGB):

View file

@ -4,7 +4,6 @@ Connect to a MySensors gateway via pymysensors API.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/mysensors/
"""
import asyncio
from collections import defaultdict
import logging
import os
@ -519,11 +518,12 @@ def get_mysensors_gateway(hass, gateway_id):
return gateways.get(gateway_id)
@callback
def setup_mysensors_platform(
hass, domain, discovery_info, device_class, device_args=None,
add_devices=None):
async_add_devices=None):
"""Set up a MySensors platform."""
# Only act if called via MySensors by discovery event.
# Only act if called via mysensors by discovery event.
# Otherwise gateway is not setup.
if not discovery_info:
return
@ -552,8 +552,8 @@ def setup_mysensors_platform(
new_devices.append(devices[dev_id])
if new_devices:
_LOGGER.info("Adding new devices: %s", new_devices)
if add_devices is not None:
add_devices(new_devices, True)
if async_add_devices is not None:
async_add_devices(new_devices, True)
return new_devices
@ -596,7 +596,7 @@ class MySensorsDevice(object):
return attr
def update(self):
async def async_update(self):
"""Update the controller with the latest value from a sensor."""
node = self.gateway.sensors[self.node_id]
child = node.children[self.child_id]
@ -629,14 +629,13 @@ class MySensorsEntity(MySensorsDevice, Entity):
return self.value_type in self._values
@callback
def _async_update_callback(self):
def async_update_callback(self):
"""Update the entity."""
self.async_schedule_update_ha_state(True)
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register update callback."""
dev_id = id(self.gateway), self.node_id, self.child_id, self.value_type
async_dispatcher_connect(
self.hass, SIGNAL_CALLBACK.format(*dev_id),
self._async_update_callback)
self.async_update_callback)

View file

@ -9,12 +9,12 @@ from homeassistant.components.notify import (
ATTR_TARGET, DOMAIN, BaseNotificationService)
def get_service(hass, config, discovery_info=None):
async def async_get_service(hass, config, discovery_info=None):
"""Get the MySensors notification service."""
new_devices = mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsNotificationDevice)
if not new_devices:
return
return None
return MySensorsNotificationService(hass)

View file

@ -34,10 +34,12 @@ SENSORS = {
}
def setup_platform(hass, config, add_devices, discovery_info=None):
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the MySensors platform for sensors."""
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsSensor, add_devices=add_devices)
hass, DOMAIN, discovery_info, MySensorsSensor,
async_add_devices=async_add_devices)
class MySensorsSensor(mysensors.MySensorsEntity):

View file

@ -20,7 +20,8 @@ SEND_IR_CODE_SERVICE_SCHEMA = vol.Schema({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the mysensors platform for switches."""
device_class_map = {
'S_DOOR': MySensorsSwitch,
@ -39,7 +40,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
}
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, device_class_map,
add_devices=add_devices)
async_add_devices=async_add_devices)
def send_ir_code_service(service):
"""Set IR code as device state attribute."""
@ -59,9 +60,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for device in _devices:
device.turn_on(**kwargs)
hass.services.register(DOMAIN, SERVICE_SEND_IR_CODE,
send_ir_code_service,
schema=SEND_IR_CODE_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_SEND_IR_CODE, send_ir_code_service,
schema=SEND_IR_CODE_SERVICE_SCHEMA)
class MySensorsSwitch(mysensors.MySensorsEntity, SwitchDevice):
@ -143,7 +144,7 @@ class MySensorsIRSwitch(MySensorsSwitch):
self._values[set_req.V_LIGHT] = STATE_OFF
self.schedule_update_ha_state()
def update(self):
async def async_update(self):
"""Update the controller with the latest value from a sensor."""
super().update()
await super().async_update()
self._ir_code = self._values.get(self.value_type)