core/homeassistant/components/input_slider.py

162 lines
4.5 KiB
Python
Raw Normal View History

2016-03-14 21:03:30 +00:00
"""
Component to offer a way to select a value from a slider.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_slider/
"""
import logging
import voluptuous as vol
2016-06-10 06:27:35 +00:00
from homeassistant.const import ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT
import homeassistant.helpers.config_validation as cv
2016-03-14 21:03:30 +00:00
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.util import slugify
DOMAIN = 'input_slider'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
_LOGGER = logging.getLogger(__name__)
CONF_NAME = 'name'
CONF_INITIAL = 'initial'
CONF_MIN = 'min'
CONF_MAX = 'max'
CONF_ICON = 'icon'
CONF_STEP = 'step'
ATTR_VALUE = 'value'
ATTR_MIN = 'min'
ATTR_MAX = 'max'
ATTR_STEP = 'step'
SERVICE_SELECT_VALUE = 'select_value'
SERVICE_SELECT_VALUE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_VALUE): vol.Coerce(float),
})
2016-03-14 21:03:30 +00:00
def select_value(hass, entity_id, value):
"""Set input_slider to value."""
hass.services.call(DOMAIN, SERVICE_SELECT_VALUE, {
ATTR_ENTITY_ID: entity_id,
ATTR_VALUE: value,
})
def setup(hass, config):
"""Set up input slider."""
if not isinstance(config.get(DOMAIN), dict):
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
return False
component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = []
for object_id, cfg in config[DOMAIN].items():
if object_id != slugify(object_id):
_LOGGER.warning("Found invalid key for boolean input: %s. "
"Use %s instead", object_id, slugify(object_id))
continue
if not cfg:
_LOGGER.warning("No configuration specified for %s", object_id)
continue
name = cfg.get(CONF_NAME)
minimum = cfg.get(CONF_MIN)
maximum = cfg.get(CONF_MAX)
2016-06-10 06:27:35 +00:00
state = cfg.get(CONF_INITIAL, minimum)
step = cfg.get(CONF_STEP, 1)
2016-03-14 21:03:30 +00:00
icon = cfg.get(CONF_ICON)
2016-06-10 06:27:35 +00:00
unit = cfg.get(ATTR_UNIT_OF_MEASUREMENT)
2016-03-14 21:03:30 +00:00
if state < minimum:
state = minimum
if state > maximum:
state = maximum
2016-06-10 06:27:35 +00:00
entities.append(InputSlider(object_id, name, state, minimum, maximum,
step, icon, unit))
2016-03-14 21:03:30 +00:00
if not entities:
return False
def select_value_service(call):
"""Handle a calls to the input slider services."""
target_inputs = component.extract_from_service(call)
for input_slider in target_inputs:
input_slider.select_value(call.data[ATTR_VALUE])
2016-03-14 21:03:30 +00:00
hass.services.register(DOMAIN, SERVICE_SELECT_VALUE,
select_value_service,
schema=SERVICE_SELECT_VALUE_SCHEMA)
2016-03-14 21:03:30 +00:00
component.add_entities(entities)
return True
class InputSlider(Entity):
"""Represent an slider."""
2016-06-10 06:41:23 +00:00
# pylint: disable=too-many-arguments, too-many-instance-attributes
2016-06-10 06:27:35 +00:00
def __init__(self, object_id, name, state, minimum, maximum, step, icon,
unit):
2016-03-14 21:03:30 +00:00
"""Initialize a select input."""
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self._name = name
self._current_value = state
self._minimum = minimum
self._maximum = maximum
self._step = step
self._icon = icon
2016-06-10 06:27:35 +00:00
self._unit = unit
2016-03-14 21:03:30 +00:00
@property
def should_poll(self):
"""If entity should be polled."""
return False
@property
def name(self):
"""Name of the select input."""
return self._name
@property
def icon(self):
"""Icon to be used for this entity."""
return self._icon
@property
def state(self):
"""State of the component."""
return self._current_value
2016-06-10 06:27:35 +00:00
@property
def unit_of_measurement(self):
2016-06-10 06:41:23 +00:00
"""Unit of measurement of slider."""
2016-06-10 06:27:35 +00:00
return self._unit
2016-03-14 21:03:30 +00:00
@property
def state_attributes(self):
"""State attributes."""
return {
ATTR_MIN: self._minimum,
ATTR_MAX: self._maximum,
ATTR_STEP: self._step
}
def select_value(self, value):
"""Select new value."""
num_value = float(value)
2016-03-14 21:03:30 +00:00
if num_value < self._minimum or num_value > self._maximum:
_LOGGER.warning('Invalid value: %s (range %s - %s)',
num_value, self._minimum, self._maximum)
return
self._current_value = num_value
self.update_ha_state()