# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#import sys
-#import os
+import os
import os.path
-#import time
-#import struct
-#import signal
-#import optparse
-#import dbus
-#import dbus.mainloop.glib
-#import gobject
+import time
+import dbus
import zavai
-class GPSMonitor():
+class GPSMonitor(zavai.Service):
def __init__(self, gps):
+ super(GPSMonitor, self).__init__(["satellites"])
+
self.gps = gps
self.gps_ubx = gps.gps_ubx
self.debug_have = set()
self.debug_error = set()
- self.callbacks = set()
-
def debug_update(self):
if self.debug_busy is None:
pending = self.debug_want - self.debug_have - self.debug_error
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):
- for c in self.callbacks:
- c(clid, length, data)
+ zavai.info("gps monitor: UBX debug packet")
+ self.notify("satellites", clid, length, data)
- def _start_listening(self):
- self.gps.request(self)
+ def start(self):
+ self.gps.connect("gps", self)
# 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.debug_request()
- def _stop_listening(self):
+ def stop(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)
+ self.gps.disconnect("gps", self)
- def connect(self, callback):
- "Send UBX debug packets 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 UBX debug packets to the given callback"
- if not self.callbacks: return
- self.callbacks.discard(callback)
- if not self.callbacks:
- self._stop_listening()
+class GPSPosition(zavai.Service):
+ def __init__(self, gps):
+ super(GPSPosition, self).__init__(["position"])
+ self.gps = gps
+ def on_position_changed(self, fields, tstamp, lat, lon, alt):
+ zavai.info("gps position: position changed")
+ self.notify("position", fields, tstamp, lat, lon, alt)
+
+ def start(self):
+ self.gps.connect("gps", self)
+ self.gps.bus.add_signal_receiver(
+ self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+
+ def stop(self):
+ self.gps.bus.remove_signal_receiver(
+ self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps.disconnect("gps", self)
# For a list of dbus services, look in /etc/dbus-1/system.d/
-class GPS(zavai.Resource):
+class GPS(zavai.Service):
def __init__(self, registry, name):
+ super(GPS, self).__init__(["gps"])
+
self.bus = registry.resource("dbus.system_bus")
# see mdbus -s org.freesmartphone.ousaged /org/freesmartphone/Usage
self.gps_ubx = dbus.Interface(gps, 'org.freesmartphone.GPS.UBX')
self.monitor = GPSMonitor(self)
+ self.position = GPSPosition(self)
- self.requestors = set()
-
- def request(self, tag):
- "Request usage of GPS by the subsystem with the given tag"
- do_start = not self.requestors
- self.requestors.add(tag)
- if do_start:
- # Request GPS resource
- self.usage.RequestResource('GPS')
- zavai.info("Acquired GPS")
-
- def release(self, tag):
- "Release usage of GPS by the subsystem with the given tag"
- if not self.requestors: return
- self.requestors.discard(tag)
- if not self.requestors:
- self.usage.ReleaseResource('GPS')
- zavai.info("Released GPS")
-
- def shutdown(self):
- if self.requestors:
- self.requestors.clear()
- self.usage.ReleaseResource('GPS')
- zavai.info("Released GPS")
+ def start(self):
+ """Request GPS resource"""
+ self.usage.RequestResource('GPS')
+ zavai.info("Acquired GPS")
+
+ def stop(self):
+ """Release usage of GPS"""
+ self.usage.ReleaseResource('GPS')
+ zavai.info("Released GPS")
# def wait_for_fix(self, callback):
# status = self.gps.GetFixStatus()
# 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):
+class GPX(zavai.Service):
"Write GPX track and waypoint files"
- def __init__(self, resource, name):
- self.resource = resource
+ def __init__(self, registry, name):
+ super(GPX, self).__init__(["gpx"])
+ self.registry = registry
self.trk = None
self.wpt = None
+ self.last_pos = None
+ conf = registry.resource("conf")
+ self.trackdir = conf.homedir
+ self.activity_monitors = set()
+ self.started = False
+
+ def add_activity_monitor(self, cb):
+ self.activity_monitors.add(cb)
+ cb(self, self.last_pos is not None)
- def start(basename = None, tstamp = None):
+ def del_activity_monitor(self, cb):
+ self.activity_monitors.discard(cb)
+
+ def notify_activity_monitors(self):
+ for mon in self.activity_monitors:
+ mon(self, self.last_pos is not None)
+
+ def start(self):
+ zavai.info("Starting GPX trace subsystem")
+ self.started = True
+ gps = self.registry.resource("gps")
+ gps.position.connect("gps", self.on_position_changed)
+
+ def stop(self):
+ if not self.started: return
+ zavai.info("Stopping GPX trace subsystem")
+ gps = self.registry.resource("gps")
+ gps.position.disconnect("gps", self.on_position_changed)
+ self.stop_track()
+ self.started = False
+
+ def on_position_changed(self, fields, tstamp, lat, lon, alt):
+ self.last_pos = (fields, tstamp, lat, lon, alt)
+ self.trackpoint()
+
+ def start_track(self, tstamp = None, basename = None):
if basename is None:
- # compute it from GPS
- pass
+ self.basename = basename
+ elif tstamp is not None:
+ # Compute basename for output files
+ self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(tstamp))
+ self.basename = os.path.join(self.trackdir, self.basename)
- self.trk = open(basename + "-trk.gpx", "wt")
+ self.trk = open(self.basename + "-trk.gpx", "wt")
print >>self.trk, """<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
<trk>
<trkseg>""" % VERSION
- self.wpt = open(basename + "-wpt.gpx", "wt")
+ self.wpt = open(self.basename + "-wpt.gpx", "wt")
print >>self.wpt, """<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">""" % VERSION
self.wpt_seq = 1;
+ self.notify_activity_monitors()
- def stop(self):
+ def stop_track(self):
if self.trk is not None:
print >>self.trk, "</trkseg></trk></gpx>"
self.trk.close()
print >>self.wpt, "</gpx>"
self.wpt.close()
self.wpt = None
+ self.last_pos = None
+ self.notify_activity_monitors()
+
+ def trackpoint(self):
+ "Mark a track point"
+ if self.last_pos is None:
+ return
- def shutdown(self):
- self.stop()
+ fields, tstamp, lat, lon, ele = self.last_pos
- def waypoint(self, tstamp, lat, lon, ele = None, name = None):
+ if not self.trk:
+ self.start_track(tstamp)
+
+ print >>self.trk, """<trkpt lat="%f" lon="%f">
+ <time>%s</time>
+ <ele>%f</ele>""" % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
+ #if course is not None: print >>self.trk, " <course>%f</course>" % course
+ #if speed is not None: print >>self.trk, " <speed>%f</speed>" % speed
+ #if fix is not None: print >>self.trk, " <fix>%f</fix>" % fix
+ #if hdop is not None: print >>self.trk, " <hdop>%f</hdop>" % hdop
+ print >>self.trk, "</trkpt>"
+
+ 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_track(tstamp)
+
if name is None:
name = "wpt_%d" % self.wpt_seq
self.wpt_seq += 1
print >>self.wpt, """<wpt lat="%f" lon="%f">
<name>%s</name>
- <time>%s</time>""" % (
- lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)))
- if ele is not None:
- print >>self.wpt, " <ele>%f</ele>""" % ele
- print >>self.wpt, "</wpt>"
-
- def trackpoint(self, tstamp, lat, lon, ele = None, course = None, speed = None, fix = None, hdop = None):
- print >>self.trk, """<trkpt lat="%f" lon="%f">
- <time>%s</time>""" % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)))
- if ele is not None: print >>self.trk, " <ele>%f</ele>" % ele
- if course is not None: print >>self.trk, " <course>%f</course>" % course
- if speed is not None: print >>self.trk, " <speed>%f</speed>" % speed
- if fix is not None: print >>self.trk, " <fix>%f</fix>" % fix
- if hdop is not None: print >>self.trk, " <hdop>%f</hdop>" % hdop
- print >>self.trk, "</trkpt>"
-
-
+ <time>%s</time>
+ <ele>%f</ele>
+</wpt>""" % (
+ lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
# def record(self):
# 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: