Signed-off-by: Christian Kuka <christ...@kuka.cc>
---
 gps/init.lua |  189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gps/readme   |   24 +++++++
 2 files changed, 213 insertions(+), 0 deletions(-)
 create mode 100644 gps/init.lua
 create mode 100644 gps/readme

diff --git a/gps/init.lua b/gps/init.lua
new file mode 100644
index 0000000..6b69dae
--- /dev/null
+++ b/gps/init.lua
@@ -0,0 +1,189 @@
+-----------------------------------------------
+-- GPS widget for the awesome window manager --
+-----------------------------------------------
+-- Author: Christian Kuka chrit...@kuka.cc   --
+-- Copyright 2010 Christian Kuka             --
+-- Licensed under GPLv2                      --
+-----------------------------------------------
+
+local assert = assert
+local string = string
+local tonumber = tonumber
+local math = math
+local setmetatable = setmetatable
+local table = table
+local io = {
+    open = io.open
+}
+local capi = {
+        widget = widget,
+        mouse = mouse
+}
+
+local naughty = require("naughty")
+local awful = require("awful")
+local http = require("socket.http")
+local ltn12 = require("ltn12")
+local json = require("json")
+
+local lib = {
+    hooks = require("obvious.lib.hooks"),
+    markup = require("obvious.lib.markup")
+}
+
+module("obvious.gps")
+
+widget = capi.widget({
+    type = "textbox",
+    name = "tb_gps",
+    align = "right"
+})
+
+position = {
+   date = 0,
+   time = 0,
+   latitude = 0.0,
+   longitude = 0.0,
+   quality = 0,
+   altitude = 0.0,
+   satellites = 0,
+   satellitesData = {},
+   dilution = 0.0,
+   height = 0.0,
+   status = "V",
+   speed = 0.0,
+   course = 0.0,
+   variation = 0.0,
+   node = ""
+}
+
+
+-- Set the local device for NMEA data
+local device = "/dev/rfcomm0"
+function set_device(dev)
+   device = dev
+end
+
+-- Set the browser for opening openstreetmap
+local browser = "/usr/bin/uzbl"
+function set_browser(path)
+   browser = path
+end
+
+-- Returns the position struct
+function get_data()
+   return position
+end
+
+-- Parse the NMEA messages (GGA, RMC, GSV)
+local fh = nil
+function parse_nmea(line)
+    local msg = string.sub(line,0,6)
+    if (msg == "$GPGGA") then
+       -- Match GGA message
+       local time, latitude, longitude, quality, satellites, dilution, 
altitude, height, checksum = 
line:match("^\$GPGGA,([0-9.]+),([0-9.]+),[NS],([0-9.]+),[EW],([0-8]?),([0-9]+),([0-9.]*),([0-9.-]+),M,([0-9.]+),M,,\*(.*)")
+       latitude = tonumber(latitude)
+       longitude = tonumber(longitude)
+       local dd
+       dd,_ = math.modf(latitude / 100)
+       position.latitude = dd + (latitude - dd * 100) / 60
+       dd,_ = math.modf(longitude / 100)
+       position.longitude = dd + (longitude - dd * 100) / 60
+       position.time = time
+       position.quality = tonumber(quality)
+       position.satellites = tonumber(satellites)
+       position.dilution = tonumber(dilution)
+       position.altitude = tonumber(altitude)
+       position.height = tonumber(height)
+    elseif (msg == "$GPRMC") then
+       -- Match RMC message
+       local time, status, latitude, longitude, speed, course, date, 
variation, node, checksum = 
line:match("^\$GPRMC,([0-9.]+),[AV],([0-9.]+),[NS],([0-9.]+),[EW],([0-9.]+),([0-9.]+),([0-9]+),([0-9.]*),[EW]?,([NADE])\*(.*)")
+       latitude = tonumber(latitude)
+       longitude = tonumber(longitude)
+       local dd
+       dd,_ = math.modf(latitude / 100)
+       position.latitude = dd + (latitude - dd * 100) / 60
+       dd,_ = math.modf(longitude / 100)
+       position.longitude = dd + (longitude - dd * 100) / 60
+       position.time = time
+       position.date = date
+       position.status = status
+       position.speed = tonumber(speed)
+       position.course = tonumber(course)
+       position.variation = tonumber(variation)
+       position.node = node
+
+    elseif (msg == "$GPGSV") then
+       -- TODO is satellite data needed?
+       -- Match GSV message
+       --local total, count, satellites, satellites, checksum = 
line:match("^\$GPGSV,([1-3]+),([1-3]+),([0-9]+),([0-9,]*)\*(.*)")
+       
+       -- Match satellites data
+       -- local id, elevation, azimuth, snr = 
satellites:match("([0-9]{1,2}),([0-9]+),([0-9]+),([0-9]*)")
+    end
+end
+
+-- Reverse geocode a position using geonames.org
+function reverse_geocode() 
+   local c, err, h = 
http.request("http://ws.geonames.org/findNearbyPlaceNameJSON?lat="..position.latitude.."&lng="..position.longitude)
+   if c then
+      c = json.decode(c)
+      return c.geonames[1]
+    end
+    return nil
+end
+
+-- Update position data
+local function update()
+   fh = io.open(device)
+   if fh then
+   local line = fh:read("*l")
+   local maxlines = 3
+   local l = 0
+   while line and l < maxlines do
+      parse_nmea(line)
+      l = l + 1
+   end
+   fh:close()
+end
+   widget.text = string.format("%f,%f", position.latitude, position.longitude)
+end
+
+-- Show detail information about current position
+local function detail()
+   local d = 
string.format("Latitude:\t%f\nLongitude:\t%f\nAltitude:\t%f\nDilution:\t%f", 
position.latitude, position.longitude, position.altitude, position.dilution)
+   naughty.notify({
+                     text = d,
+                     screen = capi.mouse.screen
+                  })
+end
+
+-- Show reverse geocode position information
+local function lookup()
+   local geodata = reverse_geocode()
+   if geodata then
+      local d = string.format("Country:\t%s\nName:\t%s", geodata.countryName, 
geodata.name)
+      naughty.notify({
+                        text = d,
+                        screen = capi.mouse.screen
+                     })
+   end
+end
+
+-- Open openstreetmap with current position
+local function openmap()
+   local link = 
"http://www.openstreetmap.org/?lat="..position.latitude.."&lon="..position.longitude.."&zoom=14&layers=B00FTF";
+   awful.util.spawn(browser .. " " .. link)
+end
+
+widget:buttons(awful.util.table.join(
+    awful.button({ }, 1, detail),
+    awful.button({ }, 2, openmap),
+    awful.button({ }, 3, lookup)
+))
+
+update()
+lib.hooks.timer.register(60, 300, update)
+lib.hooks.timer.start(update)
+
+setmetatable(_M, { __call = function () return widget end })
diff --git a/gps/readme b/gps/readme
new file mode 100644
index 0000000..1458a75
--- /dev/null
+++ b/gps/readme
@@ -0,0 +1,24 @@
+* GPS widget
+  This widget allows you to display position information from your
+  GPS-receiver. It also can display the position on openstreetmap and
+  perform reverse geocoding through geonames.org
+
+** Available settings
+   - set_browser: Sets the path to the www-browser. If no browser is
+    set the default is /usr/bin/uzbl
+   - set_device: Sets the GPS device ie. /dev/rfcomm0 if you have a
+    bluetooth GPS receiver. Default is /dev/rfcomm0
+
+
+** Usage
+   Include the following line into your rc.lua :
+     require("obvious.gps")
+
+   Then set the device and the browser:
+     obvious.gps.set_device("/dev/rfcomm0")
+     obvious.gps.set_browser("/usr/bin/uzbl")
+
+   And add it to your wibox's widgets list:
+     obvious.gps()
+
+Christian Kuka [christ...@kuka.cc]
-- 
1.7.0


-- 
To unsubscribe, send mail to awesome-devel-unsubscr...@naquadah.org.

Reply via email to