mirror of
https://github.com/acaloiaro/roam-location
synced 2026-07-21 18:29:11 +00:00
Initial commit
This commit is contained in:
parent
9ff96140b5
commit
0c1093519d
4 changed files with 156 additions and 0 deletions
5
go.mod
Normal file
5
go.mod
Normal 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
9
go.sum
Normal 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
66
receiver/nmea_receiver.go
Normal 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)
|
||||
}
|
||||
}
|
||||
76
service/current_location.go
Normal file
76
service/current_location.go
Normal 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))
|
||||
}
|
||||
Loading…
Reference in a new issue