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"