mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Cleanup climate platform for async update_ha_state / migrate generic thermostat (#5679)
* Cleanup climate from blocking stuff / migrate generic * Migrate generic thermostat * fix tests * fix lint
This commit is contained in:
parent
647a93801c
commit
10a104271e
@ -135,27 +135,27 @@ class DemoClimate(ClimateDevice):
|
|||||||
kwargs.get(ATTR_TARGET_TEMP_LOW) is not None:
|
kwargs.get(ATTR_TARGET_TEMP_LOW) is not None:
|
||||||
self._target_temperature_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
|
self._target_temperature_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
|
||||||
self._target_temperature_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
|
self._target_temperature_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_humidity(self, humidity):
|
def set_humidity(self, humidity):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
self._target_humidity = humidity
|
self._target_humidity = humidity
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_swing_mode(self, swing_mode):
|
def set_swing_mode(self, swing_mode):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
self._current_swing_mode = swing_mode
|
self._current_swing_mode = swing_mode
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_fan_mode(self, fan):
|
def set_fan_mode(self, fan):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
self._current_fan_mode = fan
|
self._current_fan_mode = fan
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_operation_mode(self, operation_mode):
|
def set_operation_mode(self, operation_mode):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
self._current_operation = operation_mode
|
self._current_operation = operation_mode
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_swing_mode(self):
|
def current_swing_mode(self):
|
||||||
@ -170,24 +170,24 @@ class DemoClimate(ClimateDevice):
|
|||||||
def turn_away_mode_on(self):
|
def turn_away_mode_on(self):
|
||||||
"""Turn away mode on."""
|
"""Turn away mode on."""
|
||||||
self._away = True
|
self._away = True
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def turn_away_mode_off(self):
|
def turn_away_mode_off(self):
|
||||||
"""Turn away mode off."""
|
"""Turn away mode off."""
|
||||||
self._away = False
|
self._away = False
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_hold_mode(self, hold):
|
def set_hold_mode(self, hold):
|
||||||
"""Update hold mode on."""
|
"""Update hold mode on."""
|
||||||
self._hold = hold
|
self._hold = hold
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def turn_aux_heat_on(self):
|
def turn_aux_heat_on(self):
|
||||||
"""Turn away auxillary heater on."""
|
"""Turn away auxillary heater on."""
|
||||||
self._aux = True
|
self._aux = True
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def turn_aux_heat_off(self):
|
def turn_aux_heat_off(self):
|
||||||
"""Turn auxillary heater off."""
|
"""Turn auxillary heater off."""
|
||||||
self._aux = False
|
self._aux = False
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
@ -69,7 +69,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
for thermostat in target_thermostats:
|
for thermostat in target_thermostats:
|
||||||
thermostat.set_fan_min_on_time(str(fan_min_on_time))
|
thermostat.set_fan_min_on_time(str(fan_min_on_time))
|
||||||
|
|
||||||
thermostat.update_ha_state(True)
|
thermostat.schedule_update_ha_state(True)
|
||||||
|
|
||||||
def resume_program_set_service(service):
|
def resume_program_set_service(service):
|
||||||
"""Resume the program on the target thermostats."""
|
"""Resume the program on the target thermostats."""
|
||||||
@ -85,7 +85,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
for thermostat in target_thermostats:
|
for thermostat in target_thermostats:
|
||||||
thermostat.resume_program(resume_all)
|
thermostat.resume_program(resume_all)
|
||||||
|
|
||||||
thermostat.update_ha_state(True)
|
thermostat.schedule_update_ha_state(True)
|
||||||
|
|
||||||
descriptions = load_yaml_config_file(
|
descriptions = load_yaml_config_file(
|
||||||
path.join(path.dirname(__file__), 'services.yaml'))
|
path.join(path.dirname(__file__), 'services.yaml'))
|
||||||
|
@ -4,17 +4,19 @@ Adds support for generic thermostat units.
|
|||||||
For more details about this platform, please refer to the documentation at
|
For more details about this platform, please refer to the documentation at
|
||||||
https://home-assistant.io/components/climate.generic_thermostat/
|
https://home-assistant.io/components/climate.generic_thermostat/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.components import switch
|
from homeassistant.components import switch
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA)
|
STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE)
|
ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE)
|
||||||
from homeassistant.helpers import condition
|
from homeassistant.helpers import condition
|
||||||
from homeassistant.helpers.event import track_state_change
|
from homeassistant.helpers.event import async_track_state_change
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -48,7 +50,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
@asyncio.coroutine
|
||||||
|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||||
"""Setup the generic thermostat."""
|
"""Setup the generic thermostat."""
|
||||||
name = config.get(CONF_NAME)
|
name = config.get(CONF_NAME)
|
||||||
heater_entity_id = config.get(CONF_HEATER)
|
heater_entity_id = config.get(CONF_HEATER)
|
||||||
@ -60,7 +63,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
min_cycle_duration = config.get(CONF_MIN_DUR)
|
min_cycle_duration = config.get(CONF_MIN_DUR)
|
||||||
tolerance = config.get(CONF_TOLERANCE)
|
tolerance = config.get(CONF_TOLERANCE)
|
||||||
|
|
||||||
add_devices([GenericThermostat(
|
yield from async_add_devices([GenericThermostat(
|
||||||
hass, name, heater_entity_id, sensor_entity_id, min_temp, max_temp,
|
hass, name, heater_entity_id, sensor_entity_id, min_temp, max_temp,
|
||||||
target_temp, ac_mode, min_cycle_duration, tolerance)])
|
target_temp, ac_mode, min_cycle_duration, tolerance)])
|
||||||
|
|
||||||
@ -86,12 +89,14 @@ class GenericThermostat(ClimateDevice):
|
|||||||
self._target_temp = target_temp
|
self._target_temp = target_temp
|
||||||
self._unit = hass.config.units.temperature_unit
|
self._unit = hass.config.units.temperature_unit
|
||||||
|
|
||||||
track_state_change(hass, sensor_entity_id, self._sensor_changed)
|
async_track_state_change(
|
||||||
track_state_change(hass, heater_entity_id, self._switch_changed)
|
hass, sensor_entity_id, self._async_sensor_changed)
|
||||||
|
async_track_state_change(
|
||||||
|
hass, heater_entity_id, self._async_switch_changed)
|
||||||
|
|
||||||
sensor_state = hass.states.get(sensor_entity_id)
|
sensor_state = hass.states.get(sensor_entity_id)
|
||||||
if sensor_state:
|
if sensor_state:
|
||||||
self._update_temp(sensor_state)
|
self._async_update_temp(sensor_state)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
@ -128,14 +133,15 @@ class GenericThermostat(ClimateDevice):
|
|||||||
"""Return the temperature we try to reach."""
|
"""Return the temperature we try to reach."""
|
||||||
return self._target_temp
|
return self._target_temp
|
||||||
|
|
||||||
def set_temperature(self, **kwargs):
|
@asyncio.coroutine
|
||||||
|
def async_set_temperature(self, **kwargs):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
temperature = kwargs.get(ATTR_TEMPERATURE)
|
temperature = kwargs.get(ATTR_TEMPERATURE)
|
||||||
if temperature is None:
|
if temperature is None:
|
||||||
return
|
return
|
||||||
self._target_temp = temperature
|
self._target_temp = temperature
|
||||||
self._control_heating()
|
self._async_control_heating()
|
||||||
self.schedule_update_ha_state()
|
yield from self.async_update_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_temp(self):
|
def min_temp(self):
|
||||||
@ -157,22 +163,25 @@ class GenericThermostat(ClimateDevice):
|
|||||||
# Get default temp from super class
|
# Get default temp from super class
|
||||||
return ClimateDevice.max_temp.fget(self)
|
return ClimateDevice.max_temp.fget(self)
|
||||||
|
|
||||||
def _sensor_changed(self, entity_id, old_state, new_state):
|
@asyncio.coroutine
|
||||||
|
def _async_sensor_changed(self, entity_id, old_state, new_state):
|
||||||
"""Called when temperature changes."""
|
"""Called when temperature changes."""
|
||||||
if new_state is None:
|
if new_state is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._update_temp(new_state)
|
self._async_update_temp(new_state)
|
||||||
self._control_heating()
|
self._async_control_heating()
|
||||||
self.schedule_update_ha_state()
|
yield from self.async_update_ha_state()
|
||||||
|
|
||||||
def _switch_changed(self, entity_id, old_state, new_state):
|
@callback
|
||||||
|
def _async_switch_changed(self, entity_id, old_state, new_state):
|
||||||
"""Called when heater switch changes state."""
|
"""Called when heater switch changes state."""
|
||||||
if new_state is None:
|
if new_state is None:
|
||||||
return
|
return
|
||||||
self.schedule_update_ha_state()
|
self.hass.async_add_job(self.async_update_ha_state())
|
||||||
|
|
||||||
def _update_temp(self, state):
|
@callback
|
||||||
|
def _async_update_temp(self, state):
|
||||||
"""Update thermostat with latest state from sensor."""
|
"""Update thermostat with latest state from sensor."""
|
||||||
unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||||
|
|
||||||
@ -182,7 +191,8 @@ class GenericThermostat(ClimateDevice):
|
|||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
_LOGGER.error('Unable to update from sensor: %s', ex)
|
_LOGGER.error('Unable to update from sensor: %s', ex)
|
||||||
|
|
||||||
def _control_heating(self):
|
@callback
|
||||||
|
def _async_control_heating(self):
|
||||||
"""Check if we need to turn heating on or off."""
|
"""Check if we need to turn heating on or off."""
|
||||||
if not self._active and None not in (self._cur_temp,
|
if not self._active and None not in (self._cur_temp,
|
||||||
self._target_temp):
|
self._target_temp):
|
||||||
@ -198,9 +208,9 @@ class GenericThermostat(ClimateDevice):
|
|||||||
current_state = STATE_ON
|
current_state = STATE_ON
|
||||||
else:
|
else:
|
||||||
current_state = STATE_OFF
|
current_state = STATE_OFF
|
||||||
long_enough = condition.state(self.hass, self.heater_entity_id,
|
long_enough = condition.state(
|
||||||
current_state,
|
self.hass, self.heater_entity_id, current_state,
|
||||||
self.min_cycle_duration)
|
self.min_cycle_duration)
|
||||||
if not long_enough:
|
if not long_enough:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -210,12 +220,12 @@ class GenericThermostat(ClimateDevice):
|
|||||||
too_cold = self._target_temp - self._cur_temp > self._tolerance
|
too_cold = self._target_temp - self._cur_temp > self._tolerance
|
||||||
if too_cold:
|
if too_cold:
|
||||||
_LOGGER.info('Turning off AC %s', self.heater_entity_id)
|
_LOGGER.info('Turning off AC %s', self.heater_entity_id)
|
||||||
switch.turn_off(self.hass, self.heater_entity_id)
|
switch.async_turn_off(self.hass, self.heater_entity_id)
|
||||||
else:
|
else:
|
||||||
too_hot = self._cur_temp - self._target_temp > self._tolerance
|
too_hot = self._cur_temp - self._target_temp > self._tolerance
|
||||||
if too_hot:
|
if too_hot:
|
||||||
_LOGGER.info('Turning on AC %s', self.heater_entity_id)
|
_LOGGER.info('Turning on AC %s', self.heater_entity_id)
|
||||||
switch.turn_on(self.hass, self.heater_entity_id)
|
switch.async_turn_on(self.hass, self.heater_entity_id)
|
||||||
else:
|
else:
|
||||||
is_heating = self._is_device_active
|
is_heating = self._is_device_active
|
||||||
if is_heating:
|
if is_heating:
|
||||||
@ -223,12 +233,12 @@ class GenericThermostat(ClimateDevice):
|
|||||||
if too_hot:
|
if too_hot:
|
||||||
_LOGGER.info('Turning off heater %s',
|
_LOGGER.info('Turning off heater %s',
|
||||||
self.heater_entity_id)
|
self.heater_entity_id)
|
||||||
switch.turn_off(self.hass, self.heater_entity_id)
|
switch.async_turn_off(self.hass, self.heater_entity_id)
|
||||||
else:
|
else:
|
||||||
too_cold = self._target_temp - self._cur_temp > self._tolerance
|
too_cold = self._target_temp - self._cur_temp > self._tolerance
|
||||||
if too_cold:
|
if too_cold:
|
||||||
_LOGGER.info('Turning on heater %s', self.heater_entity_id)
|
_LOGGER.info('Turning on heater %s', self.heater_entity_id)
|
||||||
switch.turn_on(self.hass, self.heater_entity_id)
|
switch.async_turn_on(self.hass, self.heater_entity_id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _is_device_active(self):
|
def _is_device_active(self):
|
||||||
|
@ -135,7 +135,7 @@ class MySensorsHVAC(mysensors.MySensorsDeviceEntity, ClimateDevice):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[value_type] = value
|
self._values[value_type] = value
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_fan_mode(self, fan):
|
def set_fan_mode(self, fan):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
@ -145,7 +145,7 @@ class MySensorsHVAC(mysensors.MySensorsDeviceEntity, ClimateDevice):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[set_req.V_HVAC_SPEED] = fan
|
self._values[set_req.V_HVAC_SPEED] = fan
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_operation_mode(self, operation_mode):
|
def set_operation_mode(self, operation_mode):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
@ -156,7 +156,7 @@ class MySensorsHVAC(mysensors.MySensorsDeviceEntity, ClimateDevice):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[set_req.V_HVAC_FLOW_STATE] = operation_mode
|
self._values[set_req.V_HVAC_FLOW_STATE] = operation_mode
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the controller with the latest value from a sensor."""
|
"""Update the controller with the latest value from a sensor."""
|
||||||
|
@ -111,7 +111,6 @@ class NetatmoThermostat(ClimateDevice):
|
|||||||
temp = None
|
temp = None
|
||||||
self._data.thermostatdata.setthermpoint(mode, temp, endTimeOffset=None)
|
self._data.thermostatdata.setthermpoint(mode, temp, endTimeOffset=None)
|
||||||
self._away = True
|
self._away = True
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
def turn_away_mode_off(self):
|
def turn_away_mode_off(self):
|
||||||
"""Turn away off."""
|
"""Turn away off."""
|
||||||
@ -119,7 +118,6 @@ class NetatmoThermostat(ClimateDevice):
|
|||||||
temp = None
|
temp = None
|
||||||
self._data.thermostatdata.setthermpoint(mode, temp, endTimeOffset=None)
|
self._data.thermostatdata.setthermpoint(mode, temp, endTimeOffset=None)
|
||||||
self._away = False
|
self._away = False
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
def set_temperature(self, endTimeOffset=DEFAULT_TIME_OFFSET, **kwargs):
|
def set_temperature(self, endTimeOffset=DEFAULT_TIME_OFFSET, **kwargs):
|
||||||
"""Set new target temperature for 2 hours."""
|
"""Set new target temperature for 2 hours."""
|
||||||
@ -131,7 +129,6 @@ class NetatmoThermostat(ClimateDevice):
|
|||||||
mode, temperature, endTimeOffset)
|
mode, temperature, endTimeOffset)
|
||||||
self._target_temperature = temperature
|
self._target_temperature = temperature
|
||||||
self._away = False
|
self._away = False
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||||
def update(self):
|
def update(self):
|
||||||
|
@ -223,10 +223,10 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice):
|
|||||||
# ZXT-120 responds only to whole int
|
# ZXT-120 responds only to whole int
|
||||||
value.data = round(temperature, 0)
|
value.data = round(temperature, 0)
|
||||||
self._target_temperature = temperature
|
self._target_temperature = temperature
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
else:
|
else:
|
||||||
value.data = temperature
|
value.data = temperature
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
break
|
break
|
||||||
|
|
||||||
def set_fan_mode(self, fan):
|
def set_fan_mode(self, fan):
|
||||||
|
@ -11,6 +11,7 @@ import os
|
|||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.config import load_yaml_config_file
|
from homeassistant.config import load_yaml_config_file
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.entity import ToggleEntity
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
@ -20,6 +21,7 @@ from homeassistant.const import (
|
|||||||
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
|
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
|
||||||
ATTR_ENTITY_ID)
|
ATTR_ENTITY_ID)
|
||||||
from homeassistant.components import group
|
from homeassistant.components import group
|
||||||
|
from homeassistant.util.async import run_callback_threadsafe
|
||||||
|
|
||||||
DOMAIN = 'switch'
|
DOMAIN = 'switch'
|
||||||
SCAN_INTERVAL = timedelta(seconds=30)
|
SCAN_INTERVAL = timedelta(seconds=30)
|
||||||
@ -47,21 +49,39 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def is_on(hass, entity_id=None):
|
def is_on(hass, entity_id=None):
|
||||||
"""Return if the switch is on based on the statemachine."""
|
"""Return if the switch is on based on the statemachine.
|
||||||
|
|
||||||
|
Async friendly.
|
||||||
|
"""
|
||||||
entity_id = entity_id or ENTITY_ID_ALL_SWITCHES
|
entity_id = entity_id or ENTITY_ID_ALL_SWITCHES
|
||||||
return hass.states.is_state(entity_id, STATE_ON)
|
return hass.states.is_state(entity_id, STATE_ON)
|
||||||
|
|
||||||
|
|
||||||
def turn_on(hass, entity_id=None):
|
def turn_on(hass, entity_id=None):
|
||||||
|
"""Turn all or specified switch on."""
|
||||||
|
run_callback_threadsafe(
|
||||||
|
hass.loop, async_turn_on, hass, entity_id).result()
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_turn_on(hass, entity_id=None):
|
||||||
"""Turn all or specified switch on."""
|
"""Turn all or specified switch on."""
|
||||||
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
|
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
|
||||||
hass.services.call(DOMAIN, SERVICE_TURN_ON, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_TURN_ON, data))
|
||||||
|
|
||||||
|
|
||||||
def turn_off(hass, entity_id=None):
|
def turn_off(hass, entity_id=None):
|
||||||
|
"""Turn all or specified switch off."""
|
||||||
|
run_callback_threadsafe(
|
||||||
|
hass.loop, async_turn_off, hass, entity_id).result()
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_turn_off(hass, entity_id=None):
|
||||||
"""Turn all or specified switch off."""
|
"""Turn all or specified switch off."""
|
||||||
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
|
data = {ATTR_ENTITY_ID: entity_id} if entity_id else None
|
||||||
hass.services.call(DOMAIN, SERVICE_TURN_OFF, data)
|
hass.async_add_job(
|
||||||
|
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, data))
|
||||||
|
|
||||||
|
|
||||||
def toggle(hass, entity_id=None):
|
def toggle(hass, entity_id=None):
|
||||||
|
@ -199,7 +199,10 @@ numeric_state_from_config = _threaded_factory(async_numeric_state_from_config)
|
|||||||
|
|
||||||
|
|
||||||
def state(hass, entity, req_state, for_period=None):
|
def state(hass, entity, req_state, for_period=None):
|
||||||
"""Test if state matches requirements."""
|
"""Test if state matches requirements.
|
||||||
|
|
||||||
|
Async friendly.
|
||||||
|
"""
|
||||||
if isinstance(entity, str):
|
if isinstance(entity, str):
|
||||||
entity = hass.states.get(entity)
|
entity = hass.states.get(entity)
|
||||||
|
|
||||||
@ -357,7 +360,7 @@ def time_from_config(config, config_validation=True):
|
|||||||
def zone(hass, zone_ent, entity):
|
def zone(hass, zone_ent, entity):
|
||||||
"""Test if zone-condition matches.
|
"""Test if zone-condition matches.
|
||||||
|
|
||||||
Can be run async.
|
Async friendly.
|
||||||
"""
|
"""
|
||||||
if isinstance(zone_ent, str):
|
if isinstance(zone_ent, str):
|
||||||
zone_ent = hass.states.get(zone_ent)
|
zone_ent = hass.states.get(zone_ent)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user