Allow passive zones

This commit is contained in:
Paulus Schoutsen 2016-01-21 23:53:57 -08:00
parent 9a092654e9
commit bb97af1504
2 changed files with 148 additions and 14 deletions

View file

@ -24,6 +24,9 @@ DEFAULT_NAME = 'Unnamed zone'
ATTR_RADIUS = 'radius'
DEFAULT_RADIUS = 100
ATTR_PASSIVE = 'passive'
DEFAULT_PASSIVE = False
ICON_HOME = 'mdi:home'
@ -37,6 +40,9 @@ def active_zone(hass, latitude, longitude, radius=0):
closest = None
for zone in zones:
if zone.attributes.get(ATTR_PASSIVE):
continue
zone_dist = distance(
latitude, longitude,
zone.attributes[ATTR_LATITUDE], zone.attributes[ATTR_LONGITUDE])
@ -78,13 +84,14 @@ def setup(hass, config):
longitude = entry.get(ATTR_LONGITUDE)
radius = entry.get(ATTR_RADIUS, DEFAULT_RADIUS)
icon = entry.get(ATTR_ICON)
passive = entry.get(ATTR_PASSIVE, DEFAULT_PASSIVE)
if None in (latitude, longitude):
logging.getLogger(__name__).error(
'Each zone needs a latitude and longitude.')
continue
zone = Zone(hass, name, latitude, longitude, radius, icon)
zone = Zone(hass, name, latitude, longitude, radius, icon, passive)
zone.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name,
entities)
zone.update_ha_state()
@ -92,7 +99,7 @@ def setup(hass, config):
if ENTITY_ID_HOME not in entities:
zone = Zone(hass, hass.config.location_name, hass.config.latitude,
hass.config.longitude, DEFAULT_RADIUS, ICON_HOME)
hass.config.longitude, DEFAULT_RADIUS, ICON_HOME, False)
zone.entity_id = ENTITY_ID_HOME
zone.update_ha_state()
@ -101,17 +108,15 @@ def setup(hass, config):
class Zone(Entity):
""" Represents a Zone in Home Assistant. """
# pylint: disable=too-many-arguments
def __init__(self, hass, name, latitude, longitude, radius, icon):
# pylint: disable=too-many-arguments, too-many-instance-attributes
def __init__(self, hass, name, latitude, longitude, radius, icon, passive):
self.hass = hass
self._name = name
self.latitude = latitude
self.longitude = longitude
self.radius = radius
self._latitude = latitude
self._longitude = longitude
self._radius = radius
self._icon = icon
def should_poll(self):
return False
self._passive = passive
@property
def name(self):
@ -128,9 +133,12 @@ class Zone(Entity):
@property
def state_attributes(self):
return {
data = {
ATTR_HIDDEN: True,
ATTR_LATITUDE: self.latitude,
ATTR_LONGITUDE: self.longitude,
ATTR_RADIUS: self.radius,
ATTR_LATITUDE: self._latitude,
ATTR_LONGITUDE: self._longitude,
ATTR_RADIUS: self._radius,
}
if self._passive:
data[ATTR_PASSIVE] = self._passive
return data

View file

@ -0,0 +1,126 @@
"""
tests.components.automation.test_location
±±±~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tests location automation.
"""
import unittest
from homeassistant.components import zone
from tests.common import get_test_home_assistant
class TestAutomationZone(unittest.TestCase):
""" Test the event automation. """
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_setup(self):
info = {
'name': 'Test Zone',
'latitude': 32.880837,
'longitude': -117.237561,
'radius': 250,
'passive': True
}
assert zone.setup(self.hass, {
'zone': info
})
state = self.hass.states.get('zone.test_zone')
assert info['name'] == state.name
assert info['latitude'] == state.attributes['latitude']
assert info['longitude'] == state.attributes['longitude']
assert info['radius'] == state.attributes['radius']
assert info['passive'] == state.attributes['passive']
def test_active_zone_skips_passive_zones(self):
assert zone.setup(self.hass, {
'zone': [
{
'name': 'Passive Zone',
'latitude': 32.880600,
'longitude': -117.237561,
'radius': 250,
'passive': True
},
]
})
active = zone.active_zone(self.hass, 32.880600, -117.237561)
assert active is None
assert zone.setup(self.hass, {
'zone': [
{
'name': 'Active Zone',
'latitude': 32.880800,
'longitude': -117.237561,
'radius': 500,
},
]
})
active = zone.active_zone(self.hass, 32.880700, -117.237561)
assert 'zone.active_zone' == active.entity_id
def test_active_zone_prefers_smaller_zone_if_same_distance(self):
latitude = 32.880600
longitude = -117.237561
assert zone.setup(self.hass, {
'zone': [
{
'name': 'Small Zone',
'latitude': latitude,
'longitude': longitude,
'radius': 250,
},
{
'name': 'Big Zone',
'latitude': latitude,
'longitude': longitude,
'radius': 500,
},
]
})
active = zone.active_zone(self.hass, latitude, longitude)
assert 'zone.small_zone' == active.entity_id
assert zone.setup(self.hass, {
'zone': [
{
'name': 'Smallest Zone',
'latitude': latitude,
'longitude': longitude,
'radius': 50,
},
]
})
active = zone.active_zone(self.hass, latitude, longitude)
assert 'zone.smallest_zone' == active.entity_id
def test_in_zone_works_for_passive_zones(self):
latitude = 32.880600
longitude = -117.237561
assert zone.setup(self.hass, {
'zone': [
{
'name': 'Passive Zone',
'latitude': latitude,
'longitude': longitude,
'radius': 250,
'passive': True
},
]
})
assert zone.in_zone(self.hass.states.get('zone.passive_zone'),
latitude, longitude)