From 1dc9bfdf737365291ec1bcd127a47c1db0901d26 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 29 Sep 2015 23:08:37 -0700 Subject: [PATCH] Update config zones --- homeassistant/components/automation/zone.py | 30 +++++------ .../components/device_tracker/__init__.py | 5 +- .../www_static/home-assistant-polymer | 2 +- homeassistant/components/zone.py | 50 +++++++++++-------- homeassistant/const.py | 3 ++ tests/components/automation/test_zone.py | 3 +- 6 files changed, 53 insertions(+), 40 deletions(-) diff --git a/homeassistant/components/automation/zone.py b/homeassistant/components/automation/zone.py index aec2f44b0d8..553d59b7da1 100644 --- a/homeassistant/components/automation/zone.py +++ b/homeassistant/components/automation/zone.py @@ -8,7 +8,8 @@ import logging from homeassistant.components import zone from homeassistant.helpers.event import track_state_change -from homeassistant.const import MATCH_ALL, ATTR_LATITUDE, ATTR_LONGITUDE +from homeassistant.const import ( + ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE, MATCH_ALL) CONF_ENTITY_ID = "entity_id" @@ -42,16 +43,8 @@ def trigger(hass, config, action): to_s.attributes.get(ATTR_LONGITUDE)): return - if from_s: - from_zone = zone.in_zone( - hass, from_s.attributes.get(ATTR_LATITUDE), - from_s.attributes.get(ATTR_LONGITUDE)) - else: - from_zone = None - - to_zone = zone.in_zone(hass, to_s.attributes.get(ATTR_LATITUDE), - to_s.attributes.get(ATTR_LONGITUDE)) - + from_zone = _in_zone(hass, from_s) if from_s else None + to_zone = _in_zone(hass, to_s) from_match = from_zone and from_zone.entity_id == zone_entity_id to_match = to_zone and to_zone.entity_id == zone_entity_id @@ -80,13 +73,20 @@ def if_action(hass, config): """ Test if condition. """ state = hass.states.get(entity_id) - if None in (state.attributes.get(ATTR_LATITUDE), - state.attributes.get(ATTR_LONGITUDE)): + if not state or None in (state.attributes.get(ATTR_LATITUDE), + state.attributes.get(ATTR_LONGITUDE)): return - cur_zone = zone.in_zone(hass, state.attributes.get(ATTR_LATITUDE), - state.attributes.get(ATTR_LONGITUDE)) + cur_zone = _in_zone(hass, state) return cur_zone and cur_zone.entity_id == zone_entity_id return if_in_zone + + +def _in_zone(hass, state): + """ Check if state is in zone. """ + return zone.in_zone( + hass, state.attributes.get(ATTR_LATITUDE), + state.attributes.get(ATTR_LONGITUDE), + state.attributes.get(ATTR_GPS_ACCURACY, 0)) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 38c66ee3949..31729b5d4a6 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -40,8 +40,8 @@ import homeassistant.util.dt as dt_util from homeassistant.helpers.event import track_utc_time_change from homeassistant.const import ( - ATTR_ENTITY_PICTURE, ATTR_LATITUDE, ATTR_LONGITUDE, DEVICE_DEFAULT_NAME, - STATE_HOME, STATE_NOT_HOME) + ATTR_ENTITY_PICTURE, ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE, + DEVICE_DEFAULT_NAME, STATE_HOME, STATE_NOT_HOME) DOMAIN = "device_tracker" DEPENDENCIES = ['zone'] @@ -76,7 +76,6 @@ ATTR_DEV_ID = 'dev_id' ATTR_HOST_NAME = 'host_name' ATTR_LOCATION_NAME = 'location_name' ATTR_GPS = 'gps' -ATTR_GPS_ACCURACY = 'gps_accuracy' ATTR_BATTERY = 'battery' DISCOVERY_PLATFORMS = { diff --git a/homeassistant/components/frontend/www_static/home-assistant-polymer b/homeassistant/components/frontend/www_static/home-assistant-polymer index b3fc452598f..4dba9729274 160000 --- a/homeassistant/components/frontend/www_static/home-assistant-polymer +++ b/homeassistant/components/frontend/www_static/home-assistant-polymer @@ -1 +1 @@ -Subproject commit b3fc452598f13d3508f4c7329a27b71ffb19d53b +Subproject commit 4dba97292744a32146e35e36031dbca59eb62733 diff --git a/homeassistant/components/zone.py b/homeassistant/components/zone.py index e89777e2fdd..6948188b400 100644 --- a/homeassistant/components/zone.py +++ b/homeassistant/components/zone.py @@ -4,7 +4,8 @@ homeassistant.components.zone Allows defintion of zones in Home Assistant. -zone School: +zone: + name: School latitude: 32.8773367 longitude: -117.2494053 # Optional radius in meters (default: 100) @@ -14,14 +15,16 @@ zone School: # Example: home, work, group-work, shopping-cart icon: group-work -zone Work: +zone: + name: Work latitude: 32.8753367 longitude: -117.2474053 """ import logging -from homeassistant.const import ATTR_HIDDEN, ATTR_LATITUDE, ATTR_LONGITUDE +from homeassistant.const import ( + ATTR_HIDDEN, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_NAME) from homeassistant.helpers import extract_domain_configs, generate_entity_id from homeassistant.helpers.entity import Entity from homeassistant.util.location import distance @@ -32,6 +35,8 @@ ENTITY_ID_FORMAT = 'zone.{}' ENTITY_ID_HOME = ENTITY_ID_FORMAT.format('home') STATE = 'zoning' +DEFAULT_NAME = 'Unnamed zone' + ATTR_RADIUS = 'radius' DEFAULT_RADIUS = 100 @@ -39,7 +44,7 @@ ATTR_ICON = 'icon' ICON_HOME = 'home' -def in_zone(hass, latitude, longitude): +def in_zone(hass, latitude, longitude, radius=0): """ Find the zone for given latitude, longitude. """ # Sort entity IDs so that we are deterministic if equal distance to 2 zones zones = (hass.states.get(entity_id) for entity_id @@ -53,8 +58,8 @@ def in_zone(hass, latitude, longitude): zone.attributes[ATTR_LATITUDE], zone.attributes[ATTR_LONGITUDE]) - if zone_dist < zone.attributes[ATTR_RADIUS] and (closest is None or - zone_dist < min_dist): + if zone_dist - radius < zone.attributes[ATTR_RADIUS] and \ + (closest is None or zone_dist < min_dist): min_dist = zone_dist closest = zone @@ -66,22 +71,27 @@ def setup(hass, config): entities = set() for key in extract_domain_configs(config, DOMAIN): - conf = config[key] - name = key.split(' ')[1] - latitude = conf.get(ATTR_LATITUDE) - longitude = conf.get(ATTR_LONGITUDE) - radius = conf.get(ATTR_RADIUS, DEFAULT_RADIUS) - icon = conf.get(ATTR_ICON) + entries = config[key] + if not isinstance(entries, list): + entries = entries, - if None in (latitude, longitude): - logging.getLogger(__name__).error( - 'Each zone needs a latitude and longitude.') - continue + for entry in entries: + name = entry.get(CONF_NAME, DEFAULT_NAME) + latitude = entry.get(ATTR_LATITUDE) + longitude = entry.get(ATTR_LONGITUDE) + radius = entry.get(ATTR_RADIUS, DEFAULT_RADIUS) + icon = entry.get(ATTR_ICON) - zone = Zone(hass, name, latitude, longitude, radius, icon) - zone.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, entities) - zone.update_ha_state() - entities.add(zone.entity_id) + 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.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, + entities) + zone.update_ha_state() + entities.add(zone.entity_id) if ENTITY_ID_HOME not in entities: zone = Zone(hass, hass.config.location_name, hass.config.latitude, diff --git a/homeassistant/const.py b/homeassistant/const.py index 28aa488a9f3..c256aa921d1 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -105,6 +105,9 @@ ATTR_HIDDEN = "hidden" ATTR_LATITUDE = "latitude" ATTR_LONGITUDE = "longitude" +# Accuracy of location in meters +ATTR_GPS_ACCURACY = 'gps_accuracy' + # #### SERVICES #### SERVICE_HOMEASSISTANT_STOP = "stop" diff --git a/tests/components/automation/test_zone.py b/tests/components/automation/test_zone.py index 47ffa76e3be..46a933ebe99 100644 --- a/tests/components/automation/test_zone.py +++ b/tests/components/automation/test_zone.py @@ -17,7 +17,8 @@ class TestAutomationEvent(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() zone.setup(self.hass, { - 'zone test': { + 'zone': { + 'name': 'test', 'latitude': 32.880837, 'longitude': -117.237561, 'radius': 250,