Mercurial > lbo > hg > geohub
changeset 129:14f3d37cd8e0
Add gpsd collection script
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 05 May 2021 19:38:32 +0200 |
parents | 0fff2024f54a |
children | f45e9d1ad13c |
files | examples/gpsd/gpsd.py |
diffstat | 1 files changed, 83 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gpsd/gpsd.py Wed May 05 19:38:32 2021 +0200 @@ -0,0 +1,83 @@ +#!/usr/bin/env python + +# Collect speed data from a driving ICE/IC train. + +import requests + +from gps3 import gps3 as gps + +import argparse +import json +import sys +import time + +def eprint(*args): + print(*args, file=sys.stderr) + +def send_point(sess, args, info: dict[str, str]): + geohub_templ = args.geohub + '/{CLIENT}/log?secret={SECRET}' + geohub_url = geohub_templ.format(HOST=args.geohub_host, CLIENT=args.client or info.get('tzn', 'TRAIN'), SECRET=args.secret, PROTOCOL=args.geohub_scheme) + additional = '&lat={lat}&longitude={long}&s={spd}&time={ts}'.format( + lat=info['lat'], long=info['lon'], spd=info['speed'], ts=info['time']) + # Delete unnecessary data. + url = geohub_url + additional + return sess.post(url, data="") + +def fetch_data(datastream, data, seen=set()): + if data is None: + return None + datastream.unpack(data) + if datastream.TPV['time'] in seen: + return None + seen.add(datastream.TPV['time']) + return datastream.TPV + +def parse_args(): + parser = argparse.ArgumentParser(description='Fetch and send gpsd data') + parser.add_argument('--client', default='gpsd', help='Client name.') + parser.add_argument('--secret', default='', help='Secret. This protects your current location; to share it, you have to share the secret. By default, the points will be made public on your GeoHub instance.') + parser.add_argument('--interval', default=5, type=int, help='Poll interval. If 0, send every point received from gpsd.') + parser.add_argument('--outfile', default='data.jsonlines', help='Where to write the JSON data received from the train.') + parser.add_argument('--geohub_host', default='example.com', help='Host of your GeoHub. Use this if the URL --geohub works for you.') + parser.add_argument('--geohub_scheme', default='https', help='Protocol scheme of the GeoHub instance. Use this if you do not want to specify the entire --geohub URL') + parser.add_argument('--geohub', default='{PROTOCOL}://{HOST}/geo/', help='Base URL of Geohub instance. E.g., https://example.com/geo. Use --geohub_host, --geohub_scheme if your URL looks like the example.') + return parser.parse_args() + +def run(args): + session = requests.Session() + socket = gps.GPSDSocket() + datastream = gps.DataStream() + socket.connect() + socket.watch() + + geohub_base = args.geohub.format(PROTOCOL=args.geohub_scheme, HOST=args.geohub_host) + livemap_url = geohub_base + 'assets/livemap.html?client={client}&secret={secret}'.format(client=args.client, secret=args.secret) + eprint('Go to LiveMap:', livemap_url); + + seen = set() + last_time = time.time() + + with open(args.outfile, 'w') as outfile: + while True: + data = socket.next(timeout=5) + if data: + info = fetch_data(datastream, data, seen=seen) + if time.time() - last_time < args.interval: + continue + elif info is not None: + last_time = time.time() + eprint('{} :: Sending point ({}, {}) to GeoHub.'.format(info['time'], info['lon'], info['lat'])) + send_point(session, args, info) + outfile.write(json.dumps(info)) + outfile.write('\n') + # Prevent memory leak. + if len(seen) > 100: + seen = set() + +def main(): + args = parse_args() + run(args) + + +if __name__ == '__main__': + main()