Initial version input_boolean
parent
40c75f0a51
commit
475b631d9c
|
@ -0,0 +1,124 @@
|
|||
"""
|
||||
Component to keep track of user controlled booleans for within automation.
|
||||
|
||||
For more details about this component, please refer to the documentation
|
||||
at https://home-assistant.io/components/input_boolean/
|
||||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.const import (
|
||||
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.util import slugify
|
||||
|
||||
DOMAIN = 'input_boolean'
|
||||
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_NAME = "name"
|
||||
CONF_INITIAL = "initial"
|
||||
CONF_ICON = "icon"
|
||||
|
||||
|
||||
def is_on(hass, entity_id):
|
||||
"""Test if input_boolean is True."""
|
||||
return hass.states.is_state(entity_id, STATE_ON)
|
||||
|
||||
|
||||
def turn_on(hass, entity_id):
|
||||
"""Set input_boolean to True."""
|
||||
hass.services.call(DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id})
|
||||
|
||||
|
||||
def turn_off(hass, entity_id):
|
||||
"""Set input_boolean to False."""
|
||||
hass.services.call(DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id})
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up input booleans."""
|
||||
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:
|
||||
cfg = {}
|
||||
|
||||
name = cfg.get(CONF_NAME)
|
||||
state = cfg.get(CONF_INITIAL, False)
|
||||
icon = cfg.get(CONF_ICON)
|
||||
|
||||
entities.append(InputBoolean(object_id, name, state, icon))
|
||||
|
||||
if not entities:
|
||||
return False
|
||||
|
||||
component.add_entities(entities)
|
||||
|
||||
def toggle_service(service):
|
||||
"""Handle a calls to the input boolean services."""
|
||||
target_inputs = component.extract_from_service(service)
|
||||
|
||||
for input_b in target_inputs:
|
||||
if service.service == SERVICE_TURN_ON:
|
||||
input_b.turn_on()
|
||||
else:
|
||||
input_b.turn_off()
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_TURN_OFF, toggle_service)
|
||||
hass.services.register(DOMAIN, SERVICE_TURN_ON, toggle_service)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class InputBoolean(ToggleEntity):
|
||||
"""Represent a boolean input within Home Assistant."""
|
||||
|
||||
def __init__(self, object_id, name, state, icon):
|
||||
"""Initialize a boolean input."""
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(object_id)
|
||||
self._name = name
|
||||
self._state = state
|
||||
self._icon = icon
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""If entitiy should be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the boolean input."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to be used for this entity."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""True if entity is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the entity on."""
|
||||
self._state = True
|
||||
self.update_ha_state()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the entity off."""
|
||||
self._state = False
|
||||
self.update_ha_state()
|
|
@ -0,0 +1,95 @@
|
|||
"""
|
||||
tests.components.test_input_boolean
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests input_boolean component.
|
||||
"""
|
||||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import unittest
|
||||
|
||||
from homeassistant.components import input_boolean
|
||||
from homeassistant.const import (
|
||||
STATE_ON, STATE_OFF, ATTR_ICON, ATTR_FRIENDLY_NAME)
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class TestInputBoolean(unittest.TestCase):
|
||||
""" Test the input boolean module. """
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
""" Stop down stuff we started. """
|
||||
self.hass.stop()
|
||||
|
||||
def test_config(self):
|
||||
"""Test config."""
|
||||
self.assertFalse(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
'test 1': None,
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
}
|
||||
}))
|
||||
|
||||
def test_methods(self):
|
||||
""" Test is_on, turn_on, turn_off methods. """
|
||||
self.assertTrue(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
'test_1': None,
|
||||
}
|
||||
}))
|
||||
entity_id = 'input_boolean.test_1'
|
||||
|
||||
self.assertFalse(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
|
||||
input_boolean.turn_on(self.hass, entity_id)
|
||||
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
self.assertTrue(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
|
||||
input_boolean.turn_off(self.hass, entity_id)
|
||||
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
self.assertFalse(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
|
||||
def test_config_options(self):
|
||||
count_start = len(self.hass.states.entity_ids())
|
||||
|
||||
self.assertTrue(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
'test_1': None,
|
||||
'test_2': {
|
||||
'name': 'Hello World',
|
||||
'icon': 'work',
|
||||
'initial': True,
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
self.assertEqual(count_start + 2, len(self.hass.states.entity_ids()))
|
||||
|
||||
state_1 = self.hass.states.get('input_boolean.test_1')
|
||||
state_2 = self.hass.states.get('input_boolean.test_2')
|
||||
|
||||
self.assertIsNotNone(state_1)
|
||||
self.assertIsNotNone(state_2)
|
||||
|
||||
self.assertEqual(STATE_OFF, state_1.state)
|
||||
self.assertNotIn(ATTR_ICON, state_1.attributes)
|
||||
self.assertNotIn(ATTR_FRIENDLY_NAME, state_1.attributes)
|
||||
|
||||
self.assertEqual(STATE_ON, state_2.state)
|
||||
self.assertEqual('Hello World',
|
||||
state_2.attributes.get(ATTR_FRIENDLY_NAME))
|
||||
self.assertEqual('work', state_2.attributes.get(ATTR_ICON))
|
Loading…
Reference in New Issue