rpirena/strato4/strato4gpx.py

105 lines
4.1 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/python3
# encoding: UTF-8
import fileinput, math, sys, time, datetime
import numpy
out = sys.stdout
"""
# Wanna drop some funky stats & graphs? Go to 'www.stratoflights.com/auswertung'
LOGGER_INFO_BEGIN
{info:{board_id:4,id_str:'STRATO4 Version 1.3',serial:'1029',hw_platform:{name:'stratologx-stm32l0',mcu:'ST STM32L072RZT6',v_ma:'1',v_mi:'3'},sw_version:{v_ma:'2',v_mi:'1',v_pa:'2',v_info:'STD',bt_t:'12:40:49'
,bt_d:'Mar 18 2023'}}}
LOGGER_INFO_END
CSV_DATA_SECTION_BEGIN
Uptime [s];GNSS: PPS Timestamp [s];GNSS: UTC date time (ISO 8601);GNSS: Fix type (0=no fix, others=fix);GNSS: Latitude [degrees];GNSS: Longitude [degrees];GNSS: Positional dilution of precision;GNSS: Altitude
[m] (above Mean Sea Level);GNSS: Ground speed [km/h];GNSS: Satellites in view;GNSS: Altitude [m] (above ellipsoid);Temperature: Board [degC];Volt: Supply Voltage [V];Volt: 3.3V board voltage [V];Volt: 5V board
voltage [V];Volt: Vin1 voltage [V];Volt: Vin2 voltage [V];Volt: Vin3 voltage [V];IO: In 1 State;IO: In 1 Timestamp [s];IO: In 2 State;IO: In 2 Timestamp [s];IO: Out 1 State;IO: Out 1 Timestamp [s];IO: Out 2 S
tate;IO: Out 2 Timestamp [s]
6.105;0.000;2015-10-18T00:00:05.0Z;0;Inval.;Inval.;Inval.;Inval.;Inval.;0;Inval.;28.8;9.46;3.28;5.05;0.179;0.179;0.375;1;0.000;1;0.000;0;0.002;0;0.002
"""
class datalog(dict):
header = "Uptime [s];GNSS: PPS Timestamp [s];GNSS: UTC date time (ISO 8601);GNSS: Fix type (0=no fix, others=fix);GNSS: Latitude [degrees];GNSS: Longitude [degrees];GNSS: Positional dilution of precision;GNSS: Altitude [m] (above Mean Sea Level);GNSS: Ground speed [km/h];GNSS: Satellites in view;GNSS: Altitude [m] (above ellipsoid);Temperature: Board [degC];Volt: Supply Voltage [V];Volt: 3.3V board voltage [V];Volt: 5V board voltage [V];Volt: Vin1 voltage [V];Volt: Vin2 voltage [V];Volt: Vin3 voltage [V];IO: In 1 State;IO: In 1 Timestamp [s];IO: In 2 State;IO: In 2 Timestamp [s];IO: Out 1 State;IO: Out 1 Timestamp [s];IO: Out 2 State;IO: Out 2 Timestamp [s]"
def __init__(self, l, header=None):
if header is not None:
self.header = header
self.fields = [f.split('[')[0].split('(')[0].strip() for f in self.header.split(';')]
l=l.strip()
self.ff = l.split(';')
if len(self.ff) != len(self.fields):
print("%d data, %d fields" % (len(self.ff), len(self.fields)), file=sys.stderr)
for i,f in enumerate(self.fields):
self[f] = self.ff[i]
def gps_ccord(self, i):
if self["GNSS: Fix type"]=='0':
return None
return float(self[i])
def longitude(self):
return self.gps_ccord('GNSS: Longitude')
def latitude(self):
return self.gps_ccord('GNSS: Latitude')
def time(self, i='UTC date time'):
return datetime.datetime.fromisoformat(self[i]).timestamp()
def iso_time(self):
return self['GNSS: UTC date time']
def elevation(self, i='GNSS: Altitude'):
return float(self[i])
h = None
do_gpx = True
for l in fileinput.input():
if l.strip()=='CSV_DATA_SECTION_BEGIN':
if do_gpx:
out.write("""<?xml version="1.0" encoding="UTF-8" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1"
creator="stratosflights2gpx.py"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd ">
<trk>
<name><![CDATA[%s]]></name>
<trkseg>
""" % "STRATO4")
do_gpx = False
continue
if do_gpx:
continue
if l[:6]=='Uptime':
h = l
continue
if not l[0].isdigit():
continue
try:
c = datalog(l, h)
except Exception as e:
sys.stderr.write(l+"\n"+str(e))
raise
lon = c.longitude()
lat = c.latitude()
if lon and lat:
out.write(' <trkpt lat="%.7f" lon="%.7f">\n' % (lat, lon))
e = c.elevation()
if e:
out.write(" <ele>%s</ele>\n" % e)
t = c.iso_time()
if t:
out.write(" <time>%s</time>\n" % t)
out.write(' </trkpt>\n')
out.write(""" </trkseg>
</trk>
</gpx>
""")