From 5804dde0e979fe097e10c95fe785e69195902007 Mon Sep 17 00:00:00 2001 From: xifle Date: Sat, 2 Jan 2016 18:26:59 +0100 Subject: [PATCH 1/3] Enables the use of owntracks transition events By using the configuration option "use_events:yes" in the device_tracker section, only 'enter'/'leave' events are considered to calculate the state of a tracker device. The home zone is defined as the owntracks region 'home'. Other regions may also be defined, the name of the region is then used as state for the device. All owntracks regions, the 'Share' setting must be enabled in the app. --- .../components/device_tracker/owntracks.py | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) 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 From 82904c59ce4abaa7b47048f551611c8ceab067f9 Mon Sep 17 00:00:00 2001 From: xifle Date: Sun, 3 Jan 2016 17:12:11 +0100 Subject: [PATCH 2/3] Fixed code style --- .../components/device_tracker/owntracks.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index a1818e60901..c20b50e7e8c 100644 --- a/homeassistant/components/device_tracker/owntracks.py +++ b/homeassistant/components/device_tracker/owntracks.py @@ -49,8 +49,8 @@ def setup_scanner(hass, config, see): kwargs['battery'] = data['batt'] see(**kwargs) - - + + def owntracks_event_update(topic, payload, qos): """ MQTT event (geofences) received. """ @@ -67,20 +67,21 @@ def setup_scanner(hass, config, see): 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']) + logging.getLogger(__name__).error('Misformatted mqtt msgs, _type=transition, event=%s', + data['event']) return parts = topic.split('/') @@ -94,10 +95,10 @@ def setup_scanner(hass, config, see): 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: From d244d3b59958da19697548987574d411cd992acb Mon Sep 17 00:00:00 2001 From: xifle Date: Sun, 3 Jan 2016 17:42:49 +0100 Subject: [PATCH 3/3] Fixed flake8 style errors --- homeassistant/components/device_tracker/owntracks.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/device_tracker/owntracks.py b/homeassistant/components/device_tracker/owntracks.py index c20b50e7e8c..e81952eb770 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 @@ -18,6 +18,7 @@ CONF_TRANSITION_EVENTS = 'use_events' LOCATION_TOPIC = 'owntracks/+/+' EVENT_TOPIC = 'owntracks/+/+/event' + def setup_scanner(hass, config, see): """ Set up an OwnTracks tracker. """ @@ -50,7 +51,6 @@ def setup_scanner(hass, config, see): see(**kwargs) - def owntracks_event_update(topic, payload, qos): """ MQTT event (geofences) received. """ @@ -67,7 +67,6 @@ def setup_scanner(hass, config, see): if not isinstance(data, dict) or data.get('_type') != 'transition': return - # check if in "home" fence or other zone location = '' if data['event'] == 'enter': @@ -80,8 +79,9 @@ def setup_scanner(hass, config, see): elif data['event'] == 'leave': location = STATE_NOT_HOME else: - logging.getLogger(__name__).error('Misformatted mqtt msgs, _type=transition, event=%s', - data['event']) + logging.getLogger(__name__).error( + 'Misformatted mqtt msgs, _type=transition, event=%s', + data['event']) return parts = topic.split('/') @@ -96,7 +96,6 @@ def setup_scanner(hass, config, see): see(**kwargs) - use_events = config.get(CONF_TRANSITION_EVENTS) if use_events: