X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/c4941ce1589611e1bdeb9416ae692c4ea064f2ce..6e5f222a876474d1f7303751ae2a8bd8638bc083:/zavai/gps.py diff --git a/zavai/gps.py b/zavai/gps.py index 3c7c8cd..49a3a26 100755 --- a/zavai/gps.py +++ b/zavai/gps.py @@ -17,13 +17,10 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #import sys -#import os +import os import os.path import time -#import signal -#import optparse import dbus -#import gobject import zavai class GPSMonitor(): @@ -67,9 +64,11 @@ class GPSMonitor(): self.debug_update() def on_satellites_changed(self, satellites): - self.gps_debug.request() + zavai.info("gps monitor: satellites changed") + self.debug_request() def on_ubxdebug_packet(self, clid, length, data): + zavai.info("gps monitor: UBX debug packet") for c in self.callbacks: c(clid, length, data) @@ -107,6 +106,55 @@ class GPSMonitor(): if not self.callbacks: self._stop_listening() +class GPSPosition(): + def __init__(self, gps): + self.gps = gps + self.callbacks = set() + + def on_position_changed(self, fields, tstamp, lat, lon, alt): + zavai.info("gps position: position changed") + for c in self.callbacks: + c(fields, tstamp, lat, lon, alt) + + def _start_listening(self): + self.gps.request(self) + + self.bus.add_signal_receiver( + self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position', + 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') + + # TODO: find out how come sometimes these events are not sent + self.gps.bus.add_signal_receiver( + self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite', + 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') + self.gps.bus.add_signal_receiver( + self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX', + 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') + self.debug_request() + + def _stop_listening(self): + self.gps.bus.remove_signal_receiver( + self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite', + 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') + self.gps.bus.remove_signal_receiver( + self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX', + 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') + self.gps.release(self) + + def connect(self, callback): + "Send position changed messages to the given callback" + do_start = not self.callbacks + self.callbacks.add(callback) + if do_start: + self._start_listening() + + def disconnect(self, callback): + "Stop sending position changed messages to the given callback" + if not self.callbacks: return + self.callbacks.discard(callback) + if not self.callbacks: + self._stop_listening() + # For a list of dbus services, look in /etc/dbus-1/system.d/ class GPS(zavai.Resource): @@ -125,6 +173,7 @@ class GPS(zavai.Resource): self.gps_ubx = dbus.Interface(gps, 'org.freesmartphone.GPS.UBX') self.monitor = GPSMonitor(self) + self.position = GPSPosition(self) self.requestors = set() @@ -177,23 +226,78 @@ class GPS(zavai.Resource): # self.waiting_for_fix() # self.waiting_for_fix = None # -# def track_position(self, callback): -# self.bus.add_signal_receiver( -# callback, 'PositionChanged', 'org.freedesktop.Gypsy.Position', -# 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy') +# def start_recording(self): +# if self.gps_monitor: +# self.gps_monitor.stop() +# self.gps_monitor = None +# +# if not self.audio: +# return +# +# # Sync system time +# gpstime = self.gps.gps_time.GetTime() +# subprocess.call(["date", "-s", "@%d" % gpstime]) +# subprocess.call(["hwclock", "--systohc"]) +# +# # Compute basename for output files +# self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(gpstime)) +# self.basename = os.path.join(AUDIODIR, self.basename) +# +# # Start recording the GPX track +# self.gpx = GPX(self.basename) +# self.gps.track_position(self.on_position_changed) +# +# # Start recording in background forking arecord +# self.audio.set_basename(self.basename) +# self.audio.start_recording() +# class GPX(zavai.Resource): "Write GPX track and waypoint files" - def __init__(self, resource, name): - self.resource = resource + def __init__(self, registry, name): + self.registry = registry self.trk = None self.wpt = None + self.last_pos = None + self.requestors = set() + conf = registry.resource("conf") + self.trackdir = os.path.expanduser("~/.zavai") + if conf.has_section("gps"): + if conf.has_option("gps", "trackdir"): + self.trackdir = conf.get("gps", "trackdir") + if not os.path.isdir(self.trackdir): + zavai.info("Creating directory", self.trackdir) + os.makedirs(self.trackdir) + + def request(self, tag): + "Request the GPX trace to be taken" + do_start = not self.requestors + self.requestors.add(tag) + if do_start: + zavai.info("Starting GPX trace subsystem") + gps = self.registry.resource("gps") + gps.position.connect(self.on_position_changed) + + def release(self, tag): + "Release a GPX trace request" + if not self.requestors: return + self.requestors.discard(tag) + if not self.requestors: + zavai.info("Stopping GPX trace subsystem") + gps = self.registry.resource("gps") + gps.position.disconnect(self.on_position_changed) + self.stop() + + def on_position_changed(self, fields, tstamp, lat, lon, alt): + self.last_pos = (fields, tstamp, lat, lon, alt) + self.trackpoint() def start(basename = None, tstamp = None): if basename is None: - # compute it from GPS - pass + # Compute basename for output files + basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(tstamp)) + basename = os.path.join(self.trackdir, self.basename) self.trk = open(basename + "-trk.gpx", "wt") print >>self.trk, """ @@ -226,35 +330,50 @@ class GPX(zavai.Resource): print >>self.wpt, "" self.wpt.close() self.wpt = None + self.last_pos = None def shutdown(self): self.stop() - def waypoint(self, tstamp, lat, lon, ele = None, name = None): + def trackpoint(self): + "Mark a track point" + if self.last_pos is None: + return + + fields, tstamp, lat, lon, ele = self.last_pos + + if not self.trk: + self.start(tstamp) + + print >>self.trk, """ + + %f""" % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele) + #if course is not None: print >>self.trk, " %f" % course + #if speed is not None: print >>self.trk, " %f" % speed + #if fix is not None: print >>self.trk, " %f" % fix + #if hdop is not None: print >>self.trk, " %f" % hdop + print >>self.trk, "" + + def waypoint(self, name = None): "Mark a waypoint" + if self.last_pos is None: + return + + fields, tstamp, lat, lon, ele = self.last_pos + + if not self.wpt: + self.start(tstamp) + if name is None: name = "wpt_%d" % self.wpt_seq self.wpt_seq += 1 print >>self.wpt, """ %s - """ % ( - lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp))) - if ele is not None: - print >>self.wpt, " %f""" % ele - print >>self.wpt, "" - - def trackpoint(self, tstamp, lat, lon, ele = None, course = None, speed = None, fix = None, hdop = None): - print >>self.trk, """ - """ % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp))) - if ele is not None: print >>self.trk, " %f" % ele - if course is not None: print >>self.trk, " %f" % course - if speed is not None: print >>self.trk, " %f" % speed - if fix is not None: print >>self.trk, " %f" % fix - if hdop is not None: print >>self.trk, " %f" % hdop - print >>self.trk, "" - - + + %f +""" % ( + lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele) # def record(self): @@ -271,35 +390,6 @@ class GPX(zavai.Resource): # self.gps_monitor = GPSMonitor(self.gps) # self.gps_monitor.start() # -# def start_recording(self): -# if self.gps_monitor: -# self.gps_monitor.stop() -# self.gps_monitor = None -# -# if not self.audio: -# return -# -# # Sync system time -# gpstime = self.gps.gps_time.GetTime() -# subprocess.call(["date", "-s", "@%d" % gpstime]) -# subprocess.call(["hwclock", "--systohc"]) -# -# # Compute basename for output files -# self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(gpstime)) -# self.basename = os.path.join(AUDIODIR, self.basename) -# -# # Start recording the GPX track -# self.gpx = GPX(self.basename) -# self.gps.track_position(self.on_position_changed) -# -# # Start recording in background forking arecord -# self.audio.set_basename(self.basename) -# self.audio.start_recording() -# -# def on_position_changed(self, fields, tstamp, lat, lon, alt): -# self.last_pos = (fields, tstamp, lat, lon, alt) -# if self.gpx: -# self.gpx.trackpoint(tstamp, lat, lon, alt) # # def make_waypoint(self): # if self.gpx is None: