Add state_as_number() helper
This adds state_as_number(), a helper method that tries to interpret state as a number, for cases we can predict. It's a generalization of what is copy-and-paste-ed into multiple other places.
This commit is contained in:
parent
4ce1a67c13
commit
3aa34deaa2
2 changed files with 72 additions and 2 deletions
|
@ -8,8 +8,11 @@ import homeassistant.util.dt as dt_util
|
|||
from homeassistant.const import (
|
||||
STATE_ON, STATE_OFF, SERVICE_TURN_ON, SERVICE_TURN_OFF,
|
||||
SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE,
|
||||
STATE_PLAYING, STATE_PAUSED, ATTR_ENTITY_ID)
|
||||
|
||||
STATE_PLAYING, STATE_PAUSED, ATTR_ENTITY_ID,
|
||||
STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN,
|
||||
STATE_OPEN, STATE_CLOSED)
|
||||
from homeassistant.components.sun import (STATE_ABOVE_HORIZON,
|
||||
STATE_BELOW_HORIZON)
|
||||
from homeassistant.components.media_player import (SERVICE_PLAY_MEDIA)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -92,3 +95,30 @@ def reproduce_state(hass, states, blocking=False):
|
|||
data = json.loads(service_data)
|
||||
data[ATTR_ENTITY_ID] = entity_ids
|
||||
hass.services.call(service_domain, service, data, blocking)
|
||||
|
||||
|
||||
def state_as_number(state):
|
||||
"""Try to coerce our state to a number.
|
||||
|
||||
Raises ValueError if this is not possible.
|
||||
"""
|
||||
|
||||
if state.state in (STATE_ON, STATE_LOCKED, STATE_ABOVE_HORIZON,
|
||||
STATE_OPEN):
|
||||
return 1
|
||||
elif state.state in (STATE_OFF, STATE_UNLOCKED, STATE_UNKNOWN,
|
||||
STATE_BELOW_HORIZON, STATE_CLOSED):
|
||||
return 0
|
||||
else:
|
||||
try:
|
||||
# This distinction is probably not important,
|
||||
# but in case something downstream cares about
|
||||
# int vs. float, try to be helpful here.
|
||||
if '.' in state.state:
|
||||
return float(state.state)
|
||||
else:
|
||||
return int(state.state)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
raise ValueError('State is not a number')
|
||||
|
|
|
@ -13,6 +13,12 @@ import homeassistant.components as core_components
|
|||
from homeassistant.const import SERVICE_TURN_ON
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.helpers import state
|
||||
from homeassistant.const import (
|
||||
STATE_OFF, STATE_OPEN, STATE_CLOSED,
|
||||
STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN,
|
||||
STATE_ON, STATE_OFF)
|
||||
from homeassistant.components.sun import (STATE_ABOVE_HORIZON,
|
||||
STATE_BELOW_HORIZON)
|
||||
|
||||
from tests.common import get_test_home_assistant, mock_service
|
||||
|
||||
|
@ -146,3 +152,37 @@ class TestStateHelpers(unittest.TestCase):
|
|||
self.assertEqual(['light.test1', 'light.test2'],
|
||||
last_call.data.get('entity_id'))
|
||||
self.assertEqual(95, last_call.data.get('brightness'))
|
||||
|
||||
def test_as_number_states(self):
|
||||
zero_states = (STATE_OFF, STATE_CLOSED, STATE_UNLOCKED,
|
||||
STATE_BELOW_HORIZON)
|
||||
one_states = (STATE_ON, STATE_OPEN, STATE_LOCKED, STATE_ABOVE_HORIZON)
|
||||
for _state in zero_states:
|
||||
self.assertEqual(0, state.state_as_number(
|
||||
ha.State('domain.test', _state, {})))
|
||||
for _state in one_states:
|
||||
self.assertEqual(1, state.state_as_number(
|
||||
ha.State('domain.test', _state, {})))
|
||||
|
||||
def test_as_number_coercion(self):
|
||||
for _state in ('0', '0.0'):
|
||||
self.assertEqual(
|
||||
0.0, float(state.state_as_number(
|
||||
ha.State('domain.test', _state, {}))))
|
||||
for _state in ('1', '1.0'):
|
||||
self.assertEqual(
|
||||
1.0, float(state.state_as_number(
|
||||
ha.State('domain.test', _state, {}))))
|
||||
|
||||
def test_as_number_tries_to_keep_types(self):
|
||||
result = state.state_as_number(ha.State('domain.test', '1', {}))
|
||||
self.assertTrue(isinstance(result, int))
|
||||
result = state.state_as_number(ha.State('domain.test', '1.0', {}))
|
||||
self.assertTrue(isinstance(result, float))
|
||||
|
||||
def test_as_number_invalid_cases(self):
|
||||
for _state in ('', 'foo', 'foo.bar', None, False, True, None,
|
||||
object, object()):
|
||||
self.assertRaises(ValueError,
|
||||
state.state_as_number,
|
||||
ha.State('domain.test', _state, {}))
|
||||
|
|
Loading…
Add table
Reference in a new issue