Initial commit

This commit is contained in:
Adriano Caloiaro 2020-07-15 21:26:31 -06:00
parent 9ff96140b5
commit 0c1093519d
No known key found for this signature in database
GPG key ID: 9FFD0E7601F166AB
4 changed files with 156 additions and 0 deletions

5
go.mod Normal file
View file

@ -0,0 +1,5 @@
module github.com/acaloiaro/roam-location
go 1.14
require github.com/adrianmo/go-nmea v1.2.0

9
go.sum Normal file
View file

@ -0,0 +1,9 @@
github.com/adrianmo/go-nmea v1.2.0 h1:igwvOtEOv4Hg6bpqOcsKFIir3JXYz54FPXQkiWO4EkU=
github.com/adrianmo/go-nmea v1.2.0/go.mod h1:u8bPnpKt/D/5rll/5l9f6iDfeq5WZW0+/SXdkwix6Tg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

66
receiver/nmea_receiver.go Normal file
View file

@ -0,0 +1,66 @@
package main
import (
"fmt"
"log"
"net"
"os"
"strings"
"github.com/adrianmo/go-nmea"
)
func main() {
listen()
}
func listen() {
addr, _ := net.ResolveUDPAddr("udp", ":22335")
sock, _ := net.ListenUDP("udp", addr)
for {
buf := make([]byte, 2048)
rlen, _, err := sock.ReadFromUDP(buf)
if err != nil {
fmt.Println(err)
}
go handlePacket(buf, rlen)
}
}
func handlePacket(buf []byte, rlen int) {
sentences := fmt.Sprintln(string(buf[0:rlen]))
sentence := strings.Split(sentences, "\n")[0] // We're not concerned with the second sentence, yet
s, err := nmea.Parse(sentence)
if err != nil {
// ignoring bad nmea sentence
log.Println("Ignoring bad NMEA sentence:", sentence)
return
}
if s.DataType() == nmea.TypeGGA {
m := s.(nmea.GGA)
fmt.Printf("Raw sentence: %v\n", m)
fmt.Printf("Time: %s\n", m.Time)
fmt.Printf("Latitude GPS: %f\n", m.Latitude)
fmt.Printf("Longitude GPS: %f\n", m.Longitude)
appendLog(m.Latitude, m.Longitude, sentence)
}
}
func appendLog(lat, lon float64, nmeaSentence string) {
dbPath := os.Getenv("ROAM_LOCATION_DB_PATH")
f, err := os.OpenFile(dbPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
}
defer f.Close()
row := fmt.Sprintf("%f,%f,%s\n", lat, lon, nmeaSentence)
if _, err := f.WriteString(row); err != nil {
log.Println(err)
}
}

View file

@ -0,0 +1,76 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
"strings"
)
type Location struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
}
func handler(w http.ResponseWriter, r *http.Request) {
location := currentLocation()
byteArray, err := json.MarshalIndent(location, "", " ")
if err != nil {
log.Fatalf("error providing current location: %v", err)
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(byteArray))
}
func currentLocation() (location Location) {
dbPath := os.Getenv("ROAM_LOCATION_DB_PATH")
fileHandle, err := os.Open(dbPath)
if err != nil {
panic("Cannot open file")
}
defer fileHandle.Close()
line := ""
stat, _ := fileHandle.Stat()
fs := stat.Size()
var cursor int64 = fs - 1 // start before the newline
for {
cursor--
char := make([]byte, 1)
fileHandle.ReadAt(char, cursor)
if cursor != -1 && (char[0] == '\n') { // stop if we find a line
break
}
line = fmt.Sprintf("%s%s", string(char), line) // there is more efficient way
if cursor == -fs { // stop if we are at the begining
break
}
}
fields := strings.Split(line, ",")
if f, err := strconv.ParseFloat(fields[0], 64); err == nil {
location.Lat = f
}
if f, err := strconv.ParseFloat(fields[1], 64); err == nil {
location.Lon = f
}
return
}
func main() {
http.HandleFunc("/current_location", handler)
log.Fatal(http.ListenAndServe(":22495", nil))
}