One method to get GPS data from a mobile device into a Tulip app

One method to get GPS data from a mobile device into a Tulip app.

From One method to get GPS data from a mobile device into a Tulip app. – Michael Ellerbeck

It’s not a great method, but it might prove useful.

TLDR

There is a useful opensource application called OwnTracks.

OwnTracks is an Open Source project which provides iOS and Android apps with which devices publish their current location to a server of your choice. While there are many smartphone apps available which can do that, OwnTracks is special in as much as you decide what happens to your data. To all of it.

Own tracks has an installable backend, but what is the fun of that. With some elbow grease you can configure an API gateway to receive the http post from the app and process it. It is also possible to use mqtt (its more of what owntracks was designed for) and talk to Iot Core from owntracks. You do need install the amazon CA’s and some tomfoolery which was difficult on an MDM’d phone. Mqtt - OwnTracks Booklet

So create a simple HTTP API with a post method. Owntrack uses basic authentication Security - OwnTracks Booklet so need to configure the API gateway to support that with an authorizer.

Once you have the API setup, setup the integration to call the lambda.

The lambda will basically parse out the lat long and insert it into a tulip table

So create yourself a tulip table.

Capture the url of the table so you can use the id

You need to use the id to lookup the behind the scene field names

Create yourself an API user, fire yourself up some postman.

You can hit your endpoint to get the table definitions (How to Use the Table API ) put in your basic auth.

https://developer-michael-ellerbeck.tulip.co/api/v3/tables

You want to look for the user friendly name, and then capture the unique field id for example nctgo_lat_string

So a quick lambda using this, BASE64 encode the creds (that’s the long string out of the Tulip API)

import json
import logging
import urllib3
from urllib3.util.retry import Retry
from urllib3.exceptions import HTTPError

# Configure logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    # Log the incoming event
    logger.info("Received event: %s", json.dumps(event))
    
    # Parse the body data and log it
    body_data = {}
    recordid = None
    if 'body' in event:
        body_data = json.loads(event['body'])
        logger.info("Parsed body data: %s", body_data)
    
    # Extract the x-limit-u header
    if 'headers' in event:
        recordid = event['headers'].get('x-limit-u')
        logger.info("Extracted recordid from headers: %s", recordid)
    
    # Access individual components
    lon = body_data.get('lon')
    lat = body_data.get('lat')
    
    lon_string = str(body_data.get('lon'))
    lat_string = str(body_data.get('lat'))

    
    # Update the Tulip table with the lon and lat values if recordid is found
    if lon is not None and lat is not None and recordid is not None:
        url = f"https://developer-michael-ellerbeck.tulip.co/api/v3/tables/---/records/{recordid}"
        headers = {
            "accept": "application/json",
            "Authorization": "Basic",
            "Content-Type": "application/json"
        }
        data = json.dumps({"zvdmz_lon": lon, "yeweg_lat": lat, "nctgo_lat_string": lat_string, "orcrz_lon_string": lon_string })

        # Create a PoolManager instance
        http = urllib3.PoolManager(
            retries=Retry(3, redirect=2)
        )

        try:
            response = http.request(
                'PUT',
                url,
                body=data,
                headers=headers
            )
            
            # Log the response from the Tulip API
            logger.info("Tulip API response: %s", response.data.decode('utf-8'))

        except HTTPError as e:
            logger.error("HTTP error occurred: %s", e)
        except Exception as e:
            logger.error("An error occurred: %s", e)
    
    return {
        'statusCode': 200,
        'body': 'Hello from Lambda!'
    }

So that will get the data into a Tulip Table, so how do we configure the iphone to send to it.

The easiest way is to install owntracks, configure it manually (by pressing the I, and then press settings.) Once you get the settings how you like, press the export button.

{
  "username" : "Test",
  "maxHistory" : 0,
  "positions" : 50,
  "ranging" : false,
  "locked" : false,
  "deviceId" : "",
  "monitoring" : 2,
  "tid" : "",
  "cmd" : true,
  "_type" : "configuration",
  "allowRemoteLocation" : false,
  "pubTopicBase" : "",
  "encryptionKey" : "",
  "url" : "https:\/\/ execute-api.us-east-1.amazonaws.com\/owntracks\/",
  "ignoreStaleLocations" : 0,
  "osmCopyright" : "",
  "waypoints" : [

  ],
  "usePassword" : true,
  "httpHeaders" : "hello",
  "auth" : true,
  "locatorInterval" : 30,
  "extendedData" : true,
  "osmTemplate" : "",
  "ignoreInaccurateLocations" : 100,
  "locatorDisplacement" : 2,
  "mode" : 3,
  "password" : "admin",
  "downgrade" : 0
}

Sample config (this one is very aggressive timing wise)

Now it gets a bit esoteric. Save off the .otrc file and then use gitbash to Base64 encode it

echo “owntracks:///config?inline=$(openssl enc -a -A -in config.otrc)”

It will make a big long text string

That you then convert to a QR code

If you scan this on your mobile device it will setup own tracks with the config in the .otrc file.

Then you can make a quick app to write the GPS where you are at.

Then you can make a quick Grafana to map those points out.

6 Likes

Woah this is awesome! Thanks for sharing your creative solution here to get GPS info into your Tulip apps.

Curious - what is the primary way you are using this GPS information for your Tulip use-cases?

Love this @mellerbeck

This makes me want to try to recreate some Garmin app functionality, and start keeping logs of locations of interest, backwoods camping spots, and other things in Tulip. Move from “frontline” to “backwoods operations”. So many fun possibilities with this one…

3 Likes