diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index 3d95e0e0268..caf0f38ad7f 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -23,23 +23,28 @@ BEACON_DEV_ID = 'beacon' LOCATION_TOPIC = 'owntracks/+/+' EVENT_TOPIC = 'owntracks/+/+/event' -WAYPOINT_TOPIC = 'owntracks/{}/+/waypoint' +WAYPOINT_TOPIC = 'owntracks/{}/{}/waypoint' _LOGGER = logging.getLogger(__name__) LOCK = threading.Lock() CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' -CONF_WAYPOINT_IMPORT_USER = 'waypoint_import_user' +CONF_WAYPOINT_IMPORT = 'waypoints' +CONF_WAYPOINT_WHITELIST = 'waypoint_whitelist' VALIDATE_LOCATION = 'location' VALIDATE_TRANSITION = 'transition' +WAYPOINT_LAT_KEY = 'lat' +WAYPOINT_LON_KEY = 'lon' + def setup_scanner(hass, config, see): """Setup an OwnTracks tracker.""" max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY) - waypoint_import_user = config.get(CONF_WAYPOINT_IMPORT_USER) + waypoint_import = config.get(CONF_WAYPOINT_IMPORT, True) + waypoint_whitelist = config.get(CONF_WAYPOINT_WHITELIST) def validate_payload(payload, data_type): """Validate OwnTracks payload.""" @@ -198,10 +203,12 @@ def setup_scanner(hass, config, see): _LOGGER.info("Got %d waypoints from %s", len(wayps), topic) for wayp in wayps: name = wayp['desc'] - lat = wayp['lat'] - lon = wayp['lon'] + lat = wayp[WAYPOINT_LAT_KEY] + lon = wayp[WAYPOINT_LON_KEY] rad = wayp['rad'] - zone_comp.add_zone(hass, name, lat, lon, rad) + zone = zone_comp.Zone(hass, name, lat, lon, rad, + zone_comp.ICON_IMPORT, False, True) + zone_comp.add_zone(hass, name, zone) def see_beacons(dev_id, kwargs_param): """Set active beacons to the current location.""" @@ -216,9 +223,15 @@ def setup_scanner(hass, config, see): mqtt.subscribe(hass, LOCATION_TOPIC, owntracks_location_update, 1) mqtt.subscribe(hass, EVENT_TOPIC, owntracks_event_update, 1) - if waypoint_import_user is not None: - mqtt.subscribe(hass, WAYPOINT_TOPIC.format(waypoint_import_user), - owntracks_waypoint_update, 1) + if waypoint_import: + if waypoint_whitelist is None: + mqtt.subscribe(hass, WAYPOINT_TOPIC.format('+', '+'), + owntracks_waypoint_update, 1) + else: + for whitelist_user in waypoint_whitelist: + mqtt.subscribe(hass, WAYPOINT_TOPIC.format(whitelist_user, + '+'), + owntracks_waypoint_update, 1) return True @@ -231,7 +244,7 @@ def _parse_see_args(topic, data): kwargs = { 'dev_id': dev_id, 'host_name': host_name, - 'gps': (data['lat'], data['lon']) + 'gps': (data[WAYPOINT_LAT_KEY], data[WAYPOINT_LON_KEY]) } if 'acc' in data: kwargs['gps_accuracy'] = data['acc'] diff --git a/homeassistant/components/zone.py b/homeassistant/components/zone.py index d097b0b76ef..a9ad05434cd 100644 --- a/homeassistant/components/zone.py +++ b/homeassistant/components/zone.py @@ -92,17 +92,16 @@ def setup(hass, config): 'Each zone needs a latitude and longitude.') continue - zone = Zone(hass, name, latitude, longitude, radius, icon, - passive, False) - zone.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, - entities) - zone.update_ha_state() + zone = Zone(hass, name, latitude, longitude, radius, + icon, passive, False) + add_zone(hass, name, zone, entities) entities.add(zone.entity_id) if ENTITY_ID_HOME not in entities: - zone = Zone(hass, hass.config.location_name, hass.config.latitude, - hass.config.longitude, DEFAULT_RADIUS, ICON_HOME, - False, False) + zone = Zone(hass, hass.config.location_name, + hass.config.latitude, hass.config.longitude, + DEFAULT_RADIUS, ICON_HOME, False, False) + add_zone(hass, hass.config.location_name, zone, entities) zone.entity_id = ENTITY_ID_HOME zone.update_ha_state() @@ -110,20 +109,24 @@ def setup(hass, config): # Add a zone to the existing set -def add_zone(hass, name, latitude, longitude, radius): +def add_zone(hass, name, zone, entities=None): """Add a zone from other components.""" _LOGGER.info("Adding new zone %s", name) - entities = set() + if entities is None: + _entities = set() + else: + _entities = entities - if hass.states.get('zone.' + name) is None: - zone = Zone(hass, name, latitude, longitude, radius, ICON_IMPORT, - False, True) + zone_exists = hass.states.get('zone.' + str(name)) + if zone_exists is None: zone.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, - entities) + _entities) zone.update_ha_state() - entities.add(zone.entity_id) + _entities.add(zone.entity_id) + return zone else: _LOGGER.info("Zone already exists") + return zone_exists class Zone(Entity): diff --git a/tests/components/device_tracker/test_owntracks.py b/tests/components/device_tracker/test_owntracks.py index 4abad8b6ca1..9a2e1e6d643 100644 --- a/tests/components/device_tracker/test_owntracks.py +++ b/tests/components/device_tracker/test_owntracks.py @@ -17,7 +17,10 @@ DEVICE = 'phone' LOCATION_TOPIC = "owntracks/{}/{}".format(USER, DEVICE) EVENT_TOPIC = "owntracks/{}/{}/event".format(USER, DEVICE) -WAYPOINT_TOPIC = 'owntracks/{}/{}/waypoint'.format(USER, DEVICE) +WAYPOINT_TOPIC = owntracks.WAYPOINT_TOPIC.format(USER, DEVICE) +USER_BLACKLIST = 'ram' +WAYPOINT_TOPIC_BLOCKED = owntracks.WAYPOINT_TOPIC.format(USER_BLACKLIST, + DEVICE) DEVICE_TRACKER_STATE = "device_tracker.{}_{}".format(USER, DEVICE) @@ -25,7 +28,8 @@ IBEACON_DEVICE = 'keys' REGION_TRACKER_STATE = "device_tracker.beacon_{}".format(IBEACON_DEVICE) CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy' -CONF_WAYPOINT_IMPORT_USER = 'waypoint_import_user' +CONF_WAYPOINT_IMPORT = owntracks.CONF_WAYPOINT_IMPORT +CONF_WAYPOINT_WHITELIST = owntracks.CONF_WAYPOINT_WHITELIST LOCATION_MESSAGE = { 'batt': 92, @@ -168,7 +172,8 @@ class TestDeviceTrackerOwnTracks(unittest.TestCase): device_tracker.DOMAIN: { CONF_PLATFORM: 'owntracks', CONF_MAX_GPS_ACCURACY: 200, - CONF_WAYPOINT_IMPORT_USER: USER + CONF_WAYPOINT_IMPORT: True, + CONF_WAYPOINT_WHITELIST: ['jon', 'greg'] }})) self.hass.states.set( @@ -565,3 +570,13 @@ class TestDeviceTrackerOwnTracks(unittest.TestCase): self.assertTrue(wayp is not None) wayp = self.hass.states.get('zone.exp_wayp2') self.assertTrue(wayp is not None) + + def test_waypoint_import_blacklist(self): + """Test import of list of waypoints for blacklisted user.""" + waypoints_message = WAYPOINTS_EXPORTED_MESSAGE.copy() + self.send_message(WAYPOINT_TOPIC_BLOCKED, waypoints_message) + # Check if it made it into states + wayp = self.hass.states.get('zone.exp_wayp1') + self.assertTrue(wayp is None) + wayp = self.hass.states.get('zone.exp_wayp2') + self.assertTrue(wayp is None)