Generalized REST switch to enable templating and configurable timeout. (#3329)
* successfully tested the "remote temperature mode" switch for the radio thermostat * removed logging and interpreted None as Off. * turn_off value is also templated now -- can depend on state Also, undid accidental removal of error logging. * ensured backward compatibility of config file if value_template is not provided, the update function behaves as before * ran autopep8 --in-place * fixed another complaint of tox * addressed the comments of balloob * undid acccidental log.error to log.info * timeout : 50 -> 10 * added a timeout parameter * removed the stray '-', better names for the failure case * string comparisons after .lower(), as suggested by balloob * addressed balloob's latest requests * making flake happy * value_template --> is_on_template in config file * moved CONF_IS_ON_TEMPLATE to local file * null checks * addressed flake error * properly comparing template text when is_on is not a template.
This commit is contained in:
parent
d8c1013b09
commit
65bd7d2326
1 changed files with 49 additions and 15 deletions
|
@ -10,7 +10,8 @@ import requests
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
|
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
|
||||||
from homeassistant.const import (CONF_NAME, CONF_RESOURCE)
|
from homeassistant.const import (
|
||||||
|
CONF_NAME, CONF_RESOURCE, CONF_TIMEOUT)
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
CONF_BODY_OFF = 'body_off'
|
CONF_BODY_OFF = 'body_off'
|
||||||
|
@ -18,12 +19,16 @@ CONF_BODY_ON = 'body_on'
|
||||||
DEFAULT_BODY_OFF = 'OFF'
|
DEFAULT_BODY_OFF = 'OFF'
|
||||||
DEFAULT_BODY_ON = 'ON'
|
DEFAULT_BODY_ON = 'ON'
|
||||||
DEFAULT_NAME = 'REST Switch'
|
DEFAULT_NAME = 'REST Switch'
|
||||||
|
DEFAULT_TIMEOUT = 10
|
||||||
|
CONF_IS_ON_TEMPLATE = 'is_on_template'
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_RESOURCE): cv.url,
|
vol.Required(CONF_RESOURCE): cv.url,
|
||||||
vol.Optional(CONF_BODY_OFF, default=DEFAULT_BODY_OFF): cv.string,
|
vol.Optional(CONF_BODY_OFF, default=DEFAULT_BODY_OFF): cv.template,
|
||||||
vol.Optional(CONF_BODY_ON, default=DEFAULT_BODY_ON): cv.string,
|
vol.Optional(CONF_BODY_ON, default=DEFAULT_BODY_ON): cv.template,
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
|
vol.Optional(CONF_IS_ON_TEMPLATE): cv.template,
|
||||||
|
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||||
})
|
})
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -36,6 +41,15 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
resource = config.get(CONF_RESOURCE)
|
resource = config.get(CONF_RESOURCE)
|
||||||
body_on = config.get(CONF_BODY_ON)
|
body_on = config.get(CONF_BODY_ON)
|
||||||
body_off = config.get(CONF_BODY_OFF)
|
body_off = config.get(CONF_BODY_OFF)
|
||||||
|
is_on_template = config.get(CONF_IS_ON_TEMPLATE)
|
||||||
|
|
||||||
|
if is_on_template is not None:
|
||||||
|
is_on_template.hass = hass
|
||||||
|
if body_on is not None:
|
||||||
|
body_on.hass = hass
|
||||||
|
if body_off is not None:
|
||||||
|
body_off.hass = hass
|
||||||
|
timeout = config.get(CONF_TIMEOUT)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
requests.get(resource, timeout=10)
|
requests.get(resource, timeout=10)
|
||||||
|
@ -47,14 +61,18 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
_LOGGER.error("No route to resource/endpoint: %s", resource)
|
_LOGGER.error("No route to resource/endpoint: %s", resource)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
add_devices_callback([RestSwitch(hass, name, resource, body_on, body_off)])
|
add_devices_callback(
|
||||||
|
[RestSwitch(hass, name, resource,
|
||||||
|
body_on, body_off, is_on_template, timeout)])
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
class RestSwitch(SwitchDevice):
|
class RestSwitch(SwitchDevice):
|
||||||
"""Representation of a switch that can be toggled using REST."""
|
"""Representation of a switch that can be toggled using REST."""
|
||||||
|
|
||||||
def __init__(self, hass, name, resource, body_on, body_off):
|
# pylint: disable=too-many-instance-attributes
|
||||||
|
def __init__(self, hass, name, resource, body_on, body_off,
|
||||||
|
is_on_template, timeout):
|
||||||
"""Initialize the REST switch."""
|
"""Initialize the REST switch."""
|
||||||
self._state = None
|
self._state = None
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
|
@ -62,6 +80,8 @@ class RestSwitch(SwitchDevice):
|
||||||
self._resource = resource
|
self._resource = resource
|
||||||
self._body_on = body_on
|
self._body_on = body_on
|
||||||
self._body_off = body_off
|
self._body_off = body_off
|
||||||
|
self._is_on_template = is_on_template
|
||||||
|
self._timeout = timeout
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -75,9 +95,10 @@ class RestSwitch(SwitchDevice):
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
|
body_on_t = self._body_on.render()
|
||||||
request = requests.post(self._resource,
|
request = requests.post(self._resource,
|
||||||
data=self._body_on,
|
data=body_on_t,
|
||||||
timeout=10)
|
timeout=self._timeout)
|
||||||
if request.status_code == 200:
|
if request.status_code == 200:
|
||||||
self._state = True
|
self._state = True
|
||||||
else:
|
else:
|
||||||
|
@ -86,9 +107,10 @@ class RestSwitch(SwitchDevice):
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
|
body_off_t = self._body_off.render()
|
||||||
request = requests.post(self._resource,
|
request = requests.post(self._resource,
|
||||||
data=self._body_off,
|
data=body_off_t,
|
||||||
timeout=10)
|
timeout=self._timeout)
|
||||||
if request.status_code == 200:
|
if request.status_code == 200:
|
||||||
self._state = False
|
self._state = False
|
||||||
else:
|
else:
|
||||||
|
@ -97,10 +119,22 @@ class RestSwitch(SwitchDevice):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data from REST API and update the state."""
|
"""Get the latest data from REST API and update the state."""
|
||||||
request = requests.get(self._resource, timeout=10)
|
request = requests.get(self._resource, timeout=self._timeout)
|
||||||
if request.text == self._body_on:
|
|
||||||
self._state = True
|
if self._is_on_template is not None:
|
||||||
elif request.text == self._body_off:
|
response = self._is_on_template.render_with_possible_json_value(
|
||||||
self._state = False
|
request.text, 'None')
|
||||||
|
response = response.lower()
|
||||||
|
if response == 'true':
|
||||||
|
self._state = True
|
||||||
|
elif response == 'false':
|
||||||
|
self._state = False
|
||||||
|
else:
|
||||||
|
self._state = None
|
||||||
else:
|
else:
|
||||||
self._state = None
|
if request.text == self._body_on.template:
|
||||||
|
self._state = True
|
||||||
|
elif request.text == self._body_off.template:
|
||||||
|
self._state = False
|
||||||
|
else:
|
||||||
|
self._state = None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue