mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Async migrate climate (#5026)
* Async migrate climate * Change update handling
This commit is contained in:
parent
43e5d28643
commit
22d1bf0acd
@ -4,8 +4,10 @@ Provides functionality to interact with climate devices.
|
|||||||
For more details about this component, please refer to the documentation at
|
For more details about this component, please refer to the documentation at
|
||||||
https://home-assistant.io/components/climate/
|
https://home-assistant.io/components/climate/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import functools as ft
|
||||||
from numbers import Number
|
from numbers import Number
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
@ -185,17 +187,38 @@ def set_swing_mode(hass, swing_mode, entity_id=None):
|
|||||||
hass.services.call(DOMAIN, SERVICE_SET_SWING_MODE, data)
|
hass.services.call(DOMAIN, SERVICE_SET_SWING_MODE, data)
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Setup climate devices."""
|
"""Setup climate devices."""
|
||||||
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
|
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
|
||||||
component.setup(config)
|
yield from component.async_setup(config)
|
||||||
|
|
||||||
descriptions = load_yaml_config_file(
|
descriptions = yield from hass.loop.run_in_executor(
|
||||||
|
None, load_yaml_config_file,
|
||||||
os.path.join(os.path.dirname(__file__), 'services.yaml'))
|
os.path.join(os.path.dirname(__file__), 'services.yaml'))
|
||||||
|
|
||||||
def away_mode_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def _async_update_climate(target_climate):
|
||||||
|
"""Update climate entity after service stuff."""
|
||||||
|
update_tasks = []
|
||||||
|
for climate in target_climate:
|
||||||
|
if not climate.should_poll:
|
||||||
|
continue
|
||||||
|
|
||||||
|
update_coro = hass.loop.create_task(
|
||||||
|
climate.async_update_ha_state(True))
|
||||||
|
if hasattr(climate, 'async_update'):
|
||||||
|
update_tasks.append(update_coro)
|
||||||
|
else:
|
||||||
|
yield from update_coro
|
||||||
|
|
||||||
|
if update_tasks:
|
||||||
|
yield from asyncio.wait(update_tasks, loop=hass.loop)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_away_mode_set_service(service):
|
||||||
"""Set away mode on target climate devices."""
|
"""Set away mode on target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
away_mode = service.data.get(ATTR_AWAY_MODE)
|
away_mode = service.data.get(ATTR_AWAY_MODE)
|
||||||
|
|
||||||
@ -207,21 +230,21 @@ def setup(hass, config):
|
|||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
if away_mode:
|
if away_mode:
|
||||||
climate.turn_away_mode_on()
|
yield from climate.async_turn_away_mode_on()
|
||||||
else:
|
else:
|
||||||
climate.turn_away_mode_off()
|
yield from climate.async_turn_away_mode_off()
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_AWAY_MODE, away_mode_set_service,
|
DOMAIN, SERVICE_SET_AWAY_MODE, async_away_mode_set_service,
|
||||||
descriptions.get(SERVICE_SET_AWAY_MODE),
|
descriptions.get(SERVICE_SET_AWAY_MODE),
|
||||||
schema=SET_AWAY_MODE_SCHEMA)
|
schema=SET_AWAY_MODE_SCHEMA)
|
||||||
|
|
||||||
def aux_heat_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_aux_heat_set_service(service):
|
||||||
"""Set auxillary heater on target climate devices."""
|
"""Set auxillary heater on target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
aux_heat = service.data.get(ATTR_AUX_HEAT)
|
aux_heat = service.data.get(ATTR_AUX_HEAT)
|
||||||
|
|
||||||
@ -233,21 +256,21 @@ def setup(hass, config):
|
|||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
if aux_heat:
|
if aux_heat:
|
||||||
climate.turn_aux_heat_on()
|
yield from climate.async_turn_aux_heat_on()
|
||||||
else:
|
else:
|
||||||
climate.turn_aux_heat_off()
|
yield from climate.async_turn_aux_heat_off()
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_AUX_HEAT, aux_heat_set_service,
|
DOMAIN, SERVICE_SET_AUX_HEAT, async_aux_heat_set_service,
|
||||||
descriptions.get(SERVICE_SET_AUX_HEAT),
|
descriptions.get(SERVICE_SET_AUX_HEAT),
|
||||||
schema=SET_AUX_HEAT_SCHEMA)
|
schema=SET_AUX_HEAT_SCHEMA)
|
||||||
|
|
||||||
def temperature_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_temperature_set_service(service):
|
||||||
"""Set temperature on the target climate devices."""
|
"""Set temperature on the target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
@ -261,18 +284,19 @@ def setup(hass, config):
|
|||||||
else:
|
else:
|
||||||
kwargs[value] = temp
|
kwargs[value] = temp
|
||||||
|
|
||||||
climate.set_temperature(**kwargs)
|
yield from climate.async_set_temperature(**kwargs)
|
||||||
if climate.should_poll:
|
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
yield from _async_update_climate(target_climate)
|
||||||
DOMAIN, SERVICE_SET_TEMPERATURE, temperature_set_service,
|
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, SERVICE_SET_TEMPERATURE, async_temperature_set_service,
|
||||||
descriptions.get(SERVICE_SET_TEMPERATURE),
|
descriptions.get(SERVICE_SET_TEMPERATURE),
|
||||||
schema=SET_TEMPERATURE_SCHEMA)
|
schema=SET_TEMPERATURE_SCHEMA)
|
||||||
|
|
||||||
def humidity_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_humidity_set_service(service):
|
||||||
"""Set humidity on the target climate devices."""
|
"""Set humidity on the target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
humidity = service.data.get(ATTR_HUMIDITY)
|
humidity = service.data.get(ATTR_HUMIDITY)
|
||||||
|
|
||||||
@ -283,19 +307,19 @@ def setup(hass, config):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
climate.set_humidity(humidity)
|
yield from climate.async_set_humidity(humidity)
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_HUMIDITY, humidity_set_service,
|
DOMAIN, SERVICE_SET_HUMIDITY, async_humidity_set_service,
|
||||||
descriptions.get(SERVICE_SET_HUMIDITY),
|
descriptions.get(SERVICE_SET_HUMIDITY),
|
||||||
schema=SET_HUMIDITY_SCHEMA)
|
schema=SET_HUMIDITY_SCHEMA)
|
||||||
|
|
||||||
def fan_mode_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_fan_mode_set_service(service):
|
||||||
"""Set fan mode on target climate devices."""
|
"""Set fan mode on target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
fan = service.data.get(ATTR_FAN_MODE)
|
fan = service.data.get(ATTR_FAN_MODE)
|
||||||
|
|
||||||
@ -306,19 +330,19 @@ def setup(hass, config):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
climate.set_fan_mode(fan)
|
yield from climate.async_set_fan_mode(fan)
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_FAN_MODE, fan_mode_set_service,
|
DOMAIN, SERVICE_SET_FAN_MODE, async_fan_mode_set_service,
|
||||||
descriptions.get(SERVICE_SET_FAN_MODE),
|
descriptions.get(SERVICE_SET_FAN_MODE),
|
||||||
schema=SET_FAN_MODE_SCHEMA)
|
schema=SET_FAN_MODE_SCHEMA)
|
||||||
|
|
||||||
def operation_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_operation_set_service(service):
|
||||||
"""Set operating mode on the target climate devices."""
|
"""Set operating mode on the target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
operation_mode = service.data.get(ATTR_OPERATION_MODE)
|
operation_mode = service.data.get(ATTR_OPERATION_MODE)
|
||||||
|
|
||||||
@ -329,19 +353,19 @@ def setup(hass, config):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
climate.set_operation_mode(operation_mode)
|
yield from climate.async_set_operation_mode(operation_mode)
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_OPERATION_MODE, operation_set_service,
|
DOMAIN, SERVICE_SET_OPERATION_MODE, async_operation_set_service,
|
||||||
descriptions.get(SERVICE_SET_OPERATION_MODE),
|
descriptions.get(SERVICE_SET_OPERATION_MODE),
|
||||||
schema=SET_OPERATION_MODE_SCHEMA)
|
schema=SET_OPERATION_MODE_SCHEMA)
|
||||||
|
|
||||||
def swing_set_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_swing_set_service(service):
|
||||||
"""Set swing mode on the target climate devices."""
|
"""Set swing mode on the target climate devices."""
|
||||||
target_climate = component.extract_from_service(service)
|
target_climate = component.async_extract_from_service(service)
|
||||||
|
|
||||||
swing_mode = service.data.get(ATTR_SWING_MODE)
|
swing_mode = service.data.get(ATTR_SWING_MODE)
|
||||||
|
|
||||||
@ -352,15 +376,15 @@ def setup(hass, config):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for climate in target_climate:
|
for climate in target_climate:
|
||||||
climate.set_swing_mode(swing_mode)
|
yield from climate.async_set_swing_mode(swing_mode)
|
||||||
|
|
||||||
if climate.should_poll:
|
yield from _async_update_climate(target_climate)
|
||||||
climate.update_ha_state(True)
|
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SET_SWING_MODE, swing_set_service,
|
DOMAIN, SERVICE_SET_SWING_MODE, async_swing_set_service,
|
||||||
descriptions.get(SERVICE_SET_SWING_MODE),
|
descriptions.get(SERVICE_SET_SWING_MODE),
|
||||||
schema=SET_SWING_MODE_SCHEMA)
|
schema=SET_SWING_MODE_SCHEMA)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -521,38 +545,110 @@ class ClimateDevice(Entity):
|
|||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_set_temperature(self, **kwargs):
|
||||||
|
"""Set new target temperature.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, ft.partial(self.set_temperature, **kwargs))
|
||||||
|
|
||||||
def set_humidity(self, humidity):
|
def set_humidity(self, humidity):
|
||||||
"""Set new target humidity."""
|
"""Set new target humidity."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_set_humidity(self, humidity):
|
||||||
|
"""Set new target humidity.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.set_humidity, humidity)
|
||||||
|
|
||||||
def set_fan_mode(self, fan):
|
def set_fan_mode(self, fan):
|
||||||
"""Set new target fan mode."""
|
"""Set new target fan mode."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_set_fan_mode(self, fan):
|
||||||
|
"""Set new target fan mode.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.set_fan_mode, fan)
|
||||||
|
|
||||||
def set_operation_mode(self, operation_mode):
|
def set_operation_mode(self, operation_mode):
|
||||||
"""Set new target operation mode."""
|
"""Set new target operation mode."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_set_operation_mode(self, operation_mode):
|
||||||
|
"""Set new target operation mode.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.set_operation_mode, operation_mode)
|
||||||
|
|
||||||
def set_swing_mode(self, swing_mode):
|
def set_swing_mode(self, swing_mode):
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_set_swing_mode(self, swing_mode):
|
||||||
|
"""Set new target swing operation.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.set_swing_mode, swing_mode)
|
||||||
|
|
||||||
def turn_away_mode_on(self):
|
def turn_away_mode_on(self):
|
||||||
"""Turn away mode on."""
|
"""Turn away mode on."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_turn_away_mode_on(self):
|
||||||
|
"""Turn away mode on.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.turn_away_mode_on)
|
||||||
|
|
||||||
def turn_away_mode_off(self):
|
def turn_away_mode_off(self):
|
||||||
"""Turn away mode off."""
|
"""Turn away mode off."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_turn_away_mode_off(self):
|
||||||
|
"""Turn away mode off.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.turn_away_mode_off)
|
||||||
|
|
||||||
def turn_aux_heat_on(self):
|
def turn_aux_heat_on(self):
|
||||||
"""Turn auxillary heater on."""
|
"""Turn auxillary heater on."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_turn_aux_heat_on(self):
|
||||||
|
"""Turn auxillary heater on.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.turn_aux_heat_on)
|
||||||
|
|
||||||
def turn_aux_heat_off(self):
|
def turn_aux_heat_off(self):
|
||||||
"""Turn auxillary heater off."""
|
"""Turn auxillary heater off."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def async_turn_aux_heat_off(self):
|
||||||
|
"""Turn auxillary heater off.
|
||||||
|
|
||||||
|
This method must be run in the event loop and returns a coroutine.
|
||||||
|
"""
|
||||||
|
return self.hass.loop.run_in_executor(
|
||||||
|
None, self.turn_aux_heat_off)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_temp(self):
|
def min_temp(self):
|
||||||
"""Return the minimum temperature."""
|
"""Return the minimum temperature."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user