diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index b98c3a1636c..a1818e60901 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -1,6 +1,6 @@ """ homeassistant.components.device_tracker.owntracks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OwnTracks platform for the device tracker. For more details about this platform, please refer to the documentation at @@ -10,14 +10,16 @@ import json import logging import homeassistant.components.mqtt as mqtt +from homeassistant.const import (STATE_HOME, STATE_NOT_HOME) DEPENDENCIES = ['mqtt'] +CONF_TRANSITION_EVENTS = 'use_events' LOCATION_TOPIC = 'owntracks/+/+' - +EVENT_TOPIC = 'owntracks/+/+/event' def setup_scanner(hass, config, see): - """ Set up a OwnTracksks tracker. """ + """ Set up an OwnTracks tracker. """ def owntracks_location_update(topic, payload, qos): """ MQTT message received. """ @@ -47,7 +49,58 @@ def setup_scanner(hass, config, see): kwargs['battery'] = data['batt'] see(**kwargs) + + + def owntracks_event_update(topic, payload, qos): + """ MQTT event (geofences) received. """ - mqtt.subscribe(hass, LOCATION_TOPIC, owntracks_location_update, 1) + # Docs on available data: + # http://owntracks.org/booklet/tech/json/#_typetransition + try: + data = json.loads(payload) + except ValueError: + # If invalid JSON + logging.getLogger(__name__).error( + 'Unable to parse payload as JSON: %s', payload) + return + + if not isinstance(data, dict) or data.get('_type') != 'transition': + return + + + # check if in "home" fence or other zone + location = '' + if data['event'] == 'enter': + + if data['desc'] == 'home': + location = STATE_HOME + else: + location = data['desc'] + + elif data['event'] == 'leave': + location = STATE_NOT_HOME + else: + logging.getLogger(__name__).error('Misformatted mqtt msgs, _type=transition, event=%s', data['event']) + return + + parts = topic.split('/') + kwargs = { + 'dev_id': '{}_{}'.format(parts[1], parts[2]), + 'host_name': parts[1], + 'gps': (data['lat'], data['lon']), + 'location_name': location, + } + if 'acc' in data: + kwargs['gps_accuracy'] = data['acc'] + + see(**kwargs) + + + use_events = config.get(CONF_TRANSITION_EVENTS) + + if use_events: + mqtt.subscribe(hass, EVENT_TOPIC, owntracks_event_update, 1) + else: + mqtt.subscribe(hass, LOCATION_TOPIC, owntracks_location_update, 1) return True