From 6a969208e9e1f727dd047d059ac6d05a5d2e2c0b Mon Sep 17 00:00:00 2001 From: Hans Bakker Date: Mon, 12 Oct 2015 00:14:05 +0200 Subject: [PATCH 1/3] Initial commit for Geofancy device tracker. --- .../components/device_tracker/geofancy.py | 74 +++++++++++++++++++ homeassistant/const.py | 2 + 2 files changed, 76 insertions(+) create mode 100644 homeassistant/components/device_tracker/geofancy.py diff --git a/homeassistant/components/device_tracker/geofancy.py b/homeassistant/components/device_tracker/geofancy.py new file mode 100644 index 00000000000..b0834e4be36 --- /dev/null +++ b/homeassistant/components/device_tracker/geofancy.py @@ -0,0 +1,74 @@ +""" +homeassistant.components.device_tracker.geofancy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Geofancy platform for the device tracker. + +device_tracker: + platform: geofancy +""" + +from homeassistant.const import ( + URL_API_GEOFANCY_ENDPOINT, + HTTP_UNPROCESSABLE_ENTITY, HTTP_INTERNAL_SERVER_ERROR) + +DEPENDENCIES = ['http'] + +_SEE = 0 + + +def setup_scanner(hass, config, see): + """ Set up an endpoint for the Geofancy app. """ + + # Use a global variable to keep setup_scanner compact when using a callback + global _SEE + _SEE = see + + """ POST would be semantically better, but that currently does not work + since Geofancy sends the data as key1=value1&key2=value2 in the request body, + while Home Assistant expects json there. """ + + hass.http.register_path( + 'GET', URL_API_GEOFANCY_ENDPOINT, _handle_get_api_geofancy) + + return True + + +def _handle_get_api_geofancy(handler, path_match, data): + """ Geofancy message received. """ + + if not isinstance(data, dict): + handler.write_json_message( + "Error while parsing Geofancy message.", HTTP_INTERNAL_SERVER_ERROR) + return + if 'latitude' not in data or 'longitude' not in data: + handler.write_json_message( + "Location not specified.", HTTP_UNPROCESSABLE_ENTITY) + return + if 'device' not in data or 'id' not in data: + handler.write_json_message( + "Device id or location id not specified.", HTTP_UNPROCESSABLE_ENTITY) + return + + try: + gps_coords = (float(data['latitude']), float(data['longitude'])) + except ValueError: + # If invalid latitude / longitude format + handler.write_json_message( + "Invalid latitude / longitude format.", HTTP_UNPROCESSABLE_ENTITY) + return + + + # entity id's in Home Assistant must be alphanumerical + device_uuid = data['device'] + device_entity_id = device_uuid.replace('-', '') + + kwargs = { + 'dev_id': device_entity_id, + 'gps': gps_coords, + 'location_name': data['id'] + } + + _SEE(**kwargs) + + handler.write_json_message("Geofancy message processed") diff --git a/homeassistant/const.py b/homeassistant/const.py index 278ffea218a..ddda08001b9 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -145,6 +145,7 @@ URL_API_SERVICES_SERVICE = "/api/services/{}/{}" URL_API_EVENT_FORWARD = "/api/event_forwarding" URL_API_COMPONENTS = "/api/components" URL_API_BOOTSTRAP = "/api/bootstrap" +URL_API_GEOFANCY_ENDPOINT = '/api/geofancy' HTTP_OK = 200 HTTP_CREATED = 201 @@ -154,6 +155,7 @@ HTTP_UNAUTHORIZED = 401 HTTP_NOT_FOUND = 404 HTTP_METHOD_NOT_ALLOWED = 405 HTTP_UNPROCESSABLE_ENTITY = 422 +HTTP_INTERNAL_SERVER_ERROR = 500 HTTP_HEADER_HA_AUTH = "X-HA-access" HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding" From 1eb3610a11dcd5871c6e79ef24355f54d60e47cf Mon Sep 17 00:00:00 2001 From: Hans Bakker Date: Mon, 12 Oct 2015 00:28:39 +0200 Subject: [PATCH 2/3] Style fixes --- .../components/device_tracker/geofancy.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/device_tracker/geofancy.py b/homeassistant/components/device_tracker/geofancy.py index b0834e4be36..8e8611e00b3 100644 --- a/homeassistant/components/device_tracker/geofancy.py +++ b/homeassistant/components/device_tracker/geofancy.py @@ -24,9 +24,9 @@ def setup_scanner(hass, config, see): global _SEE _SEE = see - """ POST would be semantically better, but that currently does not work - since Geofancy sends the data as key1=value1&key2=value2 in the request body, - while Home Assistant expects json there. """ + # POST would be semantically better, but that currently does not work + # since Geofancy sends the data as key1=value1&key2=value2 + # in the request body, while Home Assistant expects json there. hass.http.register_path( 'GET', URL_API_GEOFANCY_ENDPOINT, _handle_get_api_geofancy) @@ -39,15 +39,18 @@ def _handle_get_api_geofancy(handler, path_match, data): if not isinstance(data, dict): handler.write_json_message( - "Error while parsing Geofancy message.", HTTP_INTERNAL_SERVER_ERROR) + "Error while parsing Geofancy message.", + HTTP_INTERNAL_SERVER_ERROR) return if 'latitude' not in data or 'longitude' not in data: handler.write_json_message( - "Location not specified.", HTTP_UNPROCESSABLE_ENTITY) + "Location not specified.", + HTTP_UNPROCESSABLE_ENTITY) return if 'device' not in data or 'id' not in data: handler.write_json_message( - "Device id or location id not specified.", HTTP_UNPROCESSABLE_ENTITY) + "Device id or location id not specified.", + HTTP_UNPROCESSABLE_ENTITY) return try: @@ -55,10 +58,10 @@ def _handle_get_api_geofancy(handler, path_match, data): except ValueError: # If invalid latitude / longitude format handler.write_json_message( - "Invalid latitude / longitude format.", HTTP_UNPROCESSABLE_ENTITY) + "Invalid latitude / longitude format.", + HTTP_UNPROCESSABLE_ENTITY) return - # entity id's in Home Assistant must be alphanumerical device_uuid = data['device'] device_entity_id = device_uuid.replace('-', '') From b74e70d4e08262417675a75d693d1866dac948d4 Mon Sep 17 00:00:00 2001 From: Hans Bakker Date: Mon, 12 Oct 2015 20:58:24 +0200 Subject: [PATCH 3/3] Fixes based on balloob's comments --- homeassistant/components/device_tracker/geofancy.py | 11 +++-------- homeassistant/const.py | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/device_tracker/geofancy.py b/homeassistant/components/device_tracker/geofancy.py index 8e8611e00b3..55ebf2e0d1b 100644 --- a/homeassistant/components/device_tracker/geofancy.py +++ b/homeassistant/components/device_tracker/geofancy.py @@ -9,13 +9,14 @@ device_tracker: """ from homeassistant.const import ( - URL_API_GEOFANCY_ENDPOINT, HTTP_UNPROCESSABLE_ENTITY, HTTP_INTERNAL_SERVER_ERROR) DEPENDENCIES = ['http'] _SEE = 0 +URL_API_GEOFANCY_ENDPOINT = "/api/geofancy" + def setup_scanner(hass, config, see): """ Set up an endpoint for the Geofancy app. """ @@ -66,12 +67,6 @@ def _handle_get_api_geofancy(handler, path_match, data): device_uuid = data['device'] device_entity_id = device_uuid.replace('-', '') - kwargs = { - 'dev_id': device_entity_id, - 'gps': gps_coords, - 'location_name': data['id'] - } - - _SEE(**kwargs) + _SEE(dev_id=device_entity_id, gps=gps_coords, location_name=data['id']) handler.write_json_message("Geofancy message processed") diff --git a/homeassistant/const.py b/homeassistant/const.py index ddda08001b9..d742b345384 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -145,7 +145,6 @@ URL_API_SERVICES_SERVICE = "/api/services/{}/{}" URL_API_EVENT_FORWARD = "/api/event_forwarding" URL_API_COMPONENTS = "/api/components" URL_API_BOOTSTRAP = "/api/bootstrap" -URL_API_GEOFANCY_ENDPOINT = '/api/geofancy' HTTP_OK = 200 HTTP_CREATED = 201