mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Add sensibo_assume_state service to Sensibo climate (#11567)
This commit is contained in:
parent
c5d5d57e9b
commit
6cc285aea5
@ -13,9 +13,10 @@ import async_timeout
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_TEMPERATURE, CONF_API_KEY, CONF_ID, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
ATTR_ENTITY_ID, ATTR_STATE, ATTR_TEMPERATURE, CONF_API_KEY, CONF_ID,
|
||||||
|
STATE_ON, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
ATTR_CURRENT_HUMIDITY, ClimateDevice, PLATFORM_SCHEMA,
|
ATTR_CURRENT_HUMIDITY, ClimateDevice, DOMAIN, PLATFORM_SCHEMA,
|
||||||
SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE,
|
SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE,
|
||||||
SUPPORT_FAN_MODE, SUPPORT_SWING_MODE,
|
SUPPORT_FAN_MODE, SUPPORT_SWING_MODE,
|
||||||
SUPPORT_AUX_HEAT, SUPPORT_ON_OFF)
|
SUPPORT_AUX_HEAT, SUPPORT_ON_OFF)
|
||||||
@ -24,18 +25,25 @@ from homeassistant.helpers import config_validation as cv
|
|||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.util.temperature import convert as convert_temperature
|
from homeassistant.util.temperature import convert as convert_temperature
|
||||||
|
|
||||||
REQUIREMENTS = ['pysensibo==1.0.1']
|
REQUIREMENTS = ['pysensibo==1.0.2']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ALL = 'all'
|
ALL = 'all'
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
|
|
||||||
|
SERVICE_ASSUME_STATE = 'sensibo_assume_state'
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_API_KEY): cv.string,
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
vol.Optional(CONF_ID, default=ALL): vol.All(cv.ensure_list, [cv.string]),
|
vol.Optional(CONF_ID, default=ALL): vol.All(cv.ensure_list, [cv.string]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ASSUME_STATE_SCHEMA = vol.Schema({
|
||||||
|
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
||||||
|
vol.Required(ATTR_STATE): cv.string,
|
||||||
|
})
|
||||||
|
|
||||||
_FETCH_FIELDS = ','.join([
|
_FETCH_FIELDS = ','.join([
|
||||||
'room{name}', 'measurements', 'remoteCapabilities',
|
'room{name}', 'measurements', 'remoteCapabilities',
|
||||||
'acState', 'connectionStatus{isAlive}', 'temperatureUnit'])
|
'acState', 'connectionStatus{isAlive}', 'temperatureUnit'])
|
||||||
@ -72,6 +80,28 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||||||
if devices:
|
if devices:
|
||||||
async_add_devices(devices)
|
async_add_devices(devices)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_assume_state(service):
|
||||||
|
"""Set state according to external service call.."""
|
||||||
|
entity_ids = service.data.get(ATTR_ENTITY_ID)
|
||||||
|
if entity_ids:
|
||||||
|
target_climate = [device for device in devices
|
||||||
|
if device.entity_id in entity_ids]
|
||||||
|
else:
|
||||||
|
target_climate = devices
|
||||||
|
|
||||||
|
update_tasks = []
|
||||||
|
for climate in target_climate:
|
||||||
|
yield from climate.async_assume_state(
|
||||||
|
service.data.get(ATTR_STATE))
|
||||||
|
update_tasks.append(climate.async_update_ha_state(True))
|
||||||
|
|
||||||
|
if update_tasks:
|
||||||
|
yield from asyncio.wait(update_tasks, loop=hass.loop)
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, SERVICE_ASSUME_STATE, async_assume_state,
|
||||||
|
schema=ASSUME_STATE_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
class SensiboClimate(ClimateDevice):
|
class SensiboClimate(ClimateDevice):
|
||||||
"""Representation of a Sensibo device."""
|
"""Representation of a Sensibo device."""
|
||||||
@ -84,6 +114,7 @@ class SensiboClimate(ClimateDevice):
|
|||||||
"""
|
"""
|
||||||
self._client = client
|
self._client = client
|
||||||
self._id = data['id']
|
self._id = data['id']
|
||||||
|
self._external_state = None
|
||||||
self._do_update(data)
|
self._do_update(data)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -115,6 +146,11 @@ class SensiboClimate(ClimateDevice):
|
|||||||
if key in FIELD_TO_FLAG:
|
if key in FIELD_TO_FLAG:
|
||||||
self._supported_features |= FIELD_TO_FLAG[key]
|
self._supported_features |= FIELD_TO_FLAG[key]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Return the current state."""
|
||||||
|
return self._external_state or super().state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the state attributes."""
|
"""Return the state attributes."""
|
||||||
@ -236,46 +272,66 @@ class SensiboClimate(ClimateDevice):
|
|||||||
|
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'targetTemperature', temperature)
|
self._id, 'targetTemperature', temperature, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_set_fan_mode(self, fan):
|
def async_set_fan_mode(self, fan):
|
||||||
"""Set new target fan mode."""
|
"""Set new target fan mode."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'fanLevel', fan)
|
self._id, 'fanLevel', fan, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_set_operation_mode(self, operation_mode):
|
def async_set_operation_mode(self, operation_mode):
|
||||||
"""Set new target operation mode."""
|
"""Set new target operation mode."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'mode', operation_mode)
|
self._id, 'mode', operation_mode, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_set_swing_mode(self, swing_mode):
|
def async_set_swing_mode(self, swing_mode):
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'swing', swing_mode)
|
self._id, 'swing', swing_mode, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_turn_aux_heat_on(self):
|
def async_turn_aux_heat_on(self):
|
||||||
"""Turn Sensibo unit on."""
|
"""Turn Sensibo unit on."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'on', True)
|
self._id, 'on', True, self._ac_states)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_turn_aux_heat_off(self):
|
def async_turn_aux_heat_off(self):
|
||||||
"""Turn Sensibo unit on."""
|
"""Turn Sensibo unit on."""
|
||||||
with async_timeout.timeout(TIMEOUT):
|
with async_timeout.timeout(TIMEOUT):
|
||||||
yield from self._client.async_set_ac_state_property(
|
yield from self._client.async_set_ac_state_property(
|
||||||
self._id, 'on', False)
|
self._id, 'on', False, self._ac_states)
|
||||||
|
|
||||||
async_on = async_turn_aux_heat_on
|
async_on = async_turn_aux_heat_on
|
||||||
async_off = async_turn_aux_heat_off
|
async_off = async_turn_aux_heat_off
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def async_assume_state(self, state):
|
||||||
|
"""Set external state."""
|
||||||
|
change_needed = (state != STATE_OFF and not self.is_on) \
|
||||||
|
or (state == STATE_OFF and self.is_on)
|
||||||
|
if change_needed:
|
||||||
|
with async_timeout.timeout(TIMEOUT):
|
||||||
|
yield from self._client.async_set_ac_state_property(
|
||||||
|
self._id,
|
||||||
|
'on',
|
||||||
|
state != STATE_OFF, # value
|
||||||
|
self._ac_states,
|
||||||
|
True # assumed_state
|
||||||
|
)
|
||||||
|
|
||||||
|
if state in [STATE_ON, STATE_OFF]:
|
||||||
|
self._external_state = None
|
||||||
|
else:
|
||||||
|
self._external_state = state
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_update(self):
|
def async_update(self):
|
||||||
"""Retrieve latest state."""
|
"""Retrieve latest state."""
|
||||||
|
@ -142,3 +142,13 @@ econet_delete_vacation:
|
|||||||
entity_id:
|
entity_id:
|
||||||
description: Name(s) of entities to change.
|
description: Name(s) of entities to change.
|
||||||
example: 'climate.water_heater'
|
example: 'climate.water_heater'
|
||||||
|
|
||||||
|
sensibo_assume_state:
|
||||||
|
description: Set Sensibo device to external state.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to change.
|
||||||
|
example: 'climate.kitchen'
|
||||||
|
state:
|
||||||
|
description: State to set.
|
||||||
|
example: 'idle'
|
||||||
|
@ -825,7 +825,7 @@ pyqwikswitch==0.4
|
|||||||
pyrainbird==0.1.3
|
pyrainbird==0.1.3
|
||||||
|
|
||||||
# homeassistant.components.climate.sensibo
|
# homeassistant.components.climate.sensibo
|
||||||
pysensibo==1.0.1
|
pysensibo==1.0.2
|
||||||
|
|
||||||
# homeassistant.components.sensor.serial
|
# homeassistant.components.sensor.serial
|
||||||
pyserial-asyncio==0.4
|
pyserial-asyncio==0.4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user