mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
commit
663e4d57d9
145
homeassistant/components/input_slider.py
Normal file
145
homeassistant/components/input_slider.py
Normal file
@ -0,0 +1,145 @@
|
||||
"""
|
||||
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
|
||||
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
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'
|
||||
|
||||
|
||||
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)
|
||||
state = cfg.get(CONF_INITIAL)
|
||||
step = cfg.get(CONF_STEP)
|
||||
icon = cfg.get(CONF_ICON)
|
||||
|
||||
if state < minimum:
|
||||
state = minimum
|
||||
if state > maximum:
|
||||
state = maximum
|
||||
|
||||
entities.append(
|
||||
InputSlider(object_id, name, state, minimum, maximum, step, icon)
|
||||
)
|
||||
|
||||
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.get(ATTR_VALUE))
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SELECT_VALUE,
|
||||
select_value_service)
|
||||
|
||||
component.add_entities(entities)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class InputSlider(Entity):
|
||||
"""Represent an slider."""
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(self, object_id, name, state, minimum, maximum, step, icon):
|
||||
"""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
|
||||
|
||||
@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
|
||||
|
||||
@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 = int(value)
|
||||
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()
|
64
tests/components/test_input_slider.py
Normal file
64
tests/components/test_input_slider.py
Normal file
@ -0,0 +1,64 @@
|
||||
"""The tests for the Input slider component."""
|
||||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import unittest
|
||||
|
||||
from homeassistant.components import input_slider
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class TestInputSlider(unittest.TestCase):
|
||||
"""Test the input slider component."""
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def test_config(self):
|
||||
"""Test config."""
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': None
|
||||
}))
|
||||
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
'name with space': None
|
||||
}
|
||||
}))
|
||||
|
||||
def test_select_value(self):
|
||||
"""Test select_value method."""
|
||||
self.assertTrue(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
'test_1': {
|
||||
'initial': 50,
|
||||
'min': 0,
|
||||
'max': 100,
|
||||
},
|
||||
}
|
||||
}))
|
||||
entity_id = 'input_slider.test_1'
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual('50', state.state)
|
||||
|
||||
input_slider.select_value(self.hass, entity_id, '70')
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual('70', state.state)
|
||||
|
||||
input_slider.select_value(self.hass, entity_id, '110')
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual('70', state.state)
|
Loading…
x
Reference in New Issue
Block a user